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"
59 #include "langhooks.h"
70 #include "diagnostic.h"
72 #include "tree-iterator.h"
76 #define OBJC_VOID_AT_END void_list_node
78 /* When building Objective-C++, we are not linking against the C front-end
79 and so need to replicate the C tree-construction functions in some way. */
81 #define OBJCP_REMAP_FUNCTIONS
82 #include "objcp-decl.h"
85 /* This is the default way of generating a method name. */
86 /* I am not sure it is really correct.
87 Perhaps there's a danger that it will make name conflicts
88 if method names contain underscores. -- rms. */
89 #ifndef OBJC_GEN_METHOD_LABEL
90 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
93 sprintf ((BUF), "_%s_%s_%s_%s", \
94 ((IS_INST) ? "i" : "c"), \
96 ((CAT_NAME)? (CAT_NAME) : ""), \
98 for (temp = (BUF); *temp; temp++) \
99 if (*temp == ':') *temp = '_'; \
103 /* These need specifying. */
104 #ifndef OBJC_FORWARDING_STACK_OFFSET
105 #define OBJC_FORWARDING_STACK_OFFSET 0
108 #ifndef OBJC_FORWARDING_MIN_OFFSET
109 #define OBJC_FORWARDING_MIN_OFFSET 0
112 /* Set up for use of obstacks. */
116 /* This obstack is used to accumulate the encoding of a data type. */
117 static struct obstack util_obstack;
119 /* This points to the beginning of obstack contents, so we can free
120 the whole contents. */
123 /* The version identifies which language generation and runtime
124 the module (file) was compiled for, and is recorded in the
125 module descriptor. */
127 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
128 #define PROTOCOL_VERSION 2
130 /* (Decide if these can ever be validly changed.) */
131 #define OBJC_ENCODE_INLINE_DEFS 0
132 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
134 /*** Private Interface (procedures) ***/
136 /* Used by compile_file. */
138 static void init_objc (void);
139 static void finish_objc (void);
141 /* Code generation. */
143 static void synth_module_prologue (void);
144 static tree objc_build_constructor (tree, tree);
145 static void build_module_descriptor (void);
146 static void build_module_initializer_routine (void);
147 static tree init_module_descriptor (tree);
148 static tree build_objc_method_call (int, tree, tree, tree, tree);
149 static void generate_strings (void);
150 static tree get_proto_encoding (tree);
151 static void build_selector_translation_table (void);
152 static tree lookup_interface (tree);
153 static tree objc_add_static_instance (tree, tree);
155 static tree start_class (enum tree_code, tree, tree, tree);
156 static tree continue_class (tree);
157 static void finish_class (tree);
158 static void start_method_def (tree);
160 static void objc_start_function (tree, tree, tree, tree);
162 static void objc_start_function (tree, tree, tree, struct c_arg_info *);
164 static tree start_protocol (enum tree_code, tree, tree);
165 static tree build_method_decl (enum tree_code, tree, tree, tree);
166 static tree objc_add_method (tree, tree, int);
167 static tree add_instance_variable (tree, int, tree);
168 static tree build_ivar_reference (tree);
169 static tree is_ivar (tree, tree);
170 static int is_private (tree);
171 static tree get_super_receiver (void);
173 static void build_objc_exception_stuff (void);
174 static void build_next_objc_exception_stuff (void);
176 static tree build_ivar_template (void);
177 static tree build_method_template (void);
178 static tree build_private_template (tree);
179 static void build_class_template (void);
180 static void build_selector_template (void);
181 static void build_category_template (void);
182 static tree lookup_method_in_hash_lists (tree, int);
183 static void build_super_template (void);
184 static tree build_category_initializer (tree, tree, tree, tree, tree, tree);
185 static tree build_protocol_initializer (tree, tree, tree, tree, tree);
186 static void synth_forward_declarations (void);
187 static int ivar_list_length (tree);
188 static tree get_class_ivars (tree);
189 static void generate_ivar_lists (void);
190 static void generate_dispatch_tables (void);
191 static void generate_shared_structures (void);
192 static tree generate_protocol_list (tree);
193 static void build_protocol_reference (tree);
195 static tree build_keyword_selector (tree);
196 static const char *synth_id_with_class_suffix (const char *, tree);
198 static void generate_static_references (void);
199 static int check_methods_accessible (tree, tree, int);
200 static void encode_aggregate_within (tree, int, int, int, int);
201 static const char *objc_demangle (const char *);
203 /* Hash tables to manage the global pool of method prototypes. */
205 hash *nst_method_hash_list = 0;
206 hash *cls_method_hash_list = 0;
208 static size_t hash_func (tree);
209 static void hash_init (void);
210 static void hash_enter (hash *, tree);
211 static hash hash_lookup (hash *, tree);
212 static void hash_add_attr (hash, tree);
213 static tree lookup_method (tree, tree);
214 static tree lookup_method_static (tree, tree, int);
215 static void add_method_to_hash_list (hash *, tree);
216 static tree add_class (tree);
217 static void add_category (tree, tree);
218 static inline tree lookup_category (tree, tree);
222 class_names, /* class, category, protocol, module names */
223 meth_var_names, /* method and variable names */
224 meth_var_types /* method and variable type descriptors */
227 static tree add_objc_string (tree, enum string_section);
228 static tree get_objc_string_decl (tree, enum string_section);
229 static tree build_objc_string_decl (enum string_section);
230 static tree build_selector_reference_decl (void);
231 static void build_selector_table_decl (void);
233 /* Protocol additions. */
235 static tree add_protocol (tree);
236 static tree lookup_protocol (tree);
237 static void check_protocol_recursively (tree, tree);
238 static tree lookup_and_install_protocols (tree);
242 static void encode_type_qualifiers (tree);
243 static void encode_pointer (tree, int, int);
244 static void encode_array (tree, int, int);
245 static void encode_aggregate (tree, int, int);
246 static void encode_next_bitfield (int);
247 static void encode_gnu_bitfield (int, tree, int);
248 static void encode_type (tree, int, int);
249 static void encode_field_decl (tree, int, int);
252 static void really_start_method (tree, tree);
254 static void really_start_method (tree, struct c_arg_info *);
256 static int objc_types_are_equivalent (tree, tree);
257 static int comp_proto_with_proto (tree, tree);
258 static tree get_arg_type_list (tree, int, int);
259 static void objc_push_parm (tree);
261 static tree objc_get_parm_info (int);
263 static struct c_arg_info *objc_get_parm_info (int);
265 static void synth_self_and_ucmd_args (void);
267 /* Utilities for debugging and error diagnostics. */
269 static void warn_with_method (const char *, int, tree);
270 static void error_with_ivar (const char *, tree);
271 static char *gen_type_name (tree);
272 static char *gen_type_name_0 (tree);
273 static char *gen_method_decl (tree);
274 static char *gen_declaration (tree);
275 static void dump_interface (FILE *, tree);
277 /* Everything else. */
279 static tree lookup_method_in_protocol_list (tree, tree, int);
280 static tree lookup_protocol_in_reflist (tree, tree);
281 static tree start_var_decl (tree, const char *);
282 static void finish_var_decl (tree, tree);
283 static tree create_field_decl (tree, const char *);
284 static tree setup_string_decl (void);
285 static int check_string_class_template (void);
286 static tree my_build_string (int, const char *);
287 static void build_objc_symtab_template (void);
288 static tree init_def_list (tree);
289 static tree init_objc_symtab (tree);
290 static tree build_metadata_decl (const char *, tree);
291 static void forward_declare_categories (void);
292 static void generate_objc_symtab_decl (void);
293 static tree build_selector (tree);
294 static tree build_typed_selector_reference (tree, tree);
295 static tree build_selector_reference (tree);
296 static tree build_class_reference_decl (void);
297 static void add_class_reference (tree);
298 static void build_protocol_template (void);
299 static tree build_descriptor_table_initializer (tree, tree);
300 static tree build_method_prototype_list_template (tree, int);
301 static tree build_method_prototype_template (void);
302 static tree objc_method_parm_type (tree);
303 static int objc_encoded_type_size (tree);
304 static tree encode_method_prototype (tree);
305 static tree generate_descriptor_table (tree, const char *, int, tree, tree);
306 static void generate_method_descriptors (tree);
307 static void generate_protocol_references (tree);
308 static void generate_protocols (void);
309 static void check_ivars (tree, tree);
310 static tree build_ivar_list_template (tree, int);
311 static tree build_method_list_template (tree, int);
312 static tree build_ivar_list_initializer (tree, tree);
313 static tree generate_ivars_list (tree, const char *, int, tree);
314 static tree build_dispatch_table_initializer (tree, tree);
315 static tree generate_dispatch_table (tree, const char *, int, tree);
316 static tree build_shared_structure_initializer (tree, tree, tree, tree,
317 tree, int, tree, tree, tree);
318 static void generate_category (tree);
319 static tree adjust_type_for_id_default (tree);
320 static tree check_duplicates (hash, int, int);
321 static tree receiver_is_class_object (tree, int, int);
322 static int check_methods (tree, tree, int);
323 static int conforms_to_protocol (tree, tree);
324 static void check_protocol (tree, const char *, const char *);
325 static void check_protocols (tree, const char *, const char *);
326 static void generate_classref_translation_entry (tree);
327 static void handle_class_ref (tree);
328 static void generate_struct_by_value_array (void)
330 static void mark_referenced_methods (void);
331 static void generate_objc_image_info (void);
333 /*** Private Interface (data) ***/
335 /* Reserved tag definitions. */
337 #define OBJECT_TYPEDEF_NAME "id"
338 #define CLASS_TYPEDEF_NAME "Class"
340 #define TAG_OBJECT "objc_object"
341 #define TAG_CLASS "objc_class"
342 #define TAG_SUPER "objc_super"
343 #define TAG_SELECTOR "objc_selector"
345 #define UTAG_CLASS "_objc_class"
346 #define UTAG_IVAR "_objc_ivar"
347 #define UTAG_IVAR_LIST "_objc_ivar_list"
348 #define UTAG_METHOD "_objc_method"
349 #define UTAG_METHOD_LIST "_objc_method_list"
350 #define UTAG_CATEGORY "_objc_category"
351 #define UTAG_MODULE "_objc_module"
352 #define UTAG_SYMTAB "_objc_symtab"
353 #define UTAG_SUPER "_objc_super"
354 #define UTAG_SELECTOR "_objc_selector"
356 #define UTAG_PROTOCOL "_objc_protocol"
357 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
358 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
360 /* Note that the string object global name is only needed for the
362 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
364 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
366 static const char *TAG_GETCLASS;
367 static const char *TAG_GETMETACLASS;
368 static const char *TAG_MSGSEND;
369 static const char *TAG_MSGSENDSUPER;
370 /* The NeXT Objective-C messenger may have two extra entry points, for use
371 when returning a structure. */
372 static const char *TAG_MSGSEND_STRET;
373 static const char *TAG_MSGSENDSUPER_STRET;
374 static const char *default_constant_string_class_name;
376 /* Runtime metadata flags. */
377 #define CLS_FACTORY 0x0001L
378 #define CLS_META 0x0002L
380 #define OBJC_MODIFIER_STATIC 0x00000001
381 #define OBJC_MODIFIER_FINAL 0x00000002
382 #define OBJC_MODIFIER_PUBLIC 0x00000004
383 #define OBJC_MODIFIER_PRIVATE 0x00000008
384 #define OBJC_MODIFIER_PROTECTED 0x00000010
385 #define OBJC_MODIFIER_NATIVE 0x00000020
386 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
387 #define OBJC_MODIFIER_ABSTRACT 0x00000080
388 #define OBJC_MODIFIER_VOLATILE 0x00000100
389 #define OBJC_MODIFIER_TRANSIENT 0x00000200
390 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
392 /* NeXT-specific tags. */
394 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
395 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
396 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
397 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
398 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
399 #define TAG_EXCEPTIONMATCH "objc_exception_match"
400 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
401 #define TAG_SYNCENTER "objc_sync_enter"
402 #define TAG_SYNCEXIT "objc_sync_exit"
403 #define TAG_SETJMP "_setjmp"
404 #define UTAG_EXCDATA "_objc_exception_data"
406 /* GNU-specific tags. */
408 #define TAG_EXECCLASS "__objc_exec_class"
409 #define TAG_GNUINIT "__objc_gnu_init"
411 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
412 tree objc_global_trees[OCTI_MAX];
414 static void handle_impent (struct imp_entry *);
416 struct imp_entry *imp_list = 0;
417 int imp_count = 0; /* `@implementation' */
418 int cat_count = 0; /* `@category' */
420 enum tree_code objc_inherit_code;
421 int objc_public_flag;
423 /* Use to generate method labels. */
424 static int method_slot = 0;
428 static char *errbuf; /* Buffer for error diagnostics */
430 /* Data imported from tree.c. */
432 extern enum debug_info_type write_symbols;
434 /* Data imported from toplev.c. */
436 extern const char *dump_base_name;
438 static int flag_typed_selectors;
440 /* Store all constructed constant strings in a hash table so that
441 they get uniqued properly. */
443 struct string_descriptor GTY(())
445 /* The literal argument . */
448 /* The resulting constant string. */
452 static GTY((param_is (struct string_descriptor))) htab_t string_htab;
454 static hashval_t string_hash (const void *);
455 static int string_eq (const void *, const void *);
457 FILE *gen_declaration_file;
459 /* Tells "encode_pointer/encode_aggregate" whether we are generating
460 type descriptors for instance variables (as opposed to methods).
461 Type descriptors for instance variables contain more information
462 than methods (for static typing and embedded structures). */
464 static int generating_instance_variables = 0;
466 /* Some platforms pass small structures through registers versus
467 through an invisible pointer. Determine at what size structure is
468 the transition point between the two possibilities. */
471 generate_struct_by_value_array (void)
474 tree field_decl, field_decl_chain;
476 int aggregate_in_mem[32];
479 /* Presumably no platform passes 32 byte structures in a register. */
480 for (i = 1; i < 32; i++)
484 /* Create an unnamed struct that has `i' character components */
485 type = start_struct (RECORD_TYPE, NULL_TREE);
487 strcpy (buffer, "c1");
488 field_decl = create_field_decl (char_type_node,
490 field_decl_chain = field_decl;
492 for (j = 1; j < i; j++)
494 sprintf (buffer, "c%d", j + 1);
495 field_decl = create_field_decl (char_type_node,
497 chainon (field_decl_chain, field_decl);
499 finish_struct (type, field_decl_chain, NULL_TREE);
501 aggregate_in_mem[i] = aggregate_value_p (type, 0);
502 if (!aggregate_in_mem[i])
506 /* We found some structures that are returned in registers instead of memory
507 so output the necessary data. */
510 for (i = 31; i >= 0; i--)
511 if (!aggregate_in_mem[i])
513 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i);
515 /* The first member of the structure is always 0 because we don't handle
516 structures with 0 members */
517 printf ("static int struct_forward_array[] = {\n 0");
519 for (j = 1; j <= i; j++)
520 printf (", %d", aggregate_in_mem[j]);
531 if (cxx_init () == false)
533 if (c_objc_common_init () == false)
537 #ifndef USE_MAPPED_LOCATION
538 /* Force the line number back to 0; check_newline will have
539 raised it to 1, which will make the builtin functions appear
540 not to be built in. */
544 /* If gen_declaration desired, open the output file. */
545 if (flag_gen_declaration)
547 register char * const dumpname = concat (dump_base_name, ".decl", NULL);
548 gen_declaration_file = fopen (dumpname, "w");
549 if (gen_declaration_file == 0)
550 fatal_error ("can't open %s: %m", dumpname);
554 if (flag_next_runtime)
556 TAG_GETCLASS = "objc_getClass";
557 TAG_GETMETACLASS = "objc_getMetaClass";
558 TAG_MSGSEND = "objc_msgSend";
559 TAG_MSGSENDSUPER = "objc_msgSendSuper";
560 TAG_MSGSEND_STRET = "objc_msgSend_stret";
561 TAG_MSGSENDSUPER_STRET = "objc_msgSendSuper_stret";
562 default_constant_string_class_name = "NSConstantString";
566 TAG_GETCLASS = "objc_get_class";
567 TAG_GETMETACLASS = "objc_get_meta_class";
568 TAG_MSGSEND = "objc_msg_lookup";
569 TAG_MSGSENDSUPER = "objc_msg_lookup_super";
570 /* GNU runtime does not provide special functions to support
571 structure-returning methods. */
572 default_constant_string_class_name = "NXConstantString";
573 flag_typed_selectors = 1;
578 if (print_struct_values)
579 generate_struct_by_value_array ();
585 objc_finish_file (void)
587 mark_referenced_methods ();
590 /* We need to instantiate templates _before_ we emit ObjC metadata;
591 if we do not, some metadata (such as selectors) may go missing. */
592 instantiate_pending_templates (0);
595 /* Finalize Objective-C runtime data. No need to generate tables
596 and code if only checking syntax. */
597 if (!flag_syntax_only)
600 if (gen_declaration_file)
601 fclose (gen_declaration_file);
608 /* Return the first occurrence of a method declaration corresponding
609 to sel_name in rproto_list. Search rproto_list recursively.
610 If is_class is 0, search for instance methods, otherwise for class
613 lookup_method_in_protocol_list (tree rproto_list, tree sel_name,
619 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
621 p = TREE_VALUE (rproto);
623 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
625 if ((fnd = lookup_method (is_class
626 ? PROTOCOL_CLS_METHODS (p)
627 : PROTOCOL_NST_METHODS (p), sel_name)))
629 else if (PROTOCOL_LIST (p))
630 fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p),
635 ; /* An identifier...if we could not find a protocol. */
646 lookup_protocol_in_reflist (tree rproto_list, tree lproto)
650 /* Make sure the protocol is supported by the object on the rhs. */
651 if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE)
654 for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto))
656 p = TREE_VALUE (rproto);
658 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
663 else if (PROTOCOL_LIST (p))
664 fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto);
673 ; /* An identifier...if we could not find a protocol. */
680 objc_start_class_interface (tree class, tree super_class, tree protos)
682 objc_interface_context
684 = start_class (CLASS_INTERFACE_TYPE, class, super_class, protos);
685 objc_public_flag = 0;
689 objc_start_category_interface (tree class, tree categ, tree protos)
691 objc_interface_context
692 = start_class (CATEGORY_INTERFACE_TYPE, class, categ, protos);
694 = continue_class (objc_interface_context);
698 objc_start_protocol (tree name, tree protos)
700 objc_interface_context
701 = start_protocol (PROTOCOL_INTERFACE_TYPE, name, protos);
705 objc_continue_interface (void)
708 = continue_class (objc_interface_context);
712 objc_finish_interface (void)
714 finish_class (objc_interface_context);
715 objc_interface_context = NULL_TREE;
719 objc_start_class_implementation (tree class, tree super_class)
721 objc_implementation_context
723 = start_class (CLASS_IMPLEMENTATION_TYPE, class, super_class, NULL_TREE);
724 objc_public_flag = 0;
728 objc_start_category_implementation (tree class, tree categ)
730 objc_implementation_context
731 = start_class (CATEGORY_IMPLEMENTATION_TYPE, class, categ, NULL_TREE);
733 = continue_class (objc_implementation_context);
737 objc_continue_implementation (void)
740 = continue_class (objc_implementation_context);
744 objc_finish_implementation (void)
746 if (objc_implementation_context)
748 finish_class (objc_implementation_context);
749 objc_ivar_chain = NULL_TREE;
750 objc_implementation_context = NULL_TREE;
753 warning ("`@end' must appear in an @implementation context");
757 objc_set_visibility (int visibility)
759 objc_public_flag = visibility;
763 objc_set_method_type (enum tree_code type)
765 objc_inherit_code = (type == PLUS_EXPR
767 : INSTANCE_METHOD_DECL);
771 objc_build_method_signature (tree rettype, tree selector, tree optparms)
773 return build_method_decl (objc_inherit_code, rettype, selector, optparms);
777 objc_add_method_declaration (tree decl)
779 if (!objc_interface_context)
780 fatal_error ("method declaration not in @interface context");
782 objc_add_method (objc_interface_context,
784 objc_inherit_code == CLASS_METHOD_DECL);
788 objc_start_method_definition (tree decl)
790 if (!objc_implementation_context)
791 fatal_error ("method definition not in @implementation context");
793 objc_add_method (objc_implementation_context,
795 objc_inherit_code == CLASS_METHOD_DECL);
796 start_method_def (decl);
800 objc_add_instance_variable (tree decl)
802 (void) add_instance_variable (objc_ivar_context,
807 /* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of
811 objc_is_reserved_word (tree ident)
813 unsigned char code = C_RID_CODE (ident);
815 return (OBJC_IS_AT_KEYWORD (code)
817 || code == RID_CLASS || code == RID_PUBLIC
818 || code == RID_PROTECTED || code == RID_PRIVATE
819 || code == RID_TRY || code == RID_THROW || code == RID_CATCH
824 /* Return true if TYPE is 'id'. */
827 objc_is_object_id (tree type)
829 return OBJC_TYPE_NAME (type) == objc_object_id;
833 objc_is_class_id (tree type)
835 return OBJC_TYPE_NAME (type) == objc_class_id;
838 /* Return 1 if LHS and RHS are compatible types for assignment or
839 various other operations. Return 0 if they are incompatible, and
840 return -1 if we choose to not decide (because the types are really
841 just C types, not ObjC specific ones). When the operation is
842 REFLEXIVE (typically comparisons), check for compatibility in
843 either direction; when it's not (typically assignments), don't.
845 This function is called in two cases: when both lhs and rhs are
846 pointers to records (in which case we check protocols too), and
847 when both lhs and rhs are records (in which case we check class
850 Warnings about classes/protocols not implementing a protocol are
851 emitted here (multiple of those warnings might be emitted for a
852 single line!); generic warnings about incompatible assignments and
853 lacks of casts in comparisons are/must be emitted by the caller if
858 objc_comptypes (tree lhs, tree rhs, int reflexive)
860 /* New clause for protocols. */
862 /* Here we manage the case of a POINTER_TYPE = POINTER_TYPE. We only
863 manage the ObjC ones, and leave the rest to the C code. */
864 if (TREE_CODE (lhs) == POINTER_TYPE
865 && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE
866 && TREE_CODE (rhs) == POINTER_TYPE
867 && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE)
869 int lhs_is_proto = IS_PROTOCOL_QUALIFIED_UNTYPED (lhs);
870 int rhs_is_proto = IS_PROTOCOL_QUALIFIED_UNTYPED (rhs);
874 tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs);
875 tree rproto, rproto_list;
878 /* <Protocol> = <Protocol> */
881 /* Class <Protocol> != id <Protocol>;
882 id <Protocol> != Class <Protocol> */
883 if (IS_ID (lhs) != IS_ID (rhs))
886 rproto_list = TYPE_PROTOCOL_LIST (rhs);
890 /* An assignment between objects of type 'id
891 <Protocol>'; make sure the protocol on the lhs is
892 supported by the object on the rhs. */
893 for (lproto = lproto_list; lproto;
894 lproto = TREE_CHAIN (lproto))
896 p = TREE_VALUE (lproto);
897 rproto = lookup_protocol_in_reflist (rproto_list, p);
901 ("object does not conform to the `%s' protocol",
902 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
908 /* Obscure case - a comparison between two objects
909 of type 'id <Protocol>'. Check that either the
910 protocol on the lhs is supported by the object on
911 the rhs, or viceversa. */
913 /* Check if the protocol on the lhs is supported by the
914 object on the rhs. */
915 for (lproto = lproto_list; lproto;
916 lproto = TREE_CHAIN (lproto))
918 p = TREE_VALUE (lproto);
919 rproto = lookup_protocol_in_reflist (rproto_list, p);
923 /* Check failed - check if the protocol on the rhs
924 is supported by the object on the lhs. */
925 for (rproto = rproto_list; rproto;
926 rproto = TREE_CHAIN (rproto))
928 p = TREE_VALUE (rproto);
929 lproto = lookup_protocol_in_reflist (lproto_list,
934 /* This check failed too: incompatible */
944 /* <Protocol> = <class> * */
945 else if (TYPED_OBJECT (TREE_TYPE (rhs)))
947 tree rname = OBJC_TYPE_NAME (TREE_TYPE (rhs));
950 /* Class <Protocol> != <class> * */
954 /* Make sure the protocol is supported by the object on
956 for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto))
958 p = TREE_VALUE (lproto);
960 rinter = lookup_interface (rname);
962 while (rinter && !rproto)
966 rproto_list = CLASS_PROTOCOL_LIST (rinter);
967 rproto = lookup_protocol_in_reflist (rproto_list, p);
968 /* If the underlying ObjC class does not have
969 the protocol we're looking for, check for "one-off"
970 protocols (e.g., `NSObject<MyProt> *foo;') attached
974 rproto_list = TYPE_PROTOCOL_LIST (TREE_TYPE (rhs));
975 rproto = lookup_protocol_in_reflist (rproto_list, p);
978 /* Check for protocols adopted by categories. */
979 cat = CLASS_CATEGORY_LIST (rinter);
980 while (cat && !rproto)
982 rproto_list = CLASS_PROTOCOL_LIST (cat);
983 rproto = lookup_protocol_in_reflist (rproto_list, p);
984 cat = CLASS_CATEGORY_LIST (cat);
987 rinter = lookup_interface (CLASS_SUPER_NAME (rinter));
991 warning ("class `%s' does not implement the `%s' protocol",
992 IDENTIFIER_POINTER (OBJC_TYPE_NAME (TREE_TYPE (rhs))),
993 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
997 /* id <Protocol> = id; Class <Protocol> = id */
998 else if (objc_is_object_id (TREE_TYPE (rhs)))
1002 /* id <Protocol> != Class; Class <Protocol> = Class */
1003 else if (objc_is_class_id (TREE_TYPE (rhs)))
1005 return IS_CLASS (lhs);
1007 /* <Protocol> = ?? : let comptypes decide. */
1010 else if (rhs_is_proto)
1012 /* <class> * = <Protocol> */
1013 if (TYPED_OBJECT (TREE_TYPE (lhs)))
1015 /* <class> * != Class <Protocol> */
1021 tree rname = OBJC_TYPE_NAME (TREE_TYPE (lhs));
1023 tree rproto, rproto_list = TYPE_PROTOCOL_LIST (rhs);
1025 /* Make sure the protocol is supported by the object on
1027 for (rproto = rproto_list; rproto;
1028 rproto = TREE_CHAIN (rproto))
1030 tree p = TREE_VALUE (rproto);
1032 rinter = lookup_interface (rname);
1034 while (rinter && !lproto)
1038 tree lproto_list = CLASS_PROTOCOL_LIST (rinter);
1039 lproto = lookup_protocol_in_reflist (lproto_list, p);
1040 /* If the underlying ObjC class does not
1041 have the protocol we're looking for,
1042 check for "one-off" protocols (e.g.,
1043 `NSObject<MyProt> *foo;') attached to the
1047 lproto_list = TYPE_PROTOCOL_LIST
1049 lproto = lookup_protocol_in_reflist
1053 /* Check for protocols adopted by categories. */
1054 cat = CLASS_CATEGORY_LIST (rinter);
1055 while (cat && !lproto)
1057 lproto_list = CLASS_PROTOCOL_LIST (cat);
1058 lproto = lookup_protocol_in_reflist (lproto_list,
1060 cat = CLASS_CATEGORY_LIST (cat);
1063 rinter = lookup_interface (CLASS_SUPER_NAME
1068 warning ("class `%s' does not implement the `%s' protocol",
1069 IDENTIFIER_POINTER (OBJC_TYPE_NAME
1071 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
1078 /* id = id <Protocol>; id = Class <Protocol> */
1079 else if (objc_is_object_id (TREE_TYPE (lhs)))
1083 /* Class != id <Protocol>; Class = Class <Protocol> */
1084 else if (objc_is_class_id (TREE_TYPE (lhs)))
1086 return IS_CLASS (rhs);
1088 /* ??? = <Protocol> : let comptypes decide */
1096 /* Attention: we shouldn't defer to comptypes here. One bad
1097 side effect would be that we might loose the REFLEXIVE
1100 lhs = TREE_TYPE (lhs);
1101 rhs = TREE_TYPE (rhs);
1105 if (TREE_CODE (lhs) != RECORD_TYPE || TREE_CODE (rhs) != RECORD_TYPE)
1107 /* Nothing to do with ObjC - let immediately comptypes take
1108 responsibility for checking. */
1112 /* `id' = `<class> *' `<class> *' = `id': always allow it.
1114 'Object *o = [[Object alloc] init]; falls
1115 in the case <class> * = `id'.
1117 if ((objc_is_object_id (lhs) && TYPED_OBJECT (rhs))
1118 || (objc_is_object_id (rhs) && TYPED_OBJECT (lhs)))
1121 /* `id' = `Class', `Class' = `id' */
1123 else if ((objc_is_object_id (lhs) && objc_is_class_id (rhs))
1124 || (objc_is_class_id (lhs) && objc_is_object_id (rhs)))
1127 /* `Class' != `<class> *' && `<class> *' != `Class'! */
1128 else if ((OBJC_TYPE_NAME (lhs) == objc_class_id && TYPED_OBJECT (rhs))
1129 || (OBJC_TYPE_NAME (rhs) == objc_class_id && TYPED_OBJECT (lhs)))
1132 /* `<class> *' = `<class> *' */
1134 else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs))
1136 tree lname = OBJC_TYPE_NAME (lhs);
1137 tree rname = OBJC_TYPE_NAME (rhs);
1143 /* If the left hand side is a super class of the right hand side,
1145 for (inter = lookup_interface (rname); inter;
1146 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
1147 if (lname == CLASS_SUPER_NAME (inter))
1150 /* Allow the reverse when reflexive. */
1152 for (inter = lookup_interface (lname); inter;
1153 inter = lookup_interface (CLASS_SUPER_NAME (inter)))
1154 if (rname == CLASS_SUPER_NAME (inter))
1160 /* Not an ObjC type - let comptypes do the check. */
1164 /* Called from finish_decl. */
1167 objc_check_decl (tree decl)
1169 tree type = TREE_TYPE (decl);
1171 if (TREE_CODE (type) != RECORD_TYPE)
1173 if (OBJC_TYPE_NAME (type) && (type = objc_is_class_name (OBJC_TYPE_NAME (type))))
1174 error ("statically allocated instance of Objective-C class `%s'",
1175 IDENTIFIER_POINTER (type));
1178 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1179 either name an Objective-C class, or refer to the special 'id' or 'Class'
1180 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
1183 objc_get_protocol_qualified_type (tree interface, tree protocols)
1188 type = objc_object_type;
1189 else if (!(type = objc_is_id (interface)))
1191 type = objc_is_class_name (interface);
1194 type = xref_tag (RECORD_TYPE, type);
1201 type = build_variant_type_copy (type);
1202 /* Look up protocols and install in lang specific list. Note
1203 that the protocol list can have a different lifetime than T! */
1204 SET_TYPE_PROTOCOL_LIST (type, lookup_and_install_protocols (protocols));
1206 /* Establish the ObjC-ness of this record. */
1207 if (TREE_CODE (type) == RECORD_TYPE)
1208 TREE_STATIC_TEMPLATE (type) = 1;
1214 /* Check for circular dependencies in protocols. The arguments are
1215 PROTO, the protocol to check, and LIST, a list of protocol it
1219 check_protocol_recursively (tree proto, tree list)
1223 for (p = list; p; p = TREE_CHAIN (p))
1225 tree pp = TREE_VALUE (p);
1227 if (TREE_CODE (pp) == IDENTIFIER_NODE)
1228 pp = lookup_protocol (pp);
1231 fatal_error ("protocol `%s' has circular dependency",
1232 IDENTIFIER_POINTER (PROTOCOL_NAME (pp)));
1234 check_protocol_recursively (proto, PROTOCOL_LIST (pp));
1238 /* Look up PROTOCOLS, and return a list of those that are found.
1239 If none are found, return NULL. */
1242 lookup_and_install_protocols (tree protocols)
1245 tree return_value = NULL_TREE;
1247 for (proto = protocols; proto; proto = TREE_CHAIN (proto))
1249 tree ident = TREE_VALUE (proto);
1250 tree p = lookup_protocol (ident);
1253 error ("cannot find protocol declaration for `%s'",
1254 IDENTIFIER_POINTER (ident));
1256 return_value = chainon (return_value,
1257 build_tree_list (NULL_TREE, p));
1260 return return_value;
1263 /* Create a declaration for field NAME of a given TYPE. */
1266 create_field_decl (tree type, const char *name)
1268 return build_decl (FIELD_DECL, get_identifier (name), type);
1271 /* Create a global, static declaration for variable NAME of a given TYPE. The
1272 finish_var_decl() routine will need to be called on it afterwards. */
1275 start_var_decl (tree type, const char *name)
1277 tree var = build_decl (VAR_DECL, get_identifier (name), type);
1279 TREE_STATIC (var) = 1;
1280 DECL_INITIAL (var) = error_mark_node; /* A real initializer is coming... */
1281 DECL_IGNORED_P (var) = 1;
1282 DECL_ARTIFICIAL (var) = 1;
1283 DECL_CONTEXT (var) = NULL_TREE;
1285 DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
1291 /* Finish off the variable declaration created by start_var_decl(). */
1294 finish_var_decl (tree var, tree initializer)
1296 finish_decl (var, initializer, NULL_TREE);
1297 /* Ensure that the variable actually gets output. */
1298 mark_decl_referenced (var);
1299 /* Mark the decl to avoid "defined but not used" warning. */
1300 TREE_USED (var) = 1;
1303 /* Find the decl for the constant string class reference. This is only
1304 used for the NeXT runtime. */
1307 setup_string_decl (void)
1312 /* %s in format will provide room for terminating null */
1313 length = strlen (STRING_OBJECT_GLOBAL_FORMAT)
1314 + strlen (constant_string_class_name);
1315 name = xmalloc (length);
1316 sprintf (name, STRING_OBJECT_GLOBAL_FORMAT,
1317 constant_string_class_name);
1318 constant_string_global_id = get_identifier (name);
1319 string_class_decl = lookup_name (constant_string_global_id);
1321 return string_class_decl;
1324 /* Purpose: "play" parser, creating/installing representations
1325 of the declarations that are required by Objective-C.
1329 type_spec--------->sc_spec
1330 (tree_list) (tree_list)
1333 identifier_node identifier_node */
1336 synth_module_prologue (void)
1339 enum debug_info_type save_write_symbols = write_symbols;
1340 const struct gcc_debug_hooks *const save_hooks = debug_hooks;
1342 /* Suppress outputting debug symbols, because
1343 dbxout_init hasn'r been called yet. */
1344 write_symbols = NO_DEBUG;
1345 debug_hooks = &do_nothing_debug_hooks;
1348 push_lang_context (lang_name_c); /* extern "C" */
1351 /* The following are also defined in <objc/objc.h> and friends. */
1353 objc_object_id = get_identifier (TAG_OBJECT);
1354 objc_class_id = get_identifier (TAG_CLASS);
1356 objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id);
1357 objc_class_reference = xref_tag (RECORD_TYPE, objc_class_id);
1359 objc_object_type = build_pointer_type (objc_object_reference);
1360 objc_class_type = build_pointer_type (objc_class_reference);
1362 objc_object_name = get_identifier (OBJECT_TYPEDEF_NAME);
1363 objc_class_name = get_identifier (CLASS_TYPEDEF_NAME);
1365 /* Declare the 'id' and 'Class' typedefs. */
1367 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1370 DECL_IN_SYSTEM_HEADER (type) = 1;
1371 type = lang_hooks.decls.pushdecl (build_decl (TYPE_DECL,
1374 DECL_IN_SYSTEM_HEADER (type) = 1;
1376 /* Forward-declare '@interface Protocol'. */
1378 type = get_identifier (PROTOCOL_OBJECT_CLASS_NAME);
1379 objc_declare_class (tree_cons (NULL_TREE, type, NULL_TREE));
1380 objc_protocol_type = build_pointer_type (xref_tag (RECORD_TYPE,
1383 /* Declare type of selector-objects that represent an operation name. */
1385 if (flag_next_runtime)
1386 /* `struct objc_selector *' */
1388 = build_pointer_type (xref_tag (RECORD_TYPE,
1389 get_identifier (TAG_SELECTOR)));
1391 /* `const struct objc_selector *' */
1393 = build_pointer_type
1394 (build_qualified_type (xref_tag (RECORD_TYPE,
1395 get_identifier (TAG_SELECTOR)),
1398 /* Declare receiver type used for dispatching messages to 'super'. */
1400 /* `struct objc_super *' */
1401 objc_super_type = build_pointer_type (xref_tag (RECORD_TYPE,
1402 get_identifier (TAG_SUPER)));
1404 if (flag_next_runtime)
1406 /* NB: In order to call one of the ..._stret (struct-returning)
1407 functions, the function *MUST* first be cast to a signature that
1408 corresponds to the actual ObjC method being invoked. This is
1409 what is done by the build_objc_method_call() routine below. */
1411 /* id objc_msgSend (id, SEL, ...); */
1412 /* id objc_msgSendNonNil (id, SEL, ...); */
1413 /* id objc_msgSend_stret (id, SEL, ...); */
1414 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1416 = build_function_type (objc_object_type,
1417 tree_cons (NULL_TREE, objc_object_type,
1418 tree_cons (NULL_TREE, objc_selector_type,
1420 umsg_decl = builtin_function (TAG_MSGSEND,
1421 type, 0, NOT_BUILT_IN,
1423 umsg_nonnil_decl = builtin_function (TAG_MSGSEND_NONNIL,
1424 type, 0, NOT_BUILT_IN,
1426 umsg_stret_decl = builtin_function (TAG_MSGSEND_STRET,
1427 type, 0, NOT_BUILT_IN,
1429 umsg_nonnil_stret_decl = builtin_function (TAG_MSGSEND_NONNIL_STRET,
1430 type, 0, NOT_BUILT_IN,
1433 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1434 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1436 = build_function_type (objc_object_type,
1437 tree_cons (NULL_TREE, objc_super_type,
1438 tree_cons (NULL_TREE, objc_selector_type,
1440 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1441 type, 0, NOT_BUILT_IN,
1443 umsg_super_stret_decl = builtin_function (TAG_MSGSENDSUPER_STRET,
1444 type, 0, NOT_BUILT_IN, 0,
1449 /* GNU runtime messenger entry points. */
1451 /* typedef id (*IMP)(id, SEL, ...); */
1453 = build_pointer_type
1454 (build_function_type (objc_object_type,
1455 tree_cons (NULL_TREE, objc_object_type,
1456 tree_cons (NULL_TREE, objc_selector_type,
1459 /* IMP objc_msg_lookup (id, SEL); */
1461 = build_function_type (IMP_type,
1462 tree_cons (NULL_TREE, objc_object_type,
1463 tree_cons (NULL_TREE, objc_selector_type,
1464 OBJC_VOID_AT_END)));
1465 umsg_decl = builtin_function (TAG_MSGSEND,
1466 type, 0, NOT_BUILT_IN,
1469 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1471 = build_function_type (IMP_type,
1472 tree_cons (NULL_TREE, objc_super_type,
1473 tree_cons (NULL_TREE, objc_selector_type,
1474 OBJC_VOID_AT_END)));
1475 umsg_super_decl = builtin_function (TAG_MSGSENDSUPER,
1476 type, 0, NOT_BUILT_IN,
1479 /* The following GNU runtime entry point is called to initialize
1482 __objc_exec_class (void *); */
1484 = build_function_type (void_type_node,
1485 tree_cons (NULL_TREE, ptr_type_node,
1487 execclass_decl = builtin_function (TAG_EXECCLASS,
1488 type, 0, NOT_BUILT_IN,
1492 /* id objc_getClass (const char *); */
1494 type = build_function_type (objc_object_type,
1495 tree_cons (NULL_TREE,
1496 const_string_type_node,
1500 = builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
1503 /* id objc_getMetaClass (const char *); */
1505 objc_get_meta_class_decl
1506 = builtin_function (TAG_GETMETACLASS, type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
1508 build_class_template ();
1509 build_super_template ();
1510 build_protocol_template ();
1511 build_category_template ();
1512 build_objc_exception_stuff ();
1514 if (flag_next_runtime)
1515 build_next_objc_exception_stuff ();
1517 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1519 if (! flag_next_runtime)
1520 build_selector_table_decl ();
1522 /* Forward declare constant_string_id and constant_string_type. */
1523 if (!constant_string_class_name)
1524 constant_string_class_name = default_constant_string_class_name;
1526 constant_string_id = get_identifier (constant_string_class_name);
1527 objc_declare_class (tree_cons (NULL_TREE, constant_string_id, NULL_TREE));
1529 /* Pre-build the following entities - for speed/convenience. */
1530 self_id = get_identifier ("self");
1531 ucmd_id = get_identifier ("_cmd");
1533 /* The C++ front-end does not appear to grok __attribute__((__unused__)). */
1534 unused_list = build_tree_list (get_identifier ("__unused__"), NULL_TREE);
1538 pop_lang_context ();
1541 write_symbols = save_write_symbols;
1542 debug_hooks = save_hooks;
1545 /* Ensure that the ivar list for NSConstantString/NXConstantString
1546 (or whatever was specified via `-fconstant-string-class')
1547 contains fields at least as large as the following three, so that
1548 the runtime can stomp on them with confidence:
1550 struct STRING_OBJECT_CLASS_NAME
1554 unsigned int length;
1558 check_string_class_template (void)
1560 tree field_decl = TYPE_FIELDS (constant_string_type);
1562 #define AT_LEAST_AS_LARGE_AS(F, T) \
1563 (F && TREE_CODE (F) == FIELD_DECL \
1564 && (TREE_INT_CST_LOW (DECL_SIZE (F)) \
1565 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1567 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1570 field_decl = TREE_CHAIN (field_decl);
1571 if (!AT_LEAST_AS_LARGE_AS (field_decl, ptr_type_node))
1574 field_decl = TREE_CHAIN (field_decl);
1575 return AT_LEAST_AS_LARGE_AS (field_decl, unsigned_type_node);
1577 #undef AT_LEAST_AS_LARGE_AS
1580 /* Avoid calling `check_string_class_template ()' more than once. */
1581 static GTY(()) int string_layout_checked;
1583 /* Custom build_string which sets TREE_TYPE! */
1586 my_build_string (int len, const char *str)
1588 return fix_string_type (build_string (len, str));
1593 string_hash (const void *ptr)
1595 tree str = ((struct string_descriptor *)ptr)->literal;
1596 const unsigned char *p = (const unsigned char *) TREE_STRING_POINTER (str);
1597 int i, len = TREE_STRING_LENGTH (str);
1600 for (i = 0; i < len; i++)
1601 h = ((h * 613) + p[i]);
1607 string_eq (const void *ptr1, const void *ptr2)
1609 tree str1 = ((struct string_descriptor *)ptr1)->literal;
1610 tree str2 = ((struct string_descriptor *)ptr2)->literal;
1611 int len1 = TREE_STRING_LENGTH (str1);
1613 return (len1 == TREE_STRING_LENGTH (str2)
1614 && !memcmp (TREE_STRING_POINTER (str1), TREE_STRING_POINTER (str2),
1618 /* Given a chain of STRING_CST's, build a static instance of
1619 NXConstantString which points at the concatenation of those
1620 strings. We place the string object in the __string_objects
1621 section of the __OBJC segment. The Objective-C runtime will
1622 initialize the isa pointers of the string objects to point at the
1623 NXConstantString class object. */
1626 objc_build_string_object (tree string)
1628 tree initlist, constructor, constant_string_class;
1631 struct string_descriptor *desc, key;
1634 /* Prep the string argument. */
1635 string = fix_string_type (string);
1636 TREE_SET_CODE (string, STRING_CST);
1637 length = TREE_STRING_LENGTH (string) - 1;
1639 /* Check whether the string class being used actually exists and has the
1640 correct ivar layout. */
1641 if (!string_layout_checked)
1643 string_layout_checked = -1;
1644 constant_string_class = lookup_interface (constant_string_id);
1646 if (!constant_string_class
1647 || !(constant_string_type
1648 = CLASS_STATIC_TEMPLATE (constant_string_class)))
1649 error ("cannot find interface declaration for `%s'",
1650 IDENTIFIER_POINTER (constant_string_id));
1651 /* The NSConstantString/NXConstantString ivar layout is now known. */
1652 else if (!check_string_class_template ())
1653 error ("interface `%s' does not have valid constant string layout",
1654 IDENTIFIER_POINTER (constant_string_id));
1655 /* For the NeXT runtime, we can generate a literal reference
1656 to the string class, don't need to run a constructor. */
1657 else if (flag_next_runtime && !setup_string_decl ())
1658 error ("cannot find reference tag for class `%s'",
1659 IDENTIFIER_POINTER (constant_string_id));
1662 string_layout_checked = 1; /* Success! */
1663 add_class_reference (constant_string_id);
1667 if (string_layout_checked == -1)
1668 return error_mark_node;
1670 /* Perhaps we already constructed a constant string just like this one? */
1671 key.literal = string;
1672 loc = htab_find_slot (string_htab, &key, INSERT);
1678 *loc = desc = ggc_alloc (sizeof (*desc));
1679 desc->literal = string;
1681 /* GNU: & ((NXConstantString) { NULL, string, length }) */
1682 /* NeXT: & ((NSConstantString) { isa, string, length }) */
1683 fields = TYPE_FIELDS (constant_string_type);
1685 = build_tree_list (fields,
1687 ? build_unary_op (ADDR_EXPR, string_class_decl, 0)
1688 : build_int_cst (NULL_TREE, 0));
1689 fields = TREE_CHAIN (fields);
1690 initlist = tree_cons (fields, build_unary_op (ADDR_EXPR, string, 1),
1692 fields = TREE_CHAIN (fields);
1693 initlist = tree_cons (fields, build_int_cst (NULL_TREE, length),
1695 constructor = objc_build_constructor (constant_string_type,
1696 nreverse (initlist));
1697 TREE_INVARIANT (constructor) = true;
1699 if (!flag_next_runtime)
1701 = objc_add_static_instance (constructor, constant_string_type);
1704 var = build_decl (CONST_DECL, NULL, TREE_TYPE (constructor));
1705 DECL_INITIAL (var) = constructor;
1706 TREE_STATIC (var) = 1;
1707 pushdecl_top_level (var);
1710 desc->constructor = constructor;
1713 addr = build_unary_op (ADDR_EXPR, desc->constructor, 1);
1718 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1720 static GTY(()) int num_static_inst;
1723 objc_add_static_instance (tree constructor, tree class_decl)
1728 /* Find the list of static instances for the CLASS_DECL. Create one if
1730 for (chain = &objc_static_instances;
1731 *chain && TREE_VALUE (*chain) != class_decl;
1732 chain = &TREE_CHAIN (*chain));
1735 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
1736 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
1739 sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++);
1740 decl = build_decl (VAR_DECL, get_identifier (buf), class_decl);
1741 DECL_COMMON (decl) = 1;
1742 TREE_STATIC (decl) = 1;
1743 DECL_ARTIFICIAL (decl) = 1;
1744 DECL_INITIAL (decl) = constructor;
1746 /* We may be writing something else just now.
1747 Postpone till end of input. */
1748 DECL_DEFER_OUTPUT (decl) = 1;
1749 pushdecl_top_level (decl);
1750 rest_of_decl_compilation (decl, 1, 0);
1752 /* Add the DECL to the head of this CLASS' list. */
1753 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
1758 /* Build a static constant CONSTRUCTOR
1759 with type TYPE and elements ELTS. */
1762 objc_build_constructor (tree type, tree elts)
1764 tree constructor = build_constructor (type, elts);
1766 TREE_CONSTANT (constructor) = 1;
1767 TREE_STATIC (constructor) = 1;
1768 TREE_READONLY (constructor) = 1;
1771 /* Adjust for impedance mismatch. We should figure out how to build
1772 CONSTRUCTORs that consistently please both the C and C++ gods. */
1773 if (!TREE_PURPOSE (elts))
1774 TREE_TYPE (constructor) = NULL_TREE;
1775 TREE_HAS_CONSTRUCTOR (constructor) = 1;
1781 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1783 /* Predefine the following data type:
1791 void *defs[cls_def_cnt + cat_def_cnt];
1795 build_objc_symtab_template (void)
1797 tree field_decl, field_decl_chain;
1799 objc_symtab_template
1800 = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB));
1802 /* long sel_ref_cnt; */
1803 field_decl = create_field_decl (long_integer_type_node, "sel_ref_cnt");
1804 field_decl_chain = field_decl;
1807 field_decl = create_field_decl (build_pointer_type (objc_selector_type),
1809 chainon (field_decl_chain, field_decl);
1811 /* short cls_def_cnt; */
1812 field_decl = create_field_decl (short_integer_type_node, "cls_def_cnt");
1813 chainon (field_decl_chain, field_decl);
1815 /* short cat_def_cnt; */
1816 field_decl = create_field_decl (short_integer_type_node,
1818 chainon (field_decl_chain, field_decl);
1820 if (imp_count || cat_count || !flag_next_runtime)
1822 /* void *defs[imp_count + cat_count (+ 1)]; */
1823 /* NB: The index is one less than the size of the array. */
1824 int index = imp_count + cat_count
1825 + (flag_next_runtime? -1: 0);
1826 field_decl = create_field_decl
1829 build_index_type (build_int_cst (NULL_TREE, index))),
1831 chainon (field_decl_chain, field_decl);
1834 finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE);
1837 /* Create the initial value for the `defs' field of _objc_symtab.
1838 This is a CONSTRUCTOR. */
1841 init_def_list (tree type)
1843 tree expr, initlist = NULL_TREE;
1844 struct imp_entry *impent;
1847 for (impent = imp_list; impent; impent = impent->next)
1849 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1851 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1852 initlist = tree_cons (NULL_TREE, expr, initlist);
1857 for (impent = imp_list; impent; impent = impent->next)
1859 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1861 expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0);
1862 initlist = tree_cons (NULL_TREE, expr, initlist);
1866 if (!flag_next_runtime)
1868 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1871 if (static_instances_decl)
1872 expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0);
1874 expr = build_int_cst (NULL_TREE, 0);
1876 initlist = tree_cons (NULL_TREE, expr, initlist);
1879 return objc_build_constructor (type, nreverse (initlist));
1882 /* Construct the initial value for all of _objc_symtab. */
1885 init_objc_symtab (tree type)
1889 /* sel_ref_cnt = { ..., 5, ... } */
1891 initlist = build_tree_list (NULL_TREE,
1892 build_int_cst (long_integer_type_node, 0));
1894 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1896 if (flag_next_runtime || ! sel_ref_chain)
1897 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
1900 = tree_cons (NULL_TREE,
1901 convert (build_pointer_type (objc_selector_type),
1902 build_unary_op (ADDR_EXPR,
1903 UOBJC_SELECTOR_TABLE_decl, 1)),
1906 /* cls_def_cnt = { ..., 5, ... } */
1908 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, imp_count), initlist);
1910 /* cat_def_cnt = { ..., 5, ... } */
1912 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, cat_count), initlist);
1914 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1916 if (imp_count || cat_count || !flag_next_runtime)
1919 tree field = TYPE_FIELDS (type);
1920 field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field))));
1922 initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)),
1926 return objc_build_constructor (type, nreverse (initlist));
1929 /* Generate forward declarations for metadata such as
1930 'OBJC_CLASS_...'. */
1933 build_metadata_decl (const char *name, tree type)
1937 /* struct TYPE NAME_<name>; */
1938 decl = start_var_decl (type, synth_id_with_class_suffix
1940 objc_implementation_context));
1945 /* Push forward-declarations of all the categories so that
1946 init_def_list can use them in a CONSTRUCTOR. */
1949 forward_declare_categories (void)
1951 struct imp_entry *impent;
1952 tree sav = objc_implementation_context;
1954 for (impent = imp_list; impent; impent = impent->next)
1956 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1958 /* Set an invisible arg to synth_id_with_class_suffix. */
1959 objc_implementation_context = impent->imp_context;
1960 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
1961 impent->class_decl = build_metadata_decl ("_OBJC_CATEGORY",
1962 objc_category_template);
1965 objc_implementation_context = sav;
1968 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
1969 and initialized appropriately. */
1972 generate_objc_symtab_decl (void)
1974 /* forward declare categories */
1976 forward_declare_categories ();
1978 build_objc_symtab_template ();
1979 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
1980 finish_var_decl (UOBJC_SYMBOLS_decl,
1981 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
1985 init_module_descriptor (tree type)
1987 tree initlist, expr;
1989 /* version = { 1, ... } */
1991 expr = build_int_cst (long_integer_type_node, OBJC_VERSION);
1992 initlist = build_tree_list (NULL_TREE, expr);
1994 /* size = { ..., sizeof (struct _objc_module), ... } */
1996 expr = convert (long_integer_type_node,
1997 size_in_bytes (objc_module_template));
1998 initlist = tree_cons (NULL_TREE, expr, initlist);
2000 /* name = { ..., "foo.m", ... } */
2002 expr = add_objc_string (get_identifier (input_filename), class_names);
2003 initlist = tree_cons (NULL_TREE, expr, initlist);
2005 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2007 if (UOBJC_SYMBOLS_decl)
2008 expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0);
2010 expr = build_int_cst (NULL_TREE, 0);
2011 initlist = tree_cons (NULL_TREE, expr, initlist);
2013 return objc_build_constructor (type, nreverse (initlist));
2016 /* Write out the data structures to describe Objective C classes defined.
2018 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2021 build_module_descriptor (void)
2023 tree field_decl, field_decl_chain;
2026 push_lang_context (lang_name_c); /* extern "C" */
2029 objc_module_template
2030 = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE));
2033 field_decl = create_field_decl (long_integer_type_node, "version");
2034 field_decl_chain = field_decl;
2037 field_decl = create_field_decl (long_integer_type_node, "size");
2038 chainon (field_decl_chain, field_decl);
2041 field_decl = create_field_decl (string_type_node, "name");
2042 chainon (field_decl_chain, field_decl);
2044 /* struct _objc_symtab *symtab; */
2046 = create_field_decl (build_pointer_type
2047 (xref_tag (RECORD_TYPE,
2048 get_identifier (UTAG_SYMTAB))),
2050 chainon (field_decl_chain, field_decl);
2052 finish_struct (objc_module_template, field_decl_chain, NULL_TREE);
2054 /* Create an instance of "_objc_module". */
2055 UOBJC_MODULES_decl = start_var_decl (objc_module_template, "_OBJC_MODULES");
2056 finish_var_decl (UOBJC_MODULES_decl,
2057 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)));
2060 pop_lang_context ();
2064 /* The GNU runtime requires us to provide a static initializer function
2067 static void __objc_gnu_init (void) {
2068 __objc_exec_class (&L_OBJC_MODULES);
2072 build_module_initializer_routine (void)
2077 push_lang_context (lang_name_c); /* extern "C" */
2080 objc_push_parm (build_decl (PARM_DECL, NULL_TREE, void_type_node));
2081 objc_start_function (get_identifier (TAG_GNUINIT),
2082 build_function_type (void_type_node,
2084 NULL_TREE, objc_get_parm_info (0));
2086 body = c_begin_compound_stmt (true);
2087 add_stmt (build_function_call
2091 build_unary_op (ADDR_EXPR,
2092 UOBJC_MODULES_decl, 0))));
2093 add_stmt (c_end_compound_stmt (body, true));
2095 TREE_PUBLIC (current_function_decl) = 0;
2098 /* For Objective-C++, we will need to call __objc_gnu_init
2099 from objc_generate_static_init_call() below. */
2100 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
2103 GNU_INIT_decl = current_function_decl;
2107 pop_lang_context ();
2112 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2113 to be called by the module initializer routine. */
2116 objc_static_init_needed_p (void)
2118 return (GNU_INIT_decl != NULL_TREE);
2121 /* Generate a call to the __objc_gnu_init initializer function. */
2124 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
2126 add_stmt (build_stmt (EXPR_STMT,
2127 build_function_call (GNU_INIT_decl, NULL_TREE)));
2131 #endif /* OBJCPLUS */
2133 /* Return the DECL of the string IDENT in the SECTION. */
2136 get_objc_string_decl (tree ident, enum string_section section)
2140 if (section == class_names)
2141 chain = class_names_chain;
2142 else if (section == meth_var_names)
2143 chain = meth_var_names_chain;
2144 else if (section == meth_var_types)
2145 chain = meth_var_types_chain;
2149 for (; chain != 0; chain = TREE_CHAIN (chain))
2150 if (TREE_VALUE (chain) == ident)
2151 return (TREE_PURPOSE (chain));
2157 /* Output references to all statically allocated objects. Return the DECL
2158 for the array built. */
2161 generate_static_references (void)
2163 tree decls = NULL_TREE, expr = NULL_TREE;
2164 tree class_name, class, decl, initlist;
2165 tree cl_chain, in_chain, type
2166 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
2167 int num_inst, num_class;
2170 if (flag_next_runtime)
2173 for (cl_chain = objc_static_instances, num_class = 0;
2174 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
2176 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
2177 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
2179 sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class);
2180 decl = start_var_decl (type, buf);
2182 /* Output {class_name, ...}. */
2183 class = TREE_VALUE (cl_chain);
2184 class_name = get_objc_string_decl (OBJC_TYPE_NAME (class), class_names);
2185 initlist = build_tree_list (NULL_TREE,
2186 build_unary_op (ADDR_EXPR, class_name, 1));
2188 /* Output {..., instance, ...}. */
2189 for (in_chain = TREE_PURPOSE (cl_chain);
2190 in_chain; in_chain = TREE_CHAIN (in_chain))
2192 expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1);
2193 initlist = tree_cons (NULL_TREE, expr, initlist);
2196 /* Output {..., NULL}. */
2197 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
2199 expr = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
2200 finish_var_decl (decl, expr);
2202 = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls);
2205 decls = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), decls);
2206 expr = objc_build_constructor (type, nreverse (decls));
2207 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
2208 finish_var_decl (static_instances_decl, expr);
2211 /* Output all strings. */
2214 generate_strings (void)
2216 tree chain, string_expr;
2217 tree string, decl, type;
2219 for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
2221 string = TREE_VALUE (chain);
2222 decl = TREE_PURPOSE (chain);
2223 type = build_array_type
2226 (build_int_cst (NULL_TREE,
2227 IDENTIFIER_LENGTH (string))));
2228 decl = start_var_decl (type, IDENTIFIER_POINTER (DECL_NAME (decl)));
2229 string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
2230 IDENTIFIER_POINTER (string));
2231 finish_var_decl (decl, string_expr);
2234 for (chain = meth_var_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_types_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);
2265 static GTY(()) int selector_reference_idx;
2268 build_selector_reference_decl (void)
2273 sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx++);
2274 decl = start_var_decl (objc_selector_type, buf);
2280 build_selector_table_decl (void)
2284 if (flag_typed_selectors)
2286 build_selector_template ();
2287 temp = build_array_type (objc_selector_template, NULL_TREE);
2290 temp = build_array_type (objc_selector_type, NULL_TREE);
2292 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
2295 /* Just a handy wrapper for add_objc_string. */
2298 build_selector (tree ident)
2300 return convert (objc_selector_type,
2301 add_objc_string (ident, meth_var_names));
2305 build_selector_translation_table (void)
2307 tree chain, initlist = NULL_TREE;
2309 tree decl = NULL_TREE;
2311 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
2315 if (warn_selector && objc_implementation_context)
2319 for (method_chain = meth_var_names_chain;
2321 method_chain = TREE_CHAIN (method_chain))
2323 if (TREE_VALUE (method_chain) == TREE_VALUE (chain))
2330 warning ("%Jcreating selector for nonexistent method %qE",
2331 TREE_PURPOSE (chain), TREE_VALUE (chain));
2334 expr = build_selector (TREE_VALUE (chain));
2335 /* add one for the '\0' character */
2336 offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1;
2338 if (flag_next_runtime)
2340 decl = TREE_PURPOSE (chain);
2341 finish_var_decl (decl, expr);
2345 if (flag_typed_selectors)
2347 tree eltlist = NULL_TREE;
2348 tree encoding = get_proto_encoding (TREE_PURPOSE (chain));
2349 eltlist = tree_cons (NULL_TREE, expr, NULL_TREE);
2350 eltlist = tree_cons (NULL_TREE, encoding, eltlist);
2351 expr = objc_build_constructor (objc_selector_template,
2352 nreverse (eltlist));
2355 initlist = tree_cons (NULL_TREE, expr, initlist);
2359 if (! flag_next_runtime)
2361 /* Cause the selector table (previously forward-declared)
2362 to be actually output. */
2363 initlist = tree_cons (NULL_TREE,
2364 flag_typed_selectors
2365 ? objc_build_constructor
2366 (objc_selector_template,
2367 tree_cons (NULL_TREE,
2368 build_int_cst (NULL_TREE, 0),
2369 tree_cons (NULL_TREE,
2370 build_int_cst (NULL_TREE, 0),
2372 : build_int_cst (NULL_TREE, 0), initlist);
2373 initlist = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
2374 nreverse (initlist));
2375 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, initlist);
2380 get_proto_encoding (tree proto)
2385 if (! METHOD_ENCODING (proto))
2387 encoding = encode_method_prototype (proto);
2388 METHOD_ENCODING (proto) = encoding;
2391 encoding = METHOD_ENCODING (proto);
2393 return add_objc_string (encoding, meth_var_types);
2396 return build_int_cst (NULL_TREE, 0);
2399 /* sel_ref_chain is a list whose "value" fields will be instances of
2400 identifier_node that represent the selector. */
2403 build_typed_selector_reference (tree ident, tree prototype)
2405 tree *chain = &sel_ref_chain;
2411 if (TREE_PURPOSE (*chain) == prototype && TREE_VALUE (*chain) == ident)
2412 goto return_at_index;
2415 chain = &TREE_CHAIN (*chain);
2418 *chain = tree_cons (prototype, ident, NULL_TREE);
2421 expr = build_unary_op (ADDR_EXPR,
2422 build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2423 build_int_cst (NULL_TREE, index)),
2425 return convert (objc_selector_type, expr);
2429 build_selector_reference (tree ident)
2431 tree *chain = &sel_ref_chain;
2437 if (TREE_VALUE (*chain) == ident)
2438 return (flag_next_runtime
2439 ? TREE_PURPOSE (*chain)
2440 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2441 build_int_cst (NULL_TREE, index)));
2444 chain = &TREE_CHAIN (*chain);
2447 expr = (flag_next_runtime ? build_selector_reference_decl (): NULL_TREE);
2449 *chain = tree_cons (expr, ident, NULL_TREE);
2451 return (flag_next_runtime
2453 : build_array_ref (UOBJC_SELECTOR_TABLE_decl,
2454 build_int_cst (NULL_TREE, index)));
2457 static GTY(()) int class_reference_idx;
2460 build_class_reference_decl (void)
2465 sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx++);
2466 decl = start_var_decl (objc_class_type, buf);
2471 /* Create a class reference, but don't create a variable to reference
2475 add_class_reference (tree ident)
2479 if ((chain = cls_ref_chain))
2484 if (ident == TREE_VALUE (chain))
2488 chain = TREE_CHAIN (chain);
2492 /* Append to the end of the list */
2493 TREE_CHAIN (tail) = tree_cons (NULL_TREE, ident, NULL_TREE);
2496 cls_ref_chain = tree_cons (NULL_TREE, ident, NULL_TREE);
2499 /* Get a class reference, creating it if necessary. Also create the
2500 reference variable. */
2503 objc_get_class_reference (tree ident)
2508 if (processing_template_decl)
2509 /* Must wait until template instantiation time. */
2510 return build_min_nt (CLASS_REFERENCE_EXPR, ident);
2511 if (TREE_CODE (ident) == TYPE_DECL)
2512 ident = DECL_NAME (ident);
2516 if (!(ident = objc_is_class_name (ident)))
2518 error ("`%s' is not an Objective-C class name or alias",
2519 IDENTIFIER_POINTER (orig_ident));
2520 return error_mark_node;
2523 if (flag_next_runtime && !flag_zero_link)
2528 for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain))
2529 if (TREE_VALUE (*chain) == ident)
2531 if (! TREE_PURPOSE (*chain))
2532 TREE_PURPOSE (*chain) = build_class_reference_decl ();
2534 return TREE_PURPOSE (*chain);
2537 decl = build_class_reference_decl ();
2538 *chain = tree_cons (decl, ident, NULL_TREE);
2545 add_class_reference (ident);
2547 params = build_tree_list (NULL_TREE,
2548 my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2549 IDENTIFIER_POINTER (ident)));
2551 assemble_external (objc_get_class_decl);
2552 return build_function_call (objc_get_class_decl, params);
2556 /* For each string section we have a chain which maps identifier nodes
2557 to decls for the strings. */
2560 add_objc_string (tree ident, enum string_section section)
2564 if (section == class_names)
2565 chain = &class_names_chain;
2566 else if (section == meth_var_names)
2567 chain = &meth_var_names_chain;
2568 else if (section == meth_var_types)
2569 chain = &meth_var_types_chain;
2575 if (TREE_VALUE (*chain) == ident)
2576 return convert (string_type_node,
2577 build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1));
2579 chain = &TREE_CHAIN (*chain);
2582 decl = build_objc_string_decl (section);
2584 *chain = tree_cons (decl, ident, NULL_TREE);
2586 return convert (string_type_node, build_unary_op (ADDR_EXPR, decl, 1));
2589 static GTY(()) int class_names_idx;
2590 static GTY(()) int meth_var_names_idx;
2591 static GTY(()) int meth_var_types_idx;
2594 build_objc_string_decl (enum string_section section)
2599 if (section == class_names)
2600 sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++);
2601 else if (section == meth_var_names)
2602 sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
2603 else if (section == meth_var_types)
2604 sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
2606 ident = get_identifier (buf);
2608 decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0));
2609 DECL_EXTERNAL (decl) = 1;
2610 TREE_PUBLIC (decl) = 0;
2611 TREE_USED (decl) = 1;
2612 TREE_CONSTANT (decl) = 1;
2613 DECL_CONTEXT (decl) = 0;
2614 DECL_ARTIFICIAL (decl) = 1;
2616 DECL_THIS_STATIC (decl) = 1; /* squash redeclaration errors */
2619 make_decl_rtl (decl);
2620 pushdecl_top_level (decl);
2627 objc_declare_alias (tree alias_ident, tree class_ident)
2629 tree underlying_class;
2632 if (current_namespace != global_namespace) {
2633 error ("Objective-C declarations may only appear in global scope");
2635 #endif /* OBJCPLUS */
2637 if (!(underlying_class = objc_is_class_name (class_ident)))
2638 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident));
2639 else if (objc_is_class_name (alias_ident))
2640 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident));
2642 alias_chain = tree_cons (underlying_class, alias_ident, alias_chain);
2646 objc_declare_class (tree ident_list)
2650 if (current_namespace != global_namespace) {
2651 error ("Objective-C declarations may only appear in global scope");
2653 #endif /* OBJCPLUS */
2655 for (list = ident_list; list; list = TREE_CHAIN (list))
2657 tree ident = TREE_VALUE (list);
2659 if (! objc_is_class_name (ident))
2661 tree record = lookup_name (ident);
2663 if (record && ! TREE_STATIC_TEMPLATE (record))
2665 error ("`%s' redeclared as different kind of symbol",
2666 IDENTIFIER_POINTER (ident));
2667 error ("%Jprevious declaration of '%D'",
2671 record = xref_tag (RECORD_TYPE, ident);
2672 TREE_STATIC_TEMPLATE (record) = 1;
2673 class_chain = tree_cons (NULL_TREE, ident, class_chain);
2679 objc_is_class_name (tree ident)
2683 if (ident && TREE_CODE (ident) == IDENTIFIER_NODE
2684 && identifier_global_value (ident))
2685 ident = identifier_global_value (ident);
2686 while (ident && TREE_CODE (ident) == TYPE_DECL && DECL_ORIGINAL_TYPE (ident))
2687 ident = OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident));
2689 if (ident && TREE_CODE (ident) == RECORD_TYPE)
2690 ident = OBJC_TYPE_NAME (ident);
2692 if (ident && TREE_CODE (ident) == TYPE_DECL)
2693 ident = DECL_NAME (ident);
2695 if (!ident || TREE_CODE (ident) != IDENTIFIER_NODE)
2698 if (lookup_interface (ident))
2701 for (chain = class_chain; chain; chain = TREE_CHAIN (chain))
2703 if (ident == TREE_VALUE (chain))
2707 for (chain = alias_chain; chain; chain = TREE_CHAIN (chain))
2709 if (ident == TREE_VALUE (chain))
2710 return TREE_PURPOSE (chain);
2716 /* Check whether TYPE is either 'id' or 'Class'. */
2719 objc_is_id (tree type)
2721 if (type && TREE_CODE (type) == IDENTIFIER_NODE
2722 && identifier_global_value (type))
2723 type = identifier_global_value (type);
2725 if (type && TREE_CODE (type) == TYPE_DECL)
2726 type = TREE_TYPE (type);
2728 /* NB: This function may be called before the ObjC front-end has
2729 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
2730 return (objc_object_type && type
2731 && (IS_ID (type) || IS_CLASS (type) || IS_SUPER (type))
2736 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
2737 class instance. This is needed by other parts of the compiler to
2738 handle ObjC types gracefully. */
2741 objc_is_object_ptr (tree type)
2745 type = TYPE_MAIN_VARIANT (type);
2746 if (!POINTER_TYPE_P (type))
2749 ret = objc_is_id (type);
2751 ret = objc_is_class_name (TREE_TYPE (type));
2757 lookup_interface (tree ident)
2762 if (ident && TREE_CODE (ident) == TYPE_DECL)
2763 ident = DECL_NAME (ident);
2765 for (chain = interface_chain; chain; chain = TREE_CHAIN (chain))
2767 if (ident == CLASS_NAME (chain))
2773 /* Implement @defs (<classname>) within struct bodies. */
2776 objc_get_class_ivars (tree class_name)
2778 tree interface = lookup_interface (class_name);
2781 return get_class_ivars (interface);
2783 error ("cannot find interface declaration for `%s'",
2784 IDENTIFIER_POINTER (class_name));
2786 return error_mark_node;
2789 /* Used by: build_private_template, continue_class,
2790 and for @defs constructs. */
2793 get_class_ivars (tree interface)
2795 tree ivar_chain = copy_list (CLASS_RAW_IVARS (interface));
2797 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
2798 by the current class (i.e., they do not include super-class ivars).
2799 However, the CLASS_IVARS list will be side-effected by a call to
2800 finish_struct(), which will fill in field offsets. */
2801 if (!CLASS_IVARS (interface))
2802 CLASS_IVARS (interface) = ivar_chain;
2804 while (CLASS_SUPER_NAME (interface))
2806 /* Prepend super-class ivars. */
2807 interface = lookup_interface (CLASS_SUPER_NAME (interface));
2808 ivar_chain = chainon (copy_list (CLASS_RAW_IVARS (interface)),
2816 objc_create_temporary_var (tree type)
2820 decl = build_decl (VAR_DECL, NULL_TREE, type);
2821 TREE_USED (decl) = 1;
2822 DECL_ARTIFICIAL (decl) = 1;
2823 DECL_IGNORED_P (decl) = 1;
2824 DECL_CONTEXT (decl) = current_function_decl;
2829 /* Exception handling constructs. We begin by having the parser do most
2830 of the work and passing us blocks. What we do next depends on whether
2831 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
2832 We abstract all of this in a handful of appropriately named routines. */
2834 /* Stack of open try blocks. */
2836 struct objc_try_context
2838 struct objc_try_context *outer;
2840 /* Statements (or statement lists) as processed by the parser. */
2844 /* Some file position locations. */
2845 location_t try_locus;
2846 location_t end_try_locus;
2847 location_t end_catch_locus;
2848 location_t finally_locus;
2849 location_t end_finally_locus;
2851 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
2852 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
2855 /* The CATCH_EXPR of an open @catch clause. */
2858 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
2864 static struct objc_try_context *cur_try_context;
2866 /* This hook, called via lang_eh_runtime_type, generates a runtime object
2867 that represents TYPE. For Objective-C, this is just the class name. */
2868 /* ??? Isn't there a class object or some such? Is it easy to get? */
2872 objc_eh_runtime_type (tree type)
2874 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type)), class_names);
2878 /* Initialize exception handling. */
2881 objc_init_exceptions (void)
2883 static bool done = false;
2888 if (flag_objc_sjlj_exceptions)
2890 /* On Darwin, ObjC exceptions require a sufficiently recent
2891 version of the runtime, so the user must ask for them explicitly. */
2892 if (!flag_objc_exceptions)
2893 warning ("use %<-fobjc-exceptions%> to enable Objective-C "
2894 "exception syntax");
2899 c_eh_initialized_p = true;
2900 eh_personality_libfunc
2901 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
2902 ? "__gnu_objc_personality_sj0"
2903 : "__gnu_objc_personality_v0");
2904 using_eh_for_cleanups ();
2905 lang_eh_runtime_type = objc_eh_runtime_type;
2910 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
2911 we'll arrange for it to be initialized (and associated with a binding)
2915 objc_build_exc_ptr (void)
2917 if (flag_objc_sjlj_exceptions)
2919 tree var = cur_try_context->caught_decl;
2922 var = objc_create_temporary_var (objc_object_type);
2923 cur_try_context->caught_decl = var;
2928 return build (EXC_PTR_EXPR, objc_object_type);
2931 /* Build "objc_exception_try_exit(&_stack)". */
2934 next_sjlj_build_try_exit (void)
2937 t = build_fold_addr_expr (cur_try_context->stack_decl);
2938 t = tree_cons (NULL, t, NULL);
2939 t = build_function_call (objc_exception_try_exit_decl, t);
2944 objc_exception_try_enter (&_stack);
2945 if (_setjmp(&_stack.buf))
2949 Return the COND_EXPR. Note that the THEN and ELSE fields are left
2950 empty, ready for the caller to fill them in. */
2953 next_sjlj_build_enter_and_setjmp (void)
2955 tree t, enter, sj, cond;
2957 t = build_fold_addr_expr (cur_try_context->stack_decl);
2958 t = tree_cons (NULL, t, NULL);
2959 enter = build_function_call (objc_exception_try_enter_decl, t);
2961 t = build_component_ref (cur_try_context->stack_decl,
2962 get_identifier ("buf"));
2963 t = build_fold_addr_expr (t);
2964 t = convert (ptr_type_node, t);
2965 t = tree_cons (NULL, t, NULL);
2966 sj = build_function_call (objc_setjmp_decl, t);
2968 cond = build (COMPOUND_EXPR, TREE_TYPE (sj), enter, sj);
2969 cond = lang_hooks.truthvalue_conversion (cond);
2971 return build (COND_EXPR, void_type_node, cond, NULL, NULL);
2975 DECL = objc_exception_extract(&_stack);
2979 next_sjlj_build_exc_extract (tree decl)
2983 t = build_fold_addr_expr (cur_try_context->stack_decl);
2984 t = tree_cons (NULL, t, NULL);
2985 t = build_function_call (objc_exception_extract_decl, t);
2986 t = convert (TREE_TYPE (decl), t);
2987 t = build (MODIFY_EXPR, void_type_node, decl, t);
2993 if (objc_exception_match(obj_get_class(TYPE), _caught)
3000 objc_exception_try_exit(&_stack);
3002 from the sequence of CATCH_EXPRs in the current try context. */
3005 next_sjlj_build_catch_list (void)
3007 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3009 tree *last = &catch_seq;
3010 bool saw_id = false;
3012 for (; !tsi_end_p (i); tsi_next (&i))
3014 tree stmt = tsi_stmt (i);
3015 tree type = CATCH_TYPES (stmt);
3016 tree body = CATCH_BODY (stmt);
3028 if (type == error_mark_node)
3029 cond = error_mark_node;
3032 args = tree_cons (NULL, cur_try_context->caught_decl, NULL);
3033 t = objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type)));
3034 args = tree_cons (NULL, t, args);
3035 t = build_function_call (objc_exception_match_decl, args);
3036 cond = lang_hooks.truthvalue_conversion (t);
3038 t = build (COND_EXPR, void_type_node, cond, body, NULL);
3039 SET_EXPR_LOCUS (t, EXPR_LOCUS (stmt));
3042 last = &COND_EXPR_ELSE (t);
3048 t = build (MODIFY_EXPR, void_type_node, cur_try_context->rethrow_decl,
3049 cur_try_context->caught_decl);
3050 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3051 append_to_statement_list (t, last);
3053 t = next_sjlj_build_try_exit ();
3054 SET_EXPR_LOCATION (t, cur_try_context->end_catch_locus);
3055 append_to_statement_list (t, last);
3061 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
3062 exception handling. We aim to build:
3065 struct _objc_exception_data _stack;
3066 id volatile _rethrow = 0;
3069 objc_exception_try_enter (&_stack);
3070 if (_setjmp(&_stack.buf))
3072 id _caught = objc_exception_extract(&_stack);
3073 objc_exception_try_enter (&_stack);
3074 if (_setjmp(&_stack.buf))
3075 _rethrow = objc_exception_extract(&_stack);
3085 objc_exception_try_exit(&_stack);
3088 objc_exception_throw(_rethrow);
3092 If CATCH-LIST is empty, we can omit all of the block containing
3093 "_caught" except for the setting of _rethrow. Note the use of
3094 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
3095 but handles goto and other exits from the block. */
3098 next_sjlj_build_try_catch_finally (void)
3100 tree rethrow_decl, stack_decl, t;
3101 tree catch_seq, try_fin, bind;
3103 /* Create the declarations involved. */
3104 t = xref_tag (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3105 stack_decl = objc_create_temporary_var (t);
3106 cur_try_context->stack_decl = stack_decl;
3108 rethrow_decl = objc_create_temporary_var (objc_object_type);
3109 cur_try_context->rethrow_decl = rethrow_decl;
3110 TREE_THIS_VOLATILE (rethrow_decl) = 1;
3111 TREE_CHAIN (rethrow_decl) = stack_decl;
3113 /* Build the outermost variable binding level. */
3114 bind = build (BIND_EXPR, void_type_node, rethrow_decl, NULL, NULL);
3115 SET_EXPR_LOCATION (bind, cur_try_context->try_locus);
3116 TREE_SIDE_EFFECTS (bind) = 1;
3118 /* Initialize rethrow_decl. */
3119 t = build (MODIFY_EXPR, void_type_node, rethrow_decl,
3120 convert (objc_object_type, null_pointer_node));
3121 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3122 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3124 /* Build the outermost TRY_FINALLY_EXPR. */
3125 try_fin = build (TRY_FINALLY_EXPR, void_type_node, NULL, NULL);
3126 SET_EXPR_LOCATION (try_fin, cur_try_context->try_locus);
3127 TREE_SIDE_EFFECTS (try_fin) = 1;
3128 append_to_statement_list (try_fin, &BIND_EXPR_BODY (bind));
3130 /* Create the complete catch sequence. */
3131 if (cur_try_context->catch_list)
3133 tree caught_decl = objc_build_exc_ptr ();
3134 catch_seq = build_stmt (BIND_EXPR, caught_decl, NULL, NULL);
3136 t = next_sjlj_build_exc_extract (caught_decl);
3137 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3139 t = next_sjlj_build_enter_and_setjmp ();
3140 COND_EXPR_THEN (t) = next_sjlj_build_exc_extract (rethrow_decl);
3141 COND_EXPR_ELSE (t) = next_sjlj_build_catch_list ();
3142 append_to_statement_list (t, &BIND_EXPR_BODY (catch_seq));
3145 catch_seq = next_sjlj_build_exc_extract (rethrow_decl);
3146 SET_EXPR_LOCATION (catch_seq, cur_try_context->end_try_locus);
3148 /* Build the main register-and-try if statement. */
3149 t = next_sjlj_build_enter_and_setjmp ();
3150 SET_EXPR_LOCATION (t, cur_try_context->try_locus);
3151 COND_EXPR_THEN (t) = catch_seq;
3152 COND_EXPR_ELSE (t) = cur_try_context->try_body;
3153 TREE_OPERAND (try_fin, 0) = t;
3155 /* Build the complete FINALLY statement list. */
3156 t = next_sjlj_build_try_exit ();
3157 t = build_stmt (COND_EXPR,
3158 lang_hooks.truthvalue_conversion (rethrow_decl),
3160 SET_EXPR_LOCATION (t, cur_try_context->finally_locus);
3161 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3163 append_to_statement_list (cur_try_context->finally_body,
3164 &TREE_OPERAND (try_fin, 1));
3166 t = tree_cons (NULL, rethrow_decl, NULL);
3167 t = build_function_call (objc_exception_throw_decl, t);
3168 t = build_stmt (COND_EXPR,
3169 lang_hooks.truthvalue_conversion (rethrow_decl),
3171 SET_EXPR_LOCATION (t, cur_try_context->end_finally_locus);
3172 append_to_statement_list (t, &TREE_OPERAND (try_fin, 1));
3177 /* Called just after parsing the @try and its associated BODY. We now
3178 must prepare for the tricky bits -- handling the catches and finally. */
3181 objc_begin_try_stmt (location_t try_locus, tree body)
3183 struct objc_try_context *c = xcalloc (1, sizeof (*c));
3184 c->outer = cur_try_context;
3186 c->try_locus = try_locus;
3187 c->end_try_locus = input_location;
3188 cur_try_context = c;
3190 objc_init_exceptions ();
3193 /* Called just after parsing "@catch (parm)". Open a binding level,
3194 enter DECL into the binding level, and initialize it. Leave the
3195 binding level open while the body of the compound statement is parsed. */
3198 objc_begin_catch_clause (tree decl)
3200 tree compound, type, t;
3202 /* Begin a new scope that the entire catch clause will live in. */
3203 compound = c_begin_compound_stmt (true);
3205 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
3206 decl = build_decl (VAR_DECL, DECL_NAME (decl), TREE_TYPE (decl));
3207 lang_hooks.decls.pushdecl (decl);
3209 /* Since a decl is required here by syntax, don't warn if its unused. */
3210 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3211 be what the previous objc implementation did. */
3212 TREE_USED (decl) = 1;
3214 /* Verify that the type of the catch is valid. It must be a pointer
3215 to an Objective-C class, or "id" (which is catch-all). */
3216 type = TREE_TYPE (decl);
3218 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
3220 else if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
3222 error ("@catch parameter is not a known Objective-C class type");
3223 type = error_mark_node;
3225 else if (cur_try_context->catch_list)
3227 /* Examine previous @catch clauses and see if we've already
3228 caught the type in question. */
3229 tree_stmt_iterator i = tsi_start (cur_try_context->catch_list);
3230 for (; !tsi_end_p (i); tsi_next (&i))
3232 tree stmt = tsi_stmt (i);
3233 t = CATCH_TYPES (stmt);
3234 if (t == error_mark_node)
3236 if (!t || objc_comptypes (TREE_TYPE (t), TREE_TYPE (type), 0) == 1)
3238 warning ("exception of type %<%T%> will be caught",
3240 warning ("%H by earlier handler for %<%T%>",
3241 EXPR_LOCUS (stmt), TREE_TYPE (t ? t : objc_object_type));
3247 /* Record the data for the catch in the try context so that we can
3248 finalize it later. */
3249 t = build_stmt (CATCH_EXPR, type, compound);
3250 cur_try_context->current_catch = t;
3252 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3253 t = objc_build_exc_ptr ();
3254 t = convert (TREE_TYPE (decl), t);
3255 t = build (MODIFY_EXPR, void_type_node, decl, t);
3259 /* Called just after parsing the closing brace of a @catch clause. Close
3260 the open binding level, and record a CATCH_EXPR for it. */
3263 objc_finish_catch_clause (void)
3265 tree c = cur_try_context->current_catch;
3266 cur_try_context->current_catch = NULL;
3267 cur_try_context->end_catch_locus = input_location;
3269 CATCH_BODY (c) = c_end_compound_stmt (CATCH_BODY (c), 1);
3270 append_to_statement_list (c, &cur_try_context->catch_list);
3273 /* Called after parsing a @finally clause and its associated BODY.
3274 Record the body for later placement. */
3277 objc_build_finally_clause (location_t finally_locus, tree body)
3279 cur_try_context->finally_body = body;
3280 cur_try_context->finally_locus = finally_locus;
3281 cur_try_context->end_finally_locus = input_location;
3284 /* Called to finalize a @try construct. */
3287 objc_finish_try_stmt (void)
3289 struct objc_try_context *c = cur_try_context;
3292 if (c->catch_list == NULL && c->finally_body == NULL)
3293 error ("`@try' without `@catch' or `@finally'");
3295 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3296 if (flag_objc_sjlj_exceptions)
3298 if (!cur_try_context->finally_body)
3300 cur_try_context->finally_locus = input_location;
3301 cur_try_context->end_finally_locus = input_location;
3303 stmt = next_sjlj_build_try_catch_finally ();
3307 /* Otherwise, nest the CATCH inside a FINALLY. */
3311 stmt = build_stmt (TRY_CATCH_EXPR, stmt, c->catch_list);
3312 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3314 if (c->finally_body)
3316 stmt = build_stmt (TRY_FINALLY_EXPR, stmt, c->finally_body);
3317 SET_EXPR_LOCATION (stmt, cur_try_context->try_locus);
3322 cur_try_context = c->outer;
3327 objc_build_throw_stmt (tree throw_expr)
3331 objc_init_exceptions ();
3333 if (throw_expr == NULL)
3335 /* If we're not inside a @catch block, there is no "current
3336 exception" to be rethrown. */
3337 if (cur_try_context == NULL
3338 || cur_try_context->current_catch == NULL)
3340 error ("%<@throw%> (rethrow) used outside of a @catch block");
3344 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3345 value that we get from the runtime. */
3346 throw_expr = objc_build_exc_ptr ();
3349 /* A throw is just a call to the runtime throw function with the
3350 object as a parameter. */
3351 args = tree_cons (NULL, throw_expr, NULL);
3352 return add_stmt (build_function_call (objc_exception_throw_decl, args));
3356 objc_build_synchronized (location_t start_locus, tree mutex, tree body)
3360 /* First lock the mutex. */
3361 mutex = save_expr (mutex);
3362 args = tree_cons (NULL, mutex, NULL);
3363 call = build_function_call (objc_sync_enter_decl, args);
3364 SET_EXPR_LOCATION (call, start_locus);
3367 /* Build the mutex unlock. */
3368 args = tree_cons (NULL, mutex, NULL);
3369 call = build_function_call (objc_sync_exit_decl, args);
3370 SET_EXPR_LOCATION (call, input_location);
3372 /* Put the that and the body in a TRY_FINALLY. */
3373 objc_begin_try_stmt (start_locus, body);
3374 objc_build_finally_clause (input_location, call);
3375 objc_finish_try_stmt ();
3379 /* Predefine the following data type:
3381 struct _objc_exception_data
3387 /* The following yuckiness should prevent users from having to #include
3388 <setjmp.h> in their code... */
3390 #ifdef TARGET_POWERPC
3391 /* snarfed from /usr/include/ppc/setjmp.h */
3392 #define _JBLEN (26 + 36 + 129 + 1)
3394 /* snarfed from /usr/include/i386/{setjmp,signal}.h */
3399 build_next_objc_exception_stuff (void)
3401 tree field_decl, field_decl_chain, index, temp_type;
3403 objc_exception_data_template
3404 = start_struct (RECORD_TYPE, get_identifier (UTAG_EXCDATA));
3406 /* int buf[_JBLEN]; */
3408 index = build_index_type (build_int_cst (NULL_TREE, _JBLEN - 1));
3409 field_decl = create_field_decl (build_array_type (integer_type_node, index),
3411 field_decl_chain = field_decl;
3413 /* void *pointers[4]; */
3415 index = build_index_type (build_int_cst (NULL_TREE, 4 - 1));
3416 field_decl = create_field_decl (build_array_type (ptr_type_node, index),
3418 chainon (field_decl_chain, field_decl);
3420 finish_struct (objc_exception_data_template, field_decl_chain, NULL_TREE);
3422 /* int _setjmp(...); */
3423 /* If the user includes <setjmp.h>, this shall be superseded by
3424 'int _setjmp(jmp_buf);' */
3425 temp_type = build_function_type (integer_type_node, NULL_TREE);
3427 = builtin_function (TAG_SETJMP, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3429 /* id objc_exception_extract(struct _objc_exception_data *); */
3431 = build_function_type (objc_object_type,
3432 tree_cons (NULL_TREE,
3433 build_pointer_type (objc_exception_data_template),
3435 objc_exception_extract_decl
3436 = builtin_function (TAG_EXCEPTIONEXTRACT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3437 /* void objc_exception_try_enter(struct _objc_exception_data *); */
3438 /* void objc_exception_try_exit(struct _objc_exception_data *); */
3440 = build_function_type (void_type_node,
3441 tree_cons (NULL_TREE,
3442 build_pointer_type (objc_exception_data_template),
3444 objc_exception_try_enter_decl
3445 = builtin_function (TAG_EXCEPTIONTRYENTER, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3446 objc_exception_try_exit_decl
3447 = builtin_function (TAG_EXCEPTIONTRYEXIT, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3449 /* int objc_exception_match(id, id); */
3451 = build_function_type (integer_type_node,
3452 tree_cons (NULL_TREE, objc_object_type,
3453 tree_cons (NULL_TREE, objc_object_type,
3454 OBJC_VOID_AT_END)));
3455 objc_exception_match_decl
3456 = builtin_function (TAG_EXCEPTIONMATCH, temp_type, 0, NOT_BUILT_IN, NULL, NULL_TREE);
3460 build_objc_exception_stuff (void)
3462 tree noreturn_list, nothrow_list, temp_type;
3464 noreturn_list = tree_cons (get_identifier ("noreturn"), NULL, NULL);
3465 nothrow_list = tree_cons (get_identifier ("nothrow"), NULL, NULL);
3467 /* void objc_exception_throw(id) __attribute__((noreturn)); */
3468 /* void objc_sync_enter(id); */
3469 /* void objc_sync_exit(id); */
3470 temp_type = build_function_type (void_type_node,
3471 tree_cons (NULL_TREE, objc_object_type,
3473 objc_exception_throw_decl
3474 = builtin_function (TAG_EXCEPTIONTHROW, temp_type, 0, NOT_BUILT_IN, NULL,
3476 objc_sync_enter_decl
3477 = builtin_function (TAG_SYNCENTER, temp_type, 0, NOT_BUILT_IN,
3478 NULL, nothrow_list);
3480 = builtin_function (TAG_SYNCEXIT, temp_type, 0, NOT_BUILT_IN,
3481 NULL, nothrow_list);
3485 /* struct <classname> {
3486 struct _objc_class *isa;
3491 build_private_template (tree class)
3495 if (CLASS_STATIC_TEMPLATE (class))
3497 uprivate_record = CLASS_STATIC_TEMPLATE (class);
3498 ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
3502 uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class));
3503 ivar_context = get_class_ivars (class);
3505 finish_struct (uprivate_record, ivar_context, NULL_TREE);
3507 CLASS_STATIC_TEMPLATE (class) = uprivate_record;
3509 /* mark this record as class template - for class type checking */
3510 TREE_STATIC_TEMPLATE (uprivate_record) = 1;
3513 objc_instance_type = build_pointer_type (uprivate_record);
3515 return ivar_context;
3518 /* Begin code generation for protocols... */
3520 /* struct _objc_protocol {
3521 struct _objc_class *isa;
3522 char *protocol_name;
3523 struct _objc_protocol **protocol_list;
3524 struct _objc__method_prototype_list *instance_methods;
3525 struct _objc__method_prototype_list *class_methods;
3529 build_protocol_template (void)
3531 tree field_decl, field_decl_chain;
3533 objc_protocol_template = start_struct (RECORD_TYPE,
3534 get_identifier (UTAG_PROTOCOL));
3536 /* struct _objc_class *isa; */
3537 field_decl = create_field_decl (build_pointer_type
3538 (xref_tag (RECORD_TYPE,
3539 get_identifier (UTAG_CLASS))),
3541 field_decl_chain = field_decl;
3543 /* char *protocol_name; */
3544 field_decl = create_field_decl (string_type_node, "protocol_name");
3545 chainon (field_decl_chain, field_decl);
3547 /* struct _objc_protocol **protocol_list; */
3548 field_decl = create_field_decl (build_pointer_type
3550 (objc_protocol_template)),
3552 chainon (field_decl_chain, field_decl);
3554 /* struct objc_method_list *instance_methods; */
3555 field_decl = create_field_decl (build_pointer_type
3556 (xref_tag (RECORD_TYPE,
3558 (UTAG_METHOD_PROTOTYPE_LIST))),
3559 "instance_methods");
3560 chainon (field_decl_chain, field_decl);
3562 /* struct objc_method_list *class_methods; */
3563 field_decl = create_field_decl (build_pointer_type
3564 (xref_tag (RECORD_TYPE,
3566 (UTAG_METHOD_PROTOTYPE_LIST))),
3568 chainon (field_decl_chain, field_decl);
3570 finish_struct (objc_protocol_template, field_decl_chain, NULL_TREE);
3574 build_descriptor_table_initializer (tree type, tree entries)
3576 tree initlist = NULL_TREE;
3580 tree eltlist = NULL_TREE;
3583 = tree_cons (NULL_TREE,
3584 build_selector (METHOD_SEL_NAME (entries)), NULL_TREE);
3586 = tree_cons (NULL_TREE,
3587 add_objc_string (METHOD_ENCODING (entries),
3592 = tree_cons (NULL_TREE,
3593 objc_build_constructor (type, nreverse (eltlist)),
3596 entries = TREE_CHAIN (entries);
3600 return objc_build_constructor (build_array_type (type, 0),
3601 nreverse (initlist));
3604 /* struct objc_method_prototype_list {
3606 struct objc_method_prototype {
3613 build_method_prototype_list_template (tree list_type, int size)
3615 tree objc_ivar_list_record;
3616 tree field_decl, field_decl_chain;
3618 /* Generate an unnamed struct definition. */
3620 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
3622 /* int method_count; */
3623 field_decl = create_field_decl (integer_type_node, "method_count");
3624 field_decl_chain = field_decl;
3626 /* struct objc_method method_list[]; */
3627 field_decl = create_field_decl (build_array_type
3630 (build_int_cst (NULL_TREE, size - 1))),
3632 chainon (field_decl_chain, field_decl);
3634 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
3636 return objc_ivar_list_record;
3640 build_method_prototype_template (void)
3643 tree field_decl, field_decl_chain;
3646 = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE));
3649 field_decl = create_field_decl (objc_selector_type, "_cmd");
3650 field_decl_chain = field_decl;
3652 /* char *method_types; */
3653 field_decl = create_field_decl (string_type_node, "method_types");
3654 chainon (field_decl_chain, field_decl);
3656 finish_struct (proto_record, field_decl_chain, NULL_TREE);
3658 return proto_record;
3662 objc_method_parm_type (tree type)
3664 type = TREE_VALUE (TREE_TYPE (type));
3665 if (TREE_CODE (type) == TYPE_DECL)
3666 type = TREE_TYPE (type);
3667 return TYPE_MAIN_VARIANT (type);
3671 objc_encoded_type_size (tree type)
3673 int sz = int_size_in_bytes (type);
3675 /* Make all integer and enum types at least as large
3677 if (sz > 0 && INTEGRAL_TYPE_P (type))
3678 sz = MAX (sz, int_size_in_bytes (integer_type_node));
3679 /* Treat arrays as pointers, since that's how they're
3681 else if (TREE_CODE (type) == ARRAY_TYPE)
3682 sz = int_size_in_bytes (ptr_type_node);
3687 encode_method_prototype (tree method_decl)
3694 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
3695 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl)));
3697 /* Encode return type. */
3698 encode_type (objc_method_parm_type (method_decl),
3699 obstack_object_size (&util_obstack),
3700 OBJC_ENCODE_INLINE_DEFS);
3703 /* The first two arguments (self and _cmd) are pointers; account for
3705 i = int_size_in_bytes (ptr_type_node);
3706 parm_offset = 2 * i;
3707 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3708 parms = TREE_CHAIN (parms))
3710 tree type = objc_method_parm_type (parms);
3711 int sz = objc_encoded_type_size (type);
3713 /* If a type size is not known, bail out. */
3716 error ("%Jtype '%D' does not have a known size",
3718 /* Pretend that the encoding succeeded; the compilation will
3719 fail nevertheless. */
3720 goto finish_encoding;
3725 sprintf (buf, "%d@0:%d", parm_offset, i);
3726 obstack_grow (&util_obstack, buf, strlen (buf));
3728 /* Argument types. */
3729 parm_offset = 2 * i;
3730 for (parms = METHOD_SEL_ARGS (method_decl); parms;
3731 parms = TREE_CHAIN (parms))
3733 tree type = objc_method_parm_type (parms);
3735 /* Process argument qualifiers for user supplied arguments. */
3736 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms)));
3739 encode_type (type, obstack_object_size (&util_obstack),
3740 OBJC_ENCODE_INLINE_DEFS);
3742 /* Compute offset. */
3743 sprintf (buf, "%d", parm_offset);
3744 parm_offset += objc_encoded_type_size (type);
3746 obstack_grow (&util_obstack, buf, strlen (buf));
3750 obstack_1grow (&util_obstack, '\0');
3751 result = get_identifier (obstack_finish (&util_obstack));
3752 obstack_free (&util_obstack, util_firstobj);
3757 generate_descriptor_table (tree type, const char *name, int size, tree list,
3760 tree decl, initlist;
3762 decl = start_var_decl (type, synth_id_with_class_suffix (name, proto));
3764 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
3765 initlist = tree_cons (NULL_TREE, list, initlist);
3767 finish_var_decl (decl, objc_build_constructor (type, nreverse (initlist)));
3773 generate_method_descriptors (tree protocol)
3775 tree initlist, chain, method_list_template;
3778 if (!objc_method_prototype_template)
3779 objc_method_prototype_template = build_method_prototype_template ();
3781 chain = PROTOCOL_CLS_METHODS (protocol);
3784 size = list_length (chain);
3786 method_list_template
3787 = build_method_prototype_list_template (objc_method_prototype_template,
3791 = build_descriptor_table_initializer (objc_method_prototype_template,
3794 UOBJC_CLASS_METHODS_decl
3795 = generate_descriptor_table (method_list_template,
3796 "_OBJC_PROTOCOL_CLASS_METHODS",
3797 size, initlist, protocol);
3800 UOBJC_CLASS_METHODS_decl = 0;
3802 chain = PROTOCOL_NST_METHODS (protocol);
3805 size = list_length (chain);
3807 method_list_template
3808 = build_method_prototype_list_template (objc_method_prototype_template,
3811 = build_descriptor_table_initializer (objc_method_prototype_template,
3814 UOBJC_INSTANCE_METHODS_decl
3815 = generate_descriptor_table (method_list_template,
3816 "_OBJC_PROTOCOL_INSTANCE_METHODS",
3817 size, initlist, protocol);
3820 UOBJC_INSTANCE_METHODS_decl = 0;
3824 generate_protocol_references (tree plist)
3828 /* Forward declare protocols referenced. */
3829 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
3831 tree proto = TREE_VALUE (lproto);
3833 if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
3834 && PROTOCOL_NAME (proto))
3836 if (! PROTOCOL_FORWARD_DECL (proto))
3837 build_protocol_reference (proto);
3839 if (PROTOCOL_LIST (proto))
3840 generate_protocol_references (PROTOCOL_LIST (proto));
3845 /* For each protocol which was referenced either from a @protocol()
3846 expression, or because a class/category implements it (then a
3847 pointer to the protocol is stored in the struct describing the
3848 class/category), we create a statically allocated instance of the
3849 Protocol class. The code is written in such a way as to generate
3850 as few Protocol objects as possible; we generate a unique Protocol
3851 instance for each protocol, and we don't generate a Protocol
3852 instance if the protocol is never referenced (either from a
3853 @protocol() or from a class/category implementation). These
3854 statically allocated objects can be referred to via the static
3855 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
3857 The statically allocated Protocol objects that we generate here
3858 need to be fixed up at runtime in order to be used: the 'isa'
3859 pointer of the objects need to be set up to point to the 'Protocol'
3860 class, as known at runtime.
3862 The NeXT runtime fixes up all protocols at program startup time,
3863 before main() is entered. It uses a low-level trick to look up all
3864 those symbols, then loops on them and fixes them up.
3866 The GNU runtime as well fixes up all protocols before user code
3867 from the module is executed; it requires pointers to those symbols
3868 to be put in the objc_symtab (which is then passed as argument to
3869 the function __objc_exec_class() which the compiler sets up to be
3870 executed automatically when the module is loaded); setup of those
3871 Protocol objects happen in two ways in the GNU runtime: all
3872 Protocol objects referred to by a class or category implementation
3873 are fixed up when the class/category is loaded; all Protocol
3874 objects referred to by a @protocol() expression are added by the
3875 compiler to the list of statically allocated instances to fixup
3876 (the same list holding the statically allocated constant string
3877 objects). Because, as explained above, the compiler generates as
3878 few Protocol objects as possible, some Protocol object might end up
3879 being referenced multiple times when compiled with the GNU runtime,
3880 and end up being fixed up multiple times at runtime initialization.
3881 But that doesn't hurt, it's just a little inefficient. */
3884 generate_protocols (void)
3888 tree initlist, protocol_name_expr, refs_decl, refs_expr;
3890 /* If a protocol was directly referenced, pull in indirect references. */
3891 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3892 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
3893 generate_protocol_references (PROTOCOL_LIST (p));
3895 for (p = protocol_chain; p; p = TREE_CHAIN (p))
3897 tree nst_methods = PROTOCOL_NST_METHODS (p);
3898 tree cls_methods = PROTOCOL_CLS_METHODS (p);
3900 /* If protocol wasn't referenced, don't generate any code. */
3901 decl = PROTOCOL_FORWARD_DECL (p);
3906 /* Make sure we link in the Protocol class. */
3907 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
3911 if (! METHOD_ENCODING (nst_methods))
3913 encoding = encode_method_prototype (nst_methods);
3914 METHOD_ENCODING (nst_methods) = encoding;
3916 nst_methods = TREE_CHAIN (nst_methods);
3921 if (! METHOD_ENCODING (cls_methods))
3923 encoding = encode_method_prototype (cls_methods);
3924 METHOD_ENCODING (cls_methods) = encoding;
3927 cls_methods = TREE_CHAIN (cls_methods);
3929 generate_method_descriptors (p);
3931 if (PROTOCOL_LIST (p))
3932 refs_decl = generate_protocol_list (p);
3936 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3937 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
3940 refs_expr = convert (build_pointer_type (build_pointer_type
3941 (objc_protocol_template)),
3942 build_unary_op (ADDR_EXPR, refs_decl, 0));
3944 refs_expr = build_int_cst (NULL_TREE, 0);
3946 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3947 by generate_method_descriptors, which is called above. */
3948 initlist = build_protocol_initializer (TREE_TYPE (decl),
3949 protocol_name_expr, refs_expr,
3950 UOBJC_INSTANCE_METHODS_decl,
3951 UOBJC_CLASS_METHODS_decl);
3952 finish_var_decl (decl, initlist);
3957 build_protocol_initializer (tree type, tree protocol_name,
3958 tree protocol_list, tree instance_methods,
3961 tree initlist = NULL_TREE, expr;
3962 tree cast_type = build_pointer_type
3963 (xref_tag (RECORD_TYPE,
3964 get_identifier (UTAG_CLASS)));
3966 /* Filling the "isa" in with one allows the runtime system to
3967 detect that the version change...should remove before final release. */
3969 expr = build_int_cst (cast_type, PROTOCOL_VERSION);
3970 initlist = tree_cons (NULL_TREE, expr, initlist);
3971 initlist = tree_cons (NULL_TREE, protocol_name, initlist);
3972 initlist = tree_cons (NULL_TREE, protocol_list, initlist);
3974 if (!instance_methods)
3975 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
3978 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
3979 initlist = tree_cons (NULL_TREE, expr, initlist);
3983 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
3986 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
3987 initlist = tree_cons (NULL_TREE, expr, initlist);
3990 return objc_build_constructor (type, nreverse (initlist));
3993 /* struct _objc_category {
3994 char *category_name;
3996 struct _objc_method_list *instance_methods;
3997 struct _objc_method_list *class_methods;
3998 struct _objc_protocol_list *protocols;
4002 build_category_template (void)
4004 tree field_decl, field_decl_chain;
4006 objc_category_template = start_struct (RECORD_TYPE,
4007 get_identifier (UTAG_CATEGORY));
4009 /* char *category_name; */
4010 field_decl = create_field_decl (string_type_node, "category_name");
4011 field_decl_chain = field_decl;
4013 /* char *class_name; */
4014 field_decl = create_field_decl (string_type_node, "class_name");
4015 chainon (field_decl_chain, field_decl);
4017 /* struct _objc_method_list *instance_methods; */
4018 field_decl = create_field_decl (build_pointer_type
4019 (xref_tag (RECORD_TYPE,
4021 (UTAG_METHOD_LIST))),
4022 "instance_methods");
4023 chainon (field_decl_chain, field_decl);
4025 /* struct _objc_method_list *class_methods; */
4026 field_decl = create_field_decl (build_pointer_type
4027 (xref_tag (RECORD_TYPE,
4029 (UTAG_METHOD_LIST))),
4031 chainon (field_decl_chain, field_decl);
4033 /* struct _objc_protocol **protocol_list; */
4034 field_decl = create_field_decl (build_pointer_type
4036 (objc_protocol_template)),
4038 chainon (field_decl_chain, field_decl);
4040 finish_struct (objc_category_template, field_decl_chain, NULL_TREE);
4043 /* struct _objc_selector {
4049 build_selector_template (void)
4052 tree field_decl, field_decl_chain;
4054 objc_selector_template
4055 = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR));
4058 field_decl = create_field_decl (objc_selector_type, "sel_id");
4059 field_decl_chain = field_decl;
4061 /* char *sel_type; */
4062 field_decl = create_field_decl (string_type_node, "sel_type");
4063 chainon (field_decl_chain, field_decl);
4065 finish_struct (objc_selector_template, field_decl_chain, NULL_TREE);
4068 /* struct _objc_class {
4069 struct _objc_class *isa;
4070 struct _objc_class *super_class;
4075 struct _objc_ivar_list *ivars;
4076 struct _objc_method_list *methods;
4077 #ifdef __NEXT_RUNTIME__
4078 struct objc_cache *cache;
4080 struct sarray *dtable;
4081 struct _objc_class *subclass_list;
4082 struct _objc_class *sibling_class;
4084 struct _objc_protocol_list *protocols;
4085 #ifdef __NEXT_RUNTIME__
4088 void *gc_object_type;
4091 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4092 the NeXT/Apple runtime; still, the compiler must generate them to
4093 maintain backward binary compatibility (and to allow for future
4097 build_class_template (void)
4099 tree field_decl, field_decl_chain;
4102 = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS));
4104 /* struct _objc_class *isa; */
4105 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4107 field_decl_chain = field_decl;
4109 /* struct _objc_class *super_class; */
4110 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4112 chainon (field_decl_chain, field_decl);
4115 field_decl = create_field_decl (string_type_node, "name");
4116 chainon (field_decl_chain, field_decl);
4119 field_decl = create_field_decl (long_integer_type_node, "version");
4120 chainon (field_decl_chain, field_decl);
4123 field_decl = create_field_decl (long_integer_type_node, "info");
4124 chainon (field_decl_chain, field_decl);
4126 /* long instance_size; */
4127 field_decl = create_field_decl (long_integer_type_node, "instance_size");
4128 chainon (field_decl_chain, field_decl);
4130 /* struct _objc_ivar_list *ivars; */
4131 field_decl = create_field_decl (build_pointer_type
4132 (xref_tag (RECORD_TYPE,
4136 chainon (field_decl_chain, field_decl);
4138 /* struct _objc_method_list *methods; */
4139 field_decl = create_field_decl (build_pointer_type
4140 (xref_tag (RECORD_TYPE,
4142 (UTAG_METHOD_LIST))),
4144 chainon (field_decl_chain, field_decl);
4146 if (flag_next_runtime)
4148 /* struct objc_cache *cache; */
4149 field_decl = create_field_decl (build_pointer_type
4150 (xref_tag (RECORD_TYPE,
4154 chainon (field_decl_chain, field_decl);
4158 /* struct sarray *dtable; */
4159 field_decl = create_field_decl (build_pointer_type
4160 (xref_tag (RECORD_TYPE,
4164 chainon (field_decl_chain, field_decl);
4166 /* struct objc_class *subclass_list; */
4167 field_decl = create_field_decl (build_pointer_type
4168 (objc_class_template),
4170 chainon (field_decl_chain, field_decl);
4172 /* struct objc_class *sibling_class; */
4173 field_decl = create_field_decl (build_pointer_type
4174 (objc_class_template),
4176 chainon (field_decl_chain, field_decl);
4179 /* struct _objc_protocol **protocol_list; */
4180 field_decl = create_field_decl (build_pointer_type
4182 (xref_tag (RECORD_TYPE,
4186 chainon (field_decl_chain, field_decl);
4188 if (flag_next_runtime)
4191 field_decl = create_field_decl (build_pointer_type (void_type_node),
4193 chainon (field_decl_chain, field_decl);
4196 /* void *gc_object_type; */
4197 field_decl = create_field_decl (build_pointer_type (void_type_node),
4199 chainon (field_decl_chain, field_decl);
4201 finish_struct (objc_class_template, field_decl_chain, NULL_TREE);
4204 /* Generate appropriate forward declarations for an implementation. */
4207 synth_forward_declarations (void)
4211 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4212 UOBJC_CLASS_decl = build_metadata_decl ("_OBJC_CLASS",
4213 objc_class_template);
4215 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4216 UOBJC_METACLASS_decl = build_metadata_decl ("_OBJC_METACLASS",
4217 objc_class_template);
4219 /* Pre-build the following entities - for speed/convenience. */
4221 an_id = get_identifier ("super_class");
4222 ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id);
4223 uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id);
4227 error_with_ivar (const char *message, tree decl)
4229 error ("%J%s `%s'", decl,
4230 message, gen_declaration (decl));
4235 check_ivars (tree inter, tree imp)
4237 tree intdecls = CLASS_RAW_IVARS (inter);
4238 tree impdecls = CLASS_RAW_IVARS (imp);
4245 if (intdecls && TREE_CODE (intdecls) == TYPE_DECL)
4246 intdecls = TREE_CHAIN (intdecls);
4248 if (intdecls == 0 && impdecls == 0)
4250 if (intdecls == 0 || impdecls == 0)
4252 error ("inconsistent instance variable specification");
4256 t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls);
4258 if (!comptypes (t1, t2)
4259 || !tree_int_cst_equal (DECL_INITIAL (intdecls),
4260 DECL_INITIAL (impdecls)))
4262 if (DECL_NAME (intdecls) == DECL_NAME (impdecls))
4264 error_with_ivar ("conflicting instance variable type",
4266 error_with_ivar ("previous declaration of",
4269 else /* both the type and the name don't match */
4271 error ("inconsistent instance variable specification");
4276 else if (DECL_NAME (intdecls) != DECL_NAME (impdecls))
4278 error_with_ivar ("conflicting instance variable name",
4280 error_with_ivar ("previous declaration of",
4284 intdecls = TREE_CHAIN (intdecls);
4285 impdecls = TREE_CHAIN (impdecls);
4289 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
4290 This needs to be done just once per compilation. */
4292 /* struct _objc_super {
4293 struct _objc_object *self;
4294 struct _objc_class *super_class;
4298 build_super_template (void)
4300 tree field_decl, field_decl_chain;
4302 objc_super_template = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER));
4304 /* struct _objc_object *self; */
4305 field_decl = create_field_decl (objc_object_type, "self");
4306 field_decl_chain = field_decl;
4308 /* struct _objc_class *super_class; */
4309 field_decl = create_field_decl (build_pointer_type (objc_class_template),
4311 chainon (field_decl_chain, field_decl);
4313 finish_struct (objc_super_template, field_decl_chain, NULL_TREE);
4316 /* struct _objc_ivar {
4323 build_ivar_template (void)
4325 tree objc_ivar_id, objc_ivar_record;
4326 tree field_decl, field_decl_chain;
4328 objc_ivar_id = get_identifier (UTAG_IVAR);
4329 objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id);
4331 /* char *ivar_name; */
4332 field_decl = create_field_decl (string_type_node, "ivar_name");
4333 field_decl_chain = field_decl;
4335 /* char *ivar_type; */
4336 field_decl = create_field_decl (string_type_node, "ivar_type");
4337 chainon (field_decl_chain, field_decl);
4339 /* int ivar_offset; */
4340 field_decl = create_field_decl (integer_type_node, "ivar_offset");
4341 chainon (field_decl_chain, field_decl);
4343 finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE);
4345 return objc_ivar_record;
4350 struct objc_ivar ivar_list[ivar_count];
4354 build_ivar_list_template (tree list_type, int size)
4356 tree objc_ivar_list_record;
4357 tree field_decl, field_decl_chain;
4359 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4361 /* int ivar_count; */
4362 field_decl = create_field_decl (integer_type_node, "ivar_count");
4363 field_decl_chain = field_decl;
4365 /* struct objc_ivar ivar_list[]; */
4366 field_decl = create_field_decl (build_array_type
4369 (build_int_cst (NULL_TREE, size - 1))),
4371 chainon (field_decl_chain, field_decl);
4373 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4375 return objc_ivar_list_record;
4379 struct _objc__method_prototype_list *method_next;
4381 struct objc_method method_list[method_count];
4385 build_method_list_template (tree list_type, int size)
4387 tree objc_ivar_list_record;
4388 tree field_decl, field_decl_chain;
4390 objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE);
4392 /* struct _objc__method_prototype_list *method_next; */
4393 field_decl = create_field_decl (build_pointer_type
4394 (xref_tag (RECORD_TYPE,
4396 (UTAG_METHOD_PROTOTYPE_LIST))),
4398 field_decl_chain = field_decl;
4400 /* int method_count; */
4401 field_decl = create_field_decl (integer_type_node, "method_count");
4402 chainon (field_decl_chain, field_decl);
4404 /* struct objc_method method_list[]; */
4405 field_decl = create_field_decl (build_array_type
4408 (build_int_cst (NULL_TREE, size - 1))),
4410 chainon (field_decl_chain, field_decl);
4412 finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE);
4414 return objc_ivar_list_record;
4418 build_ivar_list_initializer (tree type, tree field_decl)
4420 tree initlist = NULL_TREE;
4424 tree ivar = NULL_TREE;
4427 if (DECL_NAME (field_decl))
4428 ivar = tree_cons (NULL_TREE,
4429 add_objc_string (DECL_NAME (field_decl),
4433 /* Unnamed bit-field ivar (yuck). */
4434 ivar = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), ivar);
4437 encode_field_decl (field_decl,
4438 obstack_object_size (&util_obstack),
4439 OBJC_ENCODE_DONT_INLINE_DEFS);
4441 /* Null terminate string. */
4442 obstack_1grow (&util_obstack, 0);
4446 add_objc_string (get_identifier (obstack_finish (&util_obstack)),
4449 obstack_free (&util_obstack, util_firstobj);
4452 ivar = tree_cons (NULL_TREE, byte_position (field_decl), ivar);
4453 initlist = tree_cons (NULL_TREE,
4454 objc_build_constructor (type, nreverse (ivar)),
4457 field_decl = TREE_CHAIN (field_decl);
4458 while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
4462 return objc_build_constructor (build_array_type (type, 0),
4463 nreverse (initlist));
4467 generate_ivars_list (tree type, const char *name, int size, tree list)
4469 tree decl, initlist;
4471 decl = start_var_decl (type, synth_id_with_class_suffix
4472 (name, objc_implementation_context));
4474 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, size));
4475 initlist = tree_cons (NULL_TREE, list, initlist);
4477 finish_var_decl (decl,
4478 objc_build_constructor (TREE_TYPE (decl),
4479 nreverse (initlist)));
4484 /* Count only the fields occurring in T. */
4486 ivar_list_length (tree t)
4490 for (; t; t = TREE_CHAIN (t))
4491 if (TREE_CODE (t) == FIELD_DECL)
4498 generate_ivar_lists (void)
4500 tree initlist, ivar_list_template, chain;
4503 generating_instance_variables = 1;
4505 if (!objc_ivar_template)
4506 objc_ivar_template = build_ivar_template ();
4508 /* Only generate class variables for the root of the inheritance
4509 hierarchy since these will be the same for every class. */
4511 if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE
4512 && (chain = TYPE_FIELDS (objc_class_template)))
4514 size = ivar_list_length (chain);
4516 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
4517 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
4519 UOBJC_CLASS_VARIABLES_decl
4520 = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES",
4524 UOBJC_CLASS_VARIABLES_decl = 0;
4526 chain = CLASS_IVARS (implementation_template);
4529 size = ivar_list_length (chain);
4530 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
4531 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
4533 UOBJC_INSTANCE_VARIABLES_decl
4534 = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES",
4538 UOBJC_INSTANCE_VARIABLES_decl = 0;
4540 generating_instance_variables = 0;
4544 build_dispatch_table_initializer (tree type, tree entries)
4546 tree initlist = NULL_TREE;
4550 tree elemlist = NULL_TREE;
4552 elemlist = tree_cons (NULL_TREE,
4553 build_selector (METHOD_SEL_NAME (entries)),
4556 /* Generate the method encoding if we don't have one already. */
4557 if (! METHOD_ENCODING (entries))
4558 METHOD_ENCODING (entries) =
4559 encode_method_prototype (entries);
4561 elemlist = tree_cons (NULL_TREE,
4562 add_objc_string (METHOD_ENCODING (entries),
4567 = tree_cons (NULL_TREE,
4568 convert (ptr_type_node,
4569 build_unary_op (ADDR_EXPR,
4570 METHOD_DEFINITION (entries), 1)),
4573 initlist = tree_cons (NULL_TREE,
4574 objc_build_constructor (type, nreverse (elemlist)),
4577 entries = TREE_CHAIN (entries);
4581 return objc_build_constructor (build_array_type (type, 0),
4582 nreverse (initlist));
4585 /* To accomplish method prototyping without generating all kinds of
4586 inane warnings, the definition of the dispatch table entries were
4589 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
4591 struct objc_method { SEL _cmd; ...; void *_imp; }; */
4594 build_method_template (void)
4597 tree field_decl, field_decl_chain;
4599 _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD));
4602 field_decl = create_field_decl (objc_selector_type, "_cmd");
4603 field_decl_chain = field_decl;
4605 /* char *method_types; */
4606 field_decl = create_field_decl (string_type_node, "method_types");
4607 chainon (field_decl_chain, field_decl);
4610 field_decl = create_field_decl (build_pointer_type (void_type_node),
4612 chainon (field_decl_chain, field_decl);
4614 finish_struct (_SLT_record, field_decl_chain, NULL_TREE);
4621 generate_dispatch_table (tree type, const char *name, int size, tree list)
4623 tree decl, initlist;
4625 decl = start_var_decl (type, synth_id_with_class_suffix
4626 (name, objc_implementation_context));
4628 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
4629 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, size), initlist);
4630 initlist = tree_cons (NULL_TREE, list, initlist);
4632 finish_var_decl (decl,
4633 objc_build_constructor (TREE_TYPE (decl),
4634 nreverse (initlist)));
4640 mark_referenced_methods (void)
4642 struct imp_entry *impent;
4645 for (impent = imp_list; impent; impent = impent->next)
4647 chain = CLASS_CLS_METHODS (impent->imp_context);
4650 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
4651 chain = TREE_CHAIN (chain);
4654 chain = CLASS_NST_METHODS (impent->imp_context);
4657 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain)));
4658 chain = TREE_CHAIN (chain);
4664 generate_dispatch_tables (void)
4666 tree initlist, chain, method_list_template;
4669 if (!objc_method_template)
4670 objc_method_template = build_method_template ();
4672 chain = CLASS_CLS_METHODS (objc_implementation_context);
4675 size = list_length (chain);
4677 method_list_template
4678 = build_method_list_template (objc_method_template, size);
4680 = build_dispatch_table_initializer (objc_method_template, chain);
4682 UOBJC_CLASS_METHODS_decl
4683 = generate_dispatch_table (method_list_template,
4684 ((TREE_CODE (objc_implementation_context)
4685 == CLASS_IMPLEMENTATION_TYPE)
4686 ? "_OBJC_CLASS_METHODS"
4687 : "_OBJC_CATEGORY_CLASS_METHODS"),
4691 UOBJC_CLASS_METHODS_decl = 0;
4693 chain = CLASS_NST_METHODS (objc_implementation_context);
4696 size = list_length (chain);
4698 method_list_template
4699 = build_method_list_template (objc_method_template, size);
4701 = build_dispatch_table_initializer (objc_method_template, chain);
4703 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
4704 UOBJC_INSTANCE_METHODS_decl
4705 = generate_dispatch_table (method_list_template,
4706 "_OBJC_INSTANCE_METHODS",
4709 /* We have a category. */
4710 UOBJC_INSTANCE_METHODS_decl
4711 = generate_dispatch_table (method_list_template,
4712 "_OBJC_CATEGORY_INSTANCE_METHODS",
4716 UOBJC_INSTANCE_METHODS_decl = 0;
4720 generate_protocol_list (tree i_or_p)
4723 tree refs_decl, lproto, e, plist;
4725 const char *ref_name;
4727 if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE
4728 || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4729 plist = CLASS_PROTOCOL_LIST (i_or_p);
4730 else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4731 plist = PROTOCOL_LIST (i_or_p);
4736 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4737 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
4738 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
4741 /* Build initializer. */
4742 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), NULL_TREE);
4743 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
4744 initlist = tree_cons (NULL_TREE, e, initlist);
4746 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
4748 tree pval = TREE_VALUE (lproto);
4750 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
4751 && PROTOCOL_FORWARD_DECL (pval))
4753 e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0);
4754 initlist = tree_cons (NULL_TREE, e, initlist);
4758 /* static struct objc_protocol *refs[n]; */
4760 if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE)
4761 ref_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p);
4762 else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE)
4763 ref_name = synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p);
4764 else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE)
4765 ref_name = synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p);
4769 refs_decl = start_var_decl
4771 (build_pointer_type (objc_protocol_template),
4772 build_index_type (build_int_cst (NULL_TREE, size + 2))),
4775 finish_var_decl (refs_decl, objc_build_constructor (TREE_TYPE (refs_decl),
4776 nreverse (initlist)));
4782 build_category_initializer (tree type, tree cat_name, tree class_name,
4783 tree instance_methods, tree class_methods,
4786 tree initlist = NULL_TREE, expr;
4788 initlist = tree_cons (NULL_TREE, cat_name, initlist);
4789 initlist = tree_cons (NULL_TREE, class_name, initlist);
4791 if (!instance_methods)
4792 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4795 expr = build_unary_op (ADDR_EXPR, instance_methods, 0);
4796 initlist = tree_cons (NULL_TREE, expr, initlist);
4799 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4802 expr = build_unary_op (ADDR_EXPR, class_methods, 0);
4803 initlist = tree_cons (NULL_TREE, expr, initlist);
4806 /* protocol_list = */
4808 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4811 expr = convert (build_pointer_type
4813 (objc_protocol_template)),
4814 build_unary_op (ADDR_EXPR, protocol_list, 0));
4815 initlist = tree_cons (NULL_TREE, expr, initlist);
4818 return objc_build_constructor (type, nreverse (initlist));
4821 /* struct _objc_class {
4822 struct objc_class *isa;
4823 struct objc_class *super_class;
4828 struct objc_ivar_list *ivars;
4829 struct objc_method_list *methods;
4830 if (flag_next_runtime)
4831 struct objc_cache *cache;
4833 struct sarray *dtable;
4834 struct objc_class *subclass_list;
4835 struct objc_class *sibling_class;
4837 struct objc_protocol_list *protocols;
4838 if (flag_next_runtime)
4840 void *gc_object_type;
4844 build_shared_structure_initializer (tree type, tree isa, tree super,
4845 tree name, tree size, int status,
4846 tree dispatch_table, tree ivar_list,
4849 tree initlist = NULL_TREE, expr;
4852 initlist = tree_cons (NULL_TREE, isa, initlist);
4855 initlist = tree_cons (NULL_TREE, super, initlist);
4858 initlist = tree_cons (NULL_TREE, default_conversion (name), initlist);
4861 initlist = tree_cons (NULL_TREE, build_int_cst (long_integer_type_node, 0),
4865 initlist = tree_cons (NULL_TREE,
4866 build_int_cst (long_integer_type_node, status),
4869 /* instance_size = */
4870 initlist = tree_cons (NULL_TREE, convert (long_integer_type_node, size),
4873 /* objc_ivar_list = */
4875 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4878 expr = build_unary_op (ADDR_EXPR, ivar_list, 0);
4879 initlist = tree_cons (NULL_TREE, expr, initlist);
4882 /* objc_method_list = */
4883 if (!dispatch_table)
4884 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4887 expr = build_unary_op (ADDR_EXPR, dispatch_table, 0);
4888 initlist = tree_cons (NULL_TREE, expr, initlist);
4891 if (flag_next_runtime)
4892 /* method_cache = */
4893 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4897 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4899 /* subclass_list = */
4900 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4902 /* sibling_class = */
4903 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4906 /* protocol_list = */
4907 if (! protocol_list)
4908 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4911 expr = convert (build_pointer_type
4913 (objc_protocol_template)),
4914 build_unary_op (ADDR_EXPR, protocol_list, 0));
4915 initlist = tree_cons (NULL_TREE, expr, initlist);
4918 if (flag_next_runtime)
4920 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4922 /* gc_object_type = NULL */
4923 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 0), initlist);
4925 return objc_build_constructor (type, nreverse (initlist));
4928 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
4931 lookup_category (tree class, tree cat_name)
4933 tree category = CLASS_CATEGORY_LIST (class);
4935 while (category && CLASS_SUPER_NAME (category) != cat_name)
4936 category = CLASS_CATEGORY_LIST (category);
4940 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4943 generate_category (tree cat)
4946 tree initlist, cat_name_expr, class_name_expr;
4947 tree protocol_decl, category;
4949 add_class_reference (CLASS_NAME (cat));
4950 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
4952 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
4954 category = lookup_category (implementation_template,
4955 CLASS_SUPER_NAME (cat));
4957 if (category && CLASS_PROTOCOL_LIST (category))
4959 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
4960 protocol_decl = generate_protocol_list (category);
4965 decl = start_var_decl (objc_category_template,
4966 synth_id_with_class_suffix
4967 ("_OBJC_CATEGORY", objc_implementation_context));
4969 initlist = build_category_initializer (TREE_TYPE (decl),
4970 cat_name_expr, class_name_expr,
4971 UOBJC_INSTANCE_METHODS_decl,
4972 UOBJC_CLASS_METHODS_decl,
4975 finish_var_decl (decl, initlist);
4978 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4979 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4982 generate_shared_structures (void)
4984 tree sc_spec, decl_specs, decl;
4985 tree name_expr, super_expr, root_expr;
4986 tree my_root_id = NULL_TREE, my_super_id = NULL_TREE;
4987 tree cast_type, initlist, protocol_decl;
4989 my_super_id = CLASS_SUPER_NAME (implementation_template);
4992 add_class_reference (my_super_id);
4994 /* Compute "my_root_id" - this is required for code generation.
4995 the "isa" for all meta class structures points to the root of
4996 the inheritance hierarchy (e.g. "__Object")... */
4997 my_root_id = my_super_id;
5000 tree my_root_int = lookup_interface (my_root_id);
5002 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
5003 my_root_id = CLASS_SUPER_NAME (my_root_int);
5010 /* No super class. */
5011 my_root_id = CLASS_NAME (implementation_template);
5013 cast_type = build_pointer_type (objc_class_template);
5014 name_expr = add_objc_string (CLASS_NAME (implementation_template),
5017 /* Install class `isa' and `super' pointers at runtime. */
5020 super_expr = add_objc_string (my_super_id, class_names);
5021 super_expr = build_c_cast (cast_type, super_expr); /* cast! */
5024 super_expr = build_int_cst (NULL_TREE, 0);
5026 root_expr = add_objc_string (my_root_id, class_names);
5027 root_expr = build_c_cast (cast_type, root_expr); /* cast! */
5029 if (CLASS_PROTOCOL_LIST (implementation_template))
5031 generate_protocol_references
5032 (CLASS_PROTOCOL_LIST (implementation_template));
5033 protocol_decl = generate_protocol_list (implementation_template);
5038 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5040 sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]);
5041 decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec);
5043 decl = start_var_decl (objc_class_template,
5045 (DECL_NAME (UOBJC_METACLASS_decl)));
5048 = build_shared_structure_initializer
5050 root_expr, super_expr, name_expr,
5051 convert (integer_type_node, TYPE_SIZE_UNIT (objc_class_template)),
5053 UOBJC_CLASS_METHODS_decl,
5054 UOBJC_CLASS_VARIABLES_decl,
5057 finish_var_decl (decl, initlist);
5059 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5061 decl = start_var_decl (objc_class_template,
5063 (DECL_NAME (UOBJC_CLASS_decl)));
5066 = build_shared_structure_initializer
5068 build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0),
5069 super_expr, name_expr,
5070 convert (integer_type_node,
5071 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5072 (implementation_template))),
5074 UOBJC_INSTANCE_METHODS_decl,
5075 UOBJC_INSTANCE_VARIABLES_decl,
5078 finish_var_decl (decl, initlist);
5083 synth_id_with_class_suffix (const char *preamble, tree ctxt)
5085 static char string[BUFSIZE];
5087 if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE
5088 || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE)
5090 sprintf (string, "%s_%s", preamble,
5091 IDENTIFIER_POINTER (CLASS_NAME (ctxt)));
5093 else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE
5094 || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE)
5096 /* We have a category. */
5097 const char *const class_name
5098 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
5099 const char *const class_super_name
5100 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context));
5101 sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name);
5103 else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE)
5105 const char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt));
5106 sprintf (string, "%s_%s", preamble, protocol_name);
5114 /* If type is empty or only type qualifiers are present, add default
5115 type of id (otherwise grokdeclarator will default to int). */
5118 adjust_type_for_id_default (tree type)
5121 type = make_node (TREE_LIST);
5123 if (!TREE_VALUE (type))
5124 TREE_VALUE (type) = objc_object_type;
5125 else if (TREE_CODE (TREE_VALUE (type)) == RECORD_TYPE
5126 && TYPED_OBJECT (TREE_VALUE (type)))
5127 error ("can not use an object as parameter to a method");
5134 selector ':' '(' typename ')' identifier
5137 Transform an Objective-C keyword argument into
5138 the C equivalent parameter declarator.
5140 In: key_name, an "identifier_node" (optional).
5141 arg_type, a "tree_list" (optional).
5142 arg_name, an "identifier_node".
5144 Note: It would be really nice to strongly type the preceding
5145 arguments in the function prototype; however, then I
5146 could not use the "accessor" macros defined in "tree.h".
5148 Out: an instance of "keyword_decl". */
5151 objc_build_keyword_decl (tree key_name, tree arg_type, tree arg_name)
5155 /* If no type is specified, default to "id". */
5156 arg_type = adjust_type_for_id_default (arg_type);
5158 keyword_decl = make_node (KEYWORD_DECL);
5160 TREE_TYPE (keyword_decl) = arg_type;
5161 KEYWORD_ARG_NAME (keyword_decl) = arg_name;
5162 KEYWORD_KEY_NAME (keyword_decl) = key_name;
5164 return keyword_decl;
5167 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5170 build_keyword_selector (tree selector)
5173 tree key_chain, key_name;
5176 /* Scan the selector to see how much space we'll need. */
5177 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5179 if (TREE_CODE (selector) == KEYWORD_DECL)
5180 key_name = KEYWORD_KEY_NAME (key_chain);
5181 else if (TREE_CODE (selector) == TREE_LIST)
5182 key_name = TREE_PURPOSE (key_chain);
5187 len += IDENTIFIER_LENGTH (key_name) + 1;
5189 /* Just a ':' arg. */
5193 buf = (char *) alloca (len + 1);
5194 /* Start the buffer out as an empty string. */
5197 for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain))
5199 if (TREE_CODE (selector) == KEYWORD_DECL)
5200 key_name = KEYWORD_KEY_NAME (key_chain);
5201 else if (TREE_CODE (selector) == TREE_LIST)
5203 key_name = TREE_PURPOSE (key_chain);
5204 /* The keyword decl chain will later be used as a function argument
5205 chain. Unhook the selector itself so as to not confuse other
5206 parts of the compiler. */
5207 TREE_PURPOSE (key_chain) = NULL_TREE;
5213 strcat (buf, IDENTIFIER_POINTER (key_name));
5217 return get_identifier (buf);
5220 /* Used for declarations and definitions. */
5223 build_method_decl (enum tree_code code, tree ret_type, tree selector,
5228 /* If no type is specified, default to "id". */
5229 ret_type = adjust_type_for_id_default (ret_type);
5231 method_decl = make_node (code);
5232 TREE_TYPE (method_decl) = ret_type;
5234 /* If we have a keyword selector, create an identifier_node that
5235 represents the full selector name (`:' included)... */
5236 if (TREE_CODE (selector) == KEYWORD_DECL)
5238 METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector);
5239 METHOD_SEL_ARGS (method_decl) = selector;
5240 METHOD_ADD_ARGS (method_decl) = add_args;
5244 METHOD_SEL_NAME (method_decl) = selector;
5245 METHOD_SEL_ARGS (method_decl) = NULL_TREE;
5246 METHOD_ADD_ARGS (method_decl) = NULL_TREE;
5252 #define METHOD_DEF 0
5253 #define METHOD_REF 1
5255 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5256 an argument list for method METH. CONTEXT is either METHOD_DEF or
5257 METHOD_REF, saying whether we are trying to define a method or call
5258 one. SUPERFLAG says this is for a send to super; this makes a
5259 difference for the NeXT calling sequence in which the lookup and
5260 the method call are done together. If METH is null, user-defined
5261 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5264 get_arg_type_list (tree meth, int context, int superflag)
5268 /* Receiver type. */
5269 if (flag_next_runtime && superflag)
5270 arglist = build_tree_list (NULL_TREE, objc_super_type);
5271 else if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5272 arglist = build_tree_list (NULL_TREE, objc_instance_type);
5274 arglist = build_tree_list (NULL_TREE, objc_object_type);
5276 /* Selector type - will eventually change to `int'. */
5277 chainon (arglist, build_tree_list (NULL_TREE, objc_selector_type));
5279 /* No actual method prototype given -- assume that remaining arguments
5284 /* Build a list of argument types. */
5285 for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey))
5287 tree arg_type = TREE_VALUE (TREE_TYPE (akey));
5289 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
5292 if (METHOD_ADD_ARGS (meth))
5294 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (meth));
5295 akey; akey = TREE_CHAIN (akey))
5297 tree arg_type = TREE_TYPE (TREE_VALUE (akey));
5299 chainon (arglist, build_tree_list (NULL_TREE, arg_type));
5302 if (!TREE_OVERFLOW (METHOD_ADD_ARGS (meth)))
5303 goto lack_of_ellipsis;
5308 chainon (arglist, OBJC_VOID_AT_END);
5315 check_duplicates (hash hsh, int methods, int is_class)
5317 tree meth = NULL_TREE;
5325 /* We have two or more methods with the same name but
5329 warning ("multiple %s named `%c%s' found",
5330 methods ? "methods" : "selectors",
5331 (is_class ? '+' : '-'),
5332 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth)));
5334 warn_with_method (methods ? "using" : "found",
5335 ((TREE_CODE (meth) == INSTANCE_METHOD_DECL)
5339 for (loop = hsh->list; loop; loop = loop->next)
5340 warn_with_method ("also found",
5341 ((TREE_CODE (loop->value) == INSTANCE_METHOD_DECL)
5350 /* If RECEIVER is a class reference, return the identifier node for
5351 the referenced class. RECEIVER is created by objc_get_class_reference,
5352 so we check the exact form created depending on which runtimes are
5356 receiver_is_class_object (tree receiver, int self, int super)
5358 tree chain, exp, arg;
5360 /* The receiver is 'self' or 'super' in the context of a class method. */
5361 if (objc_method_context
5362 && TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
5365 ? CLASS_SUPER_NAME (implementation_template)
5366 : CLASS_NAME (implementation_template));
5368 if (flag_next_runtime)
5370 /* The receiver is a variable created by
5371 build_class_reference_decl. */
5372 if (TREE_CODE (receiver) == VAR_DECL && IS_CLASS (TREE_TYPE (receiver)))
5373 /* Look up the identifier. */
5374 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
5375 if (TREE_PURPOSE (chain) == receiver)
5376 return TREE_VALUE (chain);
5379 /* The receiver is a function call that returns an id. Check if
5380 it is a call to objc_getClass, if so, pick up the class name. */
5381 if (TREE_CODE (receiver) == CALL_EXPR
5382 && (exp = TREE_OPERAND (receiver, 0))
5383 && TREE_CODE (exp) == ADDR_EXPR
5384 && (exp = TREE_OPERAND (exp, 0))
5385 && TREE_CODE (exp) == FUNCTION_DECL
5386 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
5387 prototypes for objc_get_class(). Thankfully, they seem to share the
5388 same function type. */
5389 && TREE_TYPE (exp) == TREE_TYPE (objc_get_class_decl)
5390 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp)), TAG_GETCLASS)
5391 /* We have a call to objc_get_class/objc_getClass! */
5392 && (arg = TREE_OPERAND (receiver, 1))
5393 && TREE_CODE (arg) == TREE_LIST
5394 && (arg = TREE_VALUE (arg)))
5397 if (TREE_CODE (arg) == ADDR_EXPR
5398 && (arg = TREE_OPERAND (arg, 0))
5399 && TREE_CODE (arg) == STRING_CST)
5400 /* Finally, we have the class name. */
5401 return get_identifier (TREE_STRING_POINTER (arg));
5406 /* If we are currently building a message expr, this holds
5407 the identifier of the selector of the message. This is
5408 used when printing warnings about argument mismatches. */
5410 static tree current_objc_message_selector = 0;
5413 objc_message_selector (void)
5415 return current_objc_message_selector;
5418 /* Construct an expression for sending a message.
5419 MESS has the object to send to in TREE_PURPOSE
5420 and the argument list (including selector) in TREE_VALUE.
5422 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
5423 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
5426 objc_build_message_expr (tree mess)
5428 tree receiver = TREE_PURPOSE (mess);
5431 tree args = TREE_PURPOSE (TREE_VALUE (mess));
5433 tree args = TREE_VALUE (mess);
5435 tree method_params = NULL_TREE;
5437 if (TREE_CODE (receiver) == ERROR_MARK)
5438 return error_mark_node;
5440 /* Obtain the full selector name. */
5441 if (TREE_CODE (args) == IDENTIFIER_NODE)
5442 /* A unary selector. */
5444 else if (TREE_CODE (args) == TREE_LIST)
5445 sel_name = build_keyword_selector (args);
5449 /* Build the parameter list to give to the method. */
5450 if (TREE_CODE (args) == TREE_LIST)
5452 method_params = chainon (args, TREE_VALUE (TREE_VALUE (mess)));
5455 tree chain = args, prev = NULL_TREE;
5457 /* We have a keyword selector--check for comma expressions. */
5460 tree element = TREE_VALUE (chain);
5462 /* We have a comma expression, must collapse... */
5463 if (TREE_CODE (element) == TREE_LIST)
5466 TREE_CHAIN (prev) = element;
5471 chain = TREE_CHAIN (chain);
5473 method_params = args;
5478 if (processing_template_decl)
5479 /* Must wait until template instantiation time. */
5480 return build_min_nt (MESSAGE_SEND_EXPR, receiver, sel_name,
5484 return objc_finish_message_expr (receiver, sel_name, method_params);
5487 /* Look up method SEL_NAME that would be suitable for receiver
5488 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
5489 nonzero), and report on any duplicates. */
5492 lookup_method_in_hash_lists (tree sel_name, int is_class)
5494 hash method_prototype = NULL;
5497 method_prototype = hash_lookup (nst_method_hash_list,
5500 if (!method_prototype)
5502 method_prototype = hash_lookup (cls_method_hash_list,
5507 return check_duplicates (method_prototype, 1, is_class);
5510 /* The 'objc_finish_message_expr' routine is called from within
5511 'objc_build_message_expr' for non-template functions. In the case of
5512 C++ template functions, it is called from 'build_expr_from_tree'
5513 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
5516 objc_finish_message_expr (tree receiver, tree sel_name, tree method_params)
5518 tree method_prototype = NULL_TREE, rprotos = NULL_TREE, rtype;
5519 tree selector, retval, class_tree;
5520 int self, super, have_cast;
5522 /* Extract the receiver of the message, as well as its type
5523 (where the latter may take the form of a cast or be inferred
5524 from the implementation context). */
5526 while (TREE_CODE (rtype) == COMPOUND_EXPR
5527 || TREE_CODE (rtype) == MODIFY_EXPR
5528 || TREE_CODE (rtype) == NOP_EXPR
5529 || TREE_CODE (rtype) == CONVERT_EXPR
5530 || TREE_CODE (rtype) == COMPONENT_REF)
5531 rtype = TREE_OPERAND (rtype, 0);
5532 self = (rtype == self_decl);
5533 super = (rtype == UOBJC_SUPER_decl);
5534 rtype = TREE_TYPE (receiver);
5535 have_cast = (TREE_CODE (receiver) == NOP_EXPR
5536 || (TREE_CODE (receiver) == COMPOUND_EXPR
5537 && !IS_SUPER (rtype)));
5539 /* If the receiver is a class object, retrieve the corresponding
5540 @interface, if one exists. */
5541 class_tree = receiver_is_class_object (receiver, self, super);
5543 /* Now determine the receiver type (if an explicit cast has not been
5548 rtype = lookup_interface (class_tree);
5549 /* Handle `self' and `super'. */
5552 if (!CLASS_SUPER_NAME (implementation_template))
5554 error ("no super class declared in @interface for `%s'",
5555 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
5556 return error_mark_node;
5558 rtype = lookup_interface (CLASS_SUPER_NAME (implementation_template));
5561 rtype = lookup_interface (CLASS_NAME (implementation_template));
5564 /* If receiver is of type `id' or `Class' (or if the @interface for a
5565 class is not visible), we shall be satisfied with the existence of
5566 any instance or class method. */
5567 if (!rtype || objc_is_id (rtype))
5570 rtype = xref_tag (RECORD_TYPE, class_tree);
5573 class_tree = (IS_CLASS (rtype) ? objc_class_name : NULL_TREE);
5574 rprotos = TYPE_PROTOCOL_LIST (rtype);
5580 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
5581 in protocols themselves for the method prototype. */
5583 = lookup_method_in_protocol_list (rprotos, sel_name,
5584 class_tree != NULL_TREE);
5586 /* If messaging 'Class <Proto>' but did not find a class method
5587 prototype, search for an instance method instead, and warn
5588 about having done so. */
5589 if (!method_prototype && !rtype && class_tree != NULL_TREE)
5592 = lookup_method_in_protocol_list (rprotos, sel_name, 0);
5594 if (method_prototype)
5595 warning ("found `-%s' instead of `+%s' in protocol(s)",
5596 IDENTIFIER_POINTER (sel_name),
5597 IDENTIFIER_POINTER (sel_name));
5603 tree orig_rtype = rtype, saved_rtype;
5605 if (TREE_CODE (rtype) == POINTER_TYPE)
5606 rtype = TREE_TYPE (rtype);
5607 /* Traverse typedef aliases */
5608 while (TREE_CODE (rtype) == RECORD_TYPE && OBJC_TYPE_NAME (rtype)
5609 && TREE_CODE (OBJC_TYPE_NAME (rtype)) == TYPE_DECL
5610 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype)))
5611 rtype = DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype));
5612 saved_rtype = rtype;
5613 if (TYPED_OBJECT (rtype))
5615 rprotos = TYPE_PROTOCOL_LIST (rtype);
5616 rtype = lookup_interface (OBJC_TYPE_NAME (rtype));
5618 /* If we could not find an @interface declaration, we must have
5619 only seen a @class declaration; so, we cannot say anything
5620 more intelligent about which methods the receiver will
5623 rtype = saved_rtype;
5624 else if (TREE_CODE (rtype) == CLASS_INTERFACE_TYPE
5625 || TREE_CODE (rtype) == CLASS_IMPLEMENTATION_TYPE)
5627 /* We have a valid ObjC class name. Look up the method name
5628 in the published @interface for the class (and its
5631 = lookup_method_static (rtype, sel_name, class_tree != NULL_TREE);
5633 /* If the method was not found in the @interface, it may still
5634 exist locally as part of the @implementation. */
5635 if (!method_prototype && objc_implementation_context
5636 && CLASS_NAME (objc_implementation_context)
5637 == OBJC_TYPE_NAME (rtype))
5641 ? CLASS_CLS_METHODS (objc_implementation_context)
5642 : CLASS_NST_METHODS (objc_implementation_context)),
5645 /* If we haven't found a candidate method by now, try looking for
5646 it in the protocol list. */
5647 if (!method_prototype && rprotos)
5649 = lookup_method_in_protocol_list (rprotos, sel_name,
5650 class_tree != NULL_TREE);
5654 warning ("invalid receiver type `%s'",
5655 gen_type_name (orig_rtype));
5656 /* After issuing the "invalid receiver" warning, perform method
5657 lookup as if we were messaging 'id'. */
5658 rtype = rprotos = NULL_TREE;
5663 /* For 'id' or 'Class' receivers, search in the global hash table
5664 as a last resort. For all receivers, warn if protocol searches
5666 if (!method_prototype)
5669 warning ("`%c%s' not found in protocol(s)",
5670 (class_tree ? '+' : '-'),
5671 IDENTIFIER_POINTER (sel_name));
5675 = lookup_method_in_hash_lists (sel_name, class_tree != NULL_TREE);
5678 if (!method_prototype)
5680 static bool warn_missing_methods = false;
5683 warning ("`%s' may not respond to `%c%s'",
5684 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype)),
5685 (class_tree ? '+' : '-'),
5686 IDENTIFIER_POINTER (sel_name));
5687 /* If we are messaging an 'id' or 'Class' object and made it here,
5688 then we have failed to find _any_ instance or class method,
5691 warning ("no `%c%s' method found",
5692 (class_tree ? '+' : '-'),
5693 IDENTIFIER_POINTER (sel_name));
5695 if (!warn_missing_methods)
5697 warning ("(Messages without a matching method signature");
5698 warning ("will be assumed to return `id' and accept");
5699 warning ("`...' as arguments.)");
5700 warn_missing_methods = true;
5704 /* Save the selector name for printing error messages. */
5705 current_objc_message_selector = sel_name;
5707 /* Build the parameters list for looking up the method.
5708 These are the object itself and the selector. */
5710 if (flag_typed_selectors)
5711 selector = build_typed_selector_reference (sel_name, method_prototype);
5713 selector = build_selector_reference (sel_name);
5715 retval = build_objc_method_call (super, method_prototype,
5717 selector, method_params);
5719 current_objc_message_selector = 0;
5724 /* Build a tree expression to send OBJECT the operation SELECTOR,
5725 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5726 assuming the method has prototype METHOD_PROTOTYPE.
5727 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5728 Use METHOD_PARAMS as list of args to pass to the method.
5729 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5732 build_objc_method_call (int super_flag, tree method_prototype,
5733 tree lookup_object, tree selector,
5736 tree sender = (super_flag ? umsg_super_decl :
5737 (!flag_next_runtime || flag_nil_receivers
5739 : umsg_nonnil_decl));
5740 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
5742 /* If a prototype for the method to be called exists, then cast
5743 the sender's return type and arguments to match that of the method.
5744 Otherwise, leave sender as is. */
5747 ? TREE_VALUE (TREE_TYPE (method_prototype))
5748 : objc_object_type);
5750 = build_pointer_type
5751 (build_function_type
5754 (method_prototype, METHOD_REF, super_flag)));
5757 lookup_object = build_c_cast (rcv_p, lookup_object);
5759 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
5760 lookup_object = save_expr (lookup_object);
5762 if (flag_next_runtime)
5764 /* If we are returning a struct in memory, and the address
5765 of that memory location is passed as a hidden first
5766 argument, then change which messenger entry point this
5767 expr will call. NB: Note that sender_cast remains
5768 unchanged (it already has a struct return type). */
5769 if (!targetm.calls.struct_value_rtx (0, 0)
5770 && (TREE_CODE (ret_type) == RECORD_TYPE
5771 || TREE_CODE (ret_type) == UNION_TYPE)
5772 && targetm.calls.return_in_memory (ret_type, 0))
5773 sender = (super_flag ? umsg_super_stret_decl :
5774 flag_nil_receivers ? umsg_stret_decl : umsg_nonnil_stret_decl);
5776 method_params = tree_cons (NULL_TREE, lookup_object,
5777 tree_cons (NULL_TREE, selector,
5779 method = build_fold_addr_expr (sender);
5783 /* This is the portable (GNU) way. */
5786 /* First, call the lookup function to get a pointer to the method,
5787 then cast the pointer, then call it with the method arguments. */
5789 object = (super_flag ? self_decl : lookup_object);
5791 t = tree_cons (NULL_TREE, selector, NULL_TREE);
5792 t = tree_cons (NULL_TREE, lookup_object, t);
5793 method = build_function_call (sender, t);
5795 /* Pass the object to the method. */
5796 method_params = tree_cons (NULL_TREE, object,
5797 tree_cons (NULL_TREE, selector,
5801 /* ??? Selector is not at this point something we can use inside
5802 the compiler itself. Set it to garbage for the nonce. */
5803 t = build (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
5804 return build_function_call (t, method_params);
5808 build_protocol_reference (tree p)
5811 const char *proto_name;
5813 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
5815 proto_name = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p);
5816 decl = start_var_decl (objc_protocol_template, proto_name);
5818 PROTOCOL_FORWARD_DECL (p) = decl;
5821 /* This function is called by the parser when (and only when) a
5822 @protocol() expression is found, in order to compile it. */
5824 objc_build_protocol_expr (tree protoname)
5827 tree p = lookup_protocol (protoname);
5831 error ("cannot find protocol declaration for `%s'",
5832 IDENTIFIER_POINTER (protoname));
5833 return error_mark_node;
5836 if (!PROTOCOL_FORWARD_DECL (p))
5837 build_protocol_reference (p);
5839 expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
5841 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
5842 if we have it, rather than converting it here. */
5843 expr = convert (objc_protocol_type, expr);
5845 /* The @protocol() expression is being compiled into a pointer to a
5846 statically allocated instance of the Protocol class. To become
5847 usable at runtime, the 'isa' pointer of the instance need to be
5848 fixed up at runtime by the runtime library, to point to the
5849 actual 'Protocol' class. */
5851 /* For the GNU runtime, put the static Protocol instance in the list
5852 of statically allocated instances, so that we make sure that its
5853 'isa' pointer is fixed up at runtime by the GNU runtime library
5854 to point to the Protocol class (at runtime, when loading the
5855 module, the GNU runtime library loops on the statically allocated
5856 instances (as found in the defs field in objc_symtab) and fixups
5857 all the 'isa' pointers of those objects). */
5858 if (! flag_next_runtime)
5860 /* This type is a struct containing the fields of a Protocol
5861 object. (Cfr. objc_protocol_type instead is the type of a pointer
5862 to such a struct). */
5863 tree protocol_struct_type = xref_tag
5864 (RECORD_TYPE, get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
5867 /* Look for the list of Protocol statically allocated instances
5868 to fixup at runtime. Create a new list to hold Protocol
5869 statically allocated instances, if the list is not found. At
5870 present there is only another list, holding NSConstantString
5871 static instances to be fixed up at runtime. */
5872 for (chain = &objc_static_instances;
5873 *chain && TREE_VALUE (*chain) != protocol_struct_type;
5874 chain = &TREE_CHAIN (*chain));
5877 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
5878 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
5882 /* Add this statically allocated instance to the Protocol list. */
5883 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
5884 PROTOCOL_FORWARD_DECL (p),
5885 TREE_PURPOSE (*chain));
5892 /* This function is called by the parser when a @selector() expression
5893 is found, in order to compile it. It is only called by the parser
5894 and only to compile a @selector(). */
5896 objc_build_selector_expr (tree selnamelist)
5900 /* Obtain the full selector name. */
5901 if (TREE_CODE (selnamelist) == IDENTIFIER_NODE)
5902 /* A unary selector. */
5903 selname = selnamelist;
5904 else if (TREE_CODE (selnamelist) == TREE_LIST)
5905 selname = build_keyword_selector (selnamelist);
5909 /* If we are required to check @selector() expressions as they
5910 are found, check that the selector has been declared. */
5911 if (warn_undeclared_selector)
5913 /* Look the selector up in the list of all known class and
5914 instance methods (up to this line) to check that the selector
5918 /* First try with instance methods. */
5919 hsh = hash_lookup (nst_method_hash_list, selname);
5921 /* If not found, try with class methods. */
5924 hsh = hash_lookup (cls_method_hash_list, selname);
5927 /* If still not found, print out a warning. */
5930 warning ("undeclared selector `%s'", IDENTIFIER_POINTER (selname));
5935 if (flag_typed_selectors)
5936 return build_typed_selector_reference (selname, 0);
5938 return build_selector_reference (selname);
5942 objc_build_encode_expr (tree type)
5947 encode_type (type, obstack_object_size (&util_obstack),
5948 OBJC_ENCODE_INLINE_DEFS);
5949 obstack_1grow (&util_obstack, 0); /* null terminate string */
5950 string = obstack_finish (&util_obstack);
5952 /* Synthesize a string that represents the encoded struct/union. */
5953 result = my_build_string (strlen (string) + 1, string);
5954 obstack_free (&util_obstack, util_firstobj);
5959 build_ivar_reference (tree id)
5961 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
5963 /* Historically, a class method that produced objects (factory
5964 method) would assign `self' to the instance that it
5965 allocated. This would effectively turn the class method into
5966 an instance method. Following this assignment, the instance
5967 variables could be accessed. That practice, while safe,
5968 violates the simple rule that a class method should not refer
5969 to an instance variable. It's better to catch the cases
5970 where this is done unknowingly than to support the above
5972 warning ("instance variable `%s' accessed in class method",
5973 IDENTIFIER_POINTER (id));
5974 self_decl = convert (objc_instance_type, self_decl); /* cast */
5977 return build_component_ref (build_indirect_ref (self_decl, "->"), id);
5980 /* Compute a hash value for a given method SEL_NAME. */
5983 hash_func (tree sel_name)
5985 const unsigned char *s
5986 = (const unsigned char *)IDENTIFIER_POINTER (sel_name);
5990 h = h * 67 + *s++ - 113;
5997 nst_method_hash_list
5998 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
5999 cls_method_hash_list
6000 = (hash *) ggc_alloc_cleared (SIZEHASHTABLE * sizeof (hash));
6002 /* Initialize the hash table used to hold the constant string objects. */
6003 string_htab = htab_create_ggc (31, string_hash,
6007 /* WARNING!!!! hash_enter is called with a method, and will peek
6008 inside to find its selector! But hash_lookup is given a selector
6009 directly, and looks for the selector that's inside the found
6010 entry's key (method) for comparison. */
6013 hash_enter (hash *hashlist, tree method)
6016 int slot = hash_func (METHOD_SEL_NAME (method)) % SIZEHASHTABLE;
6018 obj = (hash) ggc_alloc (sizeof (struct hashed_entry));
6020 obj->next = hashlist[slot];
6023 hashlist[slot] = obj; /* append to front */
6027 hash_lookup (hash *hashlist, tree sel_name)
6031 target = hashlist[hash_func (sel_name) % SIZEHASHTABLE];
6035 if (sel_name == METHOD_SEL_NAME (target->key))
6038 target = target->next;
6044 hash_add_attr (hash entry, tree value)
6048 obj = (attr) ggc_alloc (sizeof (struct hashed_attribute));
6049 obj->next = entry->list;
6052 entry->list = obj; /* append to front */
6056 lookup_method (tree mchain, tree method)
6060 if (TREE_CODE (method) == IDENTIFIER_NODE)
6063 key = METHOD_SEL_NAME (method);
6067 if (METHOD_SEL_NAME (mchain) == key)
6070 mchain = TREE_CHAIN (mchain);
6076 lookup_method_static (tree interface, tree ident, int is_class)
6078 tree meth = NULL_TREE, root_inter = NULL_TREE;
6079 tree inter = interface;
6083 tree chain = is_class ? CLASS_CLS_METHODS (inter) : CLASS_NST_METHODS (inter);
6084 tree category = inter;
6086 /* First, look up the method in the class itself. */
6087 if ((meth = lookup_method (chain, ident)))
6090 /* Failing that, look for the method in each category of the class. */
6091 while ((category = CLASS_CATEGORY_LIST (category)))
6093 chain = is_class ? CLASS_CLS_METHODS (category) : CLASS_NST_METHODS (category);
6095 /* Check directly in each category. */
6096 if ((meth = lookup_method (chain, ident)))
6099 /* Failing that, check in each category's protocols. */
6100 if (CLASS_PROTOCOL_LIST (category))
6102 if ((meth = (lookup_method_in_protocol_list
6103 (CLASS_PROTOCOL_LIST (category), ident, is_class))))
6108 /* If not found in categories, check in protocols of the main class. */
6109 if (CLASS_PROTOCOL_LIST (inter))
6111 if ((meth = (lookup_method_in_protocol_list
6112 (CLASS_PROTOCOL_LIST (inter), ident, is_class))))
6116 /* Failing that, climb up the inheritance hierarchy. */
6118 inter = lookup_interface (CLASS_SUPER_NAME (inter));
6122 /* If no class (factory) method was found, check if an _instance_
6123 method of the same name exists in the root class. This is what
6124 the Objective-C runtime will do. If an instance method was not
6126 return is_class ? lookup_method_static (root_inter, ident, 0): NULL_TREE;
6129 /* Add the method to the hash list if it doesn't contain an identical
6132 add_method_to_hash_list (hash *hash_list, tree method)
6136 if (!(hsh = hash_lookup (hash_list, METHOD_SEL_NAME (method))))
6138 /* Install on a global chain. */
6139 hash_enter (hash_list, method);
6143 /* Check types against those; if different, add to a list. */
6145 int already_there = comp_proto_with_proto (method, hsh->key);
6146 for (loop = hsh->list; !already_there && loop; loop = loop->next)
6147 already_there |= comp_proto_with_proto (method, loop->value);
6149 hash_add_attr (hsh, method);
6154 objc_add_method (tree class, tree method, int is_class)
6158 if (!(mth = lookup_method (is_class
6159 ? CLASS_CLS_METHODS (class)
6160 : CLASS_NST_METHODS (class), method)))
6162 /* put method on list in reverse order */
6165 TREE_CHAIN (method) = CLASS_CLS_METHODS (class);
6166 CLASS_CLS_METHODS (class) = method;
6170 TREE_CHAIN (method) = CLASS_NST_METHODS (class);
6171 CLASS_NST_METHODS (class) = method;
6176 /* When processing an @interface for a class or category, give hard
6177 errors on methods with identical selectors but differing argument
6178 and/or return types. We do not do this for @implementations, because
6179 C/C++ will do it for us (i.e., there will be duplicate function
6180 definition errors). */
6181 if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
6182 || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE)
6183 && !comp_proto_with_proto (method, mth))
6184 error ("duplicate declaration of method `%c%s'",
6185 is_class ? '+' : '-',
6186 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth)));
6190 add_method_to_hash_list (cls_method_hash_list, method);
6193 add_method_to_hash_list (nst_method_hash_list, method);
6195 /* Instance methods in root classes (and categories thereof)
6196 may act as class methods as a last resort. We also add
6197 instance methods listed in @protocol declarations to
6198 the class hash table, on the assumption that @protocols
6199 may be adopted by root classes or categories. */
6200 if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
6201 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6202 class = lookup_interface (CLASS_NAME (class));
6204 if (TREE_CODE (class) == PROTOCOL_INTERFACE_TYPE
6205 || !CLASS_SUPER_NAME (class))
6206 add_method_to_hash_list (cls_method_hash_list, method);
6213 add_class (tree class)
6215 /* Put interfaces on list in reverse order. */
6216 TREE_CHAIN (class) = interface_chain;
6217 interface_chain = class;
6218 return interface_chain;
6222 add_category (tree class, tree category)
6224 /* Put categories on list in reverse order. */
6225 tree cat = lookup_category (class, CLASS_SUPER_NAME (category));
6229 warning ("duplicate interface declaration for category `%s(%s)'",
6230 IDENTIFIER_POINTER (CLASS_NAME (class)),
6231 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category)));
6235 CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class);
6236 CLASS_CATEGORY_LIST (class) = category;
6240 /* Called after parsing each instance variable declaration. Necessary to
6241 preserve typedefs and implement public/private...
6243 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
6246 add_instance_variable (tree class, int public, tree field_decl)
6248 tree field_type = TREE_TYPE (field_decl);
6249 const char *ivar_name = DECL_NAME (field_decl)
6250 ? IDENTIFIER_POINTER (DECL_NAME (field_decl))
6254 if (TREE_CODE (field_type) == REFERENCE_TYPE)
6256 error ("illegal reference type specified for instance variable `%s'",
6258 /* Return class as is without adding this ivar. */
6263 if (field_type == error_mark_node || !TYPE_SIZE (field_type)
6264 || TYPE_SIZE (field_type) == error_mark_node)
6265 /* 'type[0]' is allowed, but 'type[]' is not! */
6267 error ("instance variable `%s' has unknown size", ivar_name);
6268 /* Return class as is without adding this ivar. */
6273 /* zlaski 2001-Apr-24: C++ classes with non-trivial constructors and/or destructors
6274 cannot be ivars; ditto for classes with vtables. */
6275 if(IS_AGGR_TYPE (field_type) && (TYPE_NEEDS_CONSTRUCTING (field_type)
6276 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type) || TYPE_POLYMORPHIC_P (field_type)))
6278 const char *type_name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type));
6279 if(TYPE_POLYMORPHIC_P (field_type)) {
6280 /* vtable pointers are Real Bad(tm), since Obj-C cannot initialize them */
6281 error ("type `%s' has virtual member functions", type_name);
6282 error ("illegal aggregate type `%s' specified for instance variable `%s'",
6283 type_name, ivar_name);
6284 /* Return class as is without adding this ivar. */
6287 /* user-defined constructors and destructors are not known to Obj-C and
6288 hence will not be called. This may or may not be a problem. */
6289 if (TYPE_NEEDS_CONSTRUCTING (field_type))
6290 warning ("type `%s' has a user-defined constructor", type_name);
6291 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type))
6292 warning ("type `%s' has a user-defined destructor", type_name);
6293 warning ("C++ constructors and destructors will not be invoked for Objective-C fields");
6297 /* Overload the public attribute, it is not used for FIELD_DECLs. */
6301 TREE_PUBLIC (field_decl) = 0;
6302 TREE_PRIVATE (field_decl) = 0;
6303 TREE_PROTECTED (field_decl) = 1;
6307 TREE_PUBLIC (field_decl) = 1;
6308 TREE_PRIVATE (field_decl) = 0;
6309 TREE_PROTECTED (field_decl) = 0;
6313 TREE_PUBLIC (field_decl) = 0;
6314 TREE_PRIVATE (field_decl) = 1;
6315 TREE_PROTECTED (field_decl) = 0;
6320 CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), field_decl);
6326 is_ivar (tree decl_chain, tree ident)
6328 for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain))
6329 if (DECL_NAME (decl_chain) == ident)
6334 /* True if the ivar is private and we are not in its implementation. */
6337 is_private (tree decl)
6339 return (TREE_PRIVATE (decl)
6340 && ! is_ivar (CLASS_IVARS (implementation_template),
6344 /* We have an instance variable reference;, check to see if it is public. */
6347 objc_is_public (tree expr, tree identifier)
6349 tree basetype = TREE_TYPE (expr);
6350 enum tree_code code = TREE_CODE (basetype);
6353 if (code == RECORD_TYPE)
6355 if (TREE_STATIC_TEMPLATE (basetype))
6357 if (!lookup_interface (OBJC_TYPE_NAME (basetype)))
6359 error ("cannot find interface declaration for `%s'",
6360 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype)));
6364 if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier)))
6366 if (TREE_PUBLIC (decl))
6369 /* Important difference between the Stepstone translator:
6370 all instance variables should be public within the context
6371 of the implementation. */
6372 if (objc_implementation_context
6373 && (((TREE_CODE (objc_implementation_context)
6374 == CLASS_IMPLEMENTATION_TYPE)
6375 || (TREE_CODE (objc_implementation_context)
6376 == CATEGORY_IMPLEMENTATION_TYPE))
6377 && (CLASS_NAME (objc_implementation_context)
6378 == OBJC_TYPE_NAME (basetype))))
6380 int private = is_private (decl);
6383 error ("instance variable `%s' is declared private",
6384 IDENTIFIER_POINTER (DECL_NAME (decl)));
6388 /* The 2.95.2 compiler sometimes allowed C functions to access
6389 non-@public ivars. We will let this slide for now... */
6390 if (!objc_method_context)
6392 warning ("instance variable `%s' is %s; "
6393 "this will be a hard error in the future",
6394 IDENTIFIER_POINTER (identifier),
6395 TREE_PRIVATE (decl) ? "@private" : "@protected");
6399 error ("instance variable `%s' is declared %s",
6400 IDENTIFIER_POINTER (identifier),
6401 TREE_PRIVATE (decl) ? "private" : "protected");
6406 else if (objc_implementation_context && (basetype == objc_object_reference))
6408 expr = convert (uprivate_record, expr);
6409 warning ("static access to object of type `id'");
6416 /* Make sure all entries in CHAIN are also in LIST. */
6419 check_methods (tree chain, tree list, int mtype)
6425 if (!lookup_method (list, chain))
6429 if (TREE_CODE (objc_implementation_context)
6430 == CLASS_IMPLEMENTATION_TYPE)
6431 warning ("incomplete implementation of class `%s'",
6432 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6433 else if (TREE_CODE (objc_implementation_context)
6434 == CATEGORY_IMPLEMENTATION_TYPE)
6435 warning ("incomplete implementation of category `%s'",
6436 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6440 warning ("method definition for `%c%s' not found",
6441 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6444 chain = TREE_CHAIN (chain);
6450 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
6453 conforms_to_protocol (tree class, tree protocol)
6455 if (TREE_CODE (protocol) == PROTOCOL_INTERFACE_TYPE)
6457 tree p = CLASS_PROTOCOL_LIST (class);
6458 while (p && TREE_VALUE (p) != protocol)
6463 tree super = (CLASS_SUPER_NAME (class)
6464 ? lookup_interface (CLASS_SUPER_NAME (class))
6466 int tmp = super ? conforms_to_protocol (super, protocol) : 0;
6475 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
6476 CONTEXT. This is one of two mechanisms to check protocol integrity. */
6479 check_methods_accessible (tree chain, tree context, int mtype)
6483 tree base_context = context;
6487 context = base_context;
6491 list = CLASS_CLS_METHODS (context);
6493 list = CLASS_NST_METHODS (context);
6495 if (lookup_method (list, chain))
6498 else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE
6499 || TREE_CODE (context) == CLASS_INTERFACE_TYPE)
6500 context = (CLASS_SUPER_NAME (context)
6501 ? lookup_interface (CLASS_SUPER_NAME (context))
6504 else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE
6505 || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE)
6506 context = (CLASS_NAME (context)
6507 ? lookup_interface (CLASS_NAME (context))
6513 if (context == NULL_TREE)
6517 if (TREE_CODE (objc_implementation_context)
6518 == CLASS_IMPLEMENTATION_TYPE)
6519 warning ("incomplete implementation of class `%s'",
6521 (CLASS_NAME (objc_implementation_context)));
6522 else if (TREE_CODE (objc_implementation_context)
6523 == CATEGORY_IMPLEMENTATION_TYPE)
6524 warning ("incomplete implementation of category `%s'",
6526 (CLASS_SUPER_NAME (objc_implementation_context)));
6529 warning ("method definition for `%c%s' not found",
6530 mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain)));
6533 chain = TREE_CHAIN (chain); /* next method... */
6538 /* Check whether the current interface (accessible via
6539 'objc_implementation_context') actually implements protocol P, along
6540 with any protocols that P inherits. */
6543 check_protocol (tree p, const char *type, const char *name)
6545 if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE)
6549 /* Ensure that all protocols have bodies! */
6552 f1 = check_methods (PROTOCOL_CLS_METHODS (p),
6553 CLASS_CLS_METHODS (objc_implementation_context),
6555 f2 = check_methods (PROTOCOL_NST_METHODS (p),
6556 CLASS_NST_METHODS (objc_implementation_context),
6561 f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p),
6562 objc_implementation_context,
6564 f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p),
6565 objc_implementation_context,
6570 warning ("%s `%s' does not fully implement the `%s' protocol",
6571 type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
6574 /* Check protocols recursively. */
6575 if (PROTOCOL_LIST (p))
6577 tree subs = PROTOCOL_LIST (p);
6579 lookup_interface (CLASS_SUPER_NAME (implementation_template));
6583 tree sub = TREE_VALUE (subs);
6585 /* If the superclass does not conform to the protocols
6586 inherited by P, then we must! */
6587 if (!super_class || !conforms_to_protocol (super_class, sub))
6588 check_protocol (sub, type, name);
6589 subs = TREE_CHAIN (subs);
6594 /* Check whether the current interface (accessible via
6595 'objc_implementation_context') actually implements the protocols listed
6599 check_protocols (tree proto_list, const char *type, const char *name)
6601 for ( ; proto_list; proto_list = TREE_CHAIN (proto_list))
6603 tree p = TREE_VALUE (proto_list);
6605 check_protocol (p, type, name);
6609 /* Make sure that the class CLASS_NAME is defined
6610 CODE says which kind of thing CLASS_NAME ought to be.
6611 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6612 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6615 start_class (enum tree_code code, tree class_name, tree super_name,
6621 if (current_namespace != global_namespace) {
6622 error ("Objective-C declarations may only appear in global scope");
6624 #endif /* OBJCPLUS */
6626 if (objc_implementation_context)
6628 warning ("`@end' missing in implementation context");
6629 finish_class (objc_implementation_context);
6630 objc_ivar_chain = NULL_TREE;
6631 objc_implementation_context = NULL_TREE;
6634 class = make_node (code);
6635 TYPE_LANG_SLOT_1 (class) = make_tree_vec (CLASS_LANG_SLOT_ELTS);
6637 /* Check for existence of the super class, if one was specified. */
6638 if ((code == CLASS_INTERFACE_TYPE || code == CLASS_IMPLEMENTATION_TYPE)
6639 && super_name && !objc_is_class_name (super_name))
6641 error ("cannot find interface declaration for `%s', superclass of `%s'",
6642 IDENTIFIER_POINTER (super_name),
6643 IDENTIFIER_POINTER (class_name));
6644 super_name = NULL_TREE;
6647 CLASS_NAME (class) = class_name;
6648 CLASS_SUPER_NAME (class) = super_name;
6649 CLASS_CLS_METHODS (class) = NULL_TREE;
6651 if (! objc_is_class_name (class_name)
6652 && (decl = lookup_name (class_name)))
6654 error ("`%s' redeclared as different kind of symbol",
6655 IDENTIFIER_POINTER (class_name));
6656 error ("%Jprevious declaration of '%D'",
6660 if (code == CLASS_IMPLEMENTATION_TYPE)
6665 for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain))
6666 if (TREE_VALUE (chain) == class_name)
6668 error ("reimplementation of class `%s'",
6669 IDENTIFIER_POINTER (class_name));
6670 return error_mark_node;
6672 implemented_classes = tree_cons (NULL_TREE, class_name,
6673 implemented_classes);
6676 /* Reset for multiple classes per file. */
6679 objc_implementation_context = class;
6681 /* Lookup the interface for this implementation. */
6683 if (!(implementation_template = lookup_interface (class_name)))
6685 warning ("cannot find interface declaration for `%s'",
6686 IDENTIFIER_POINTER (class_name));
6687 add_class (implementation_template = objc_implementation_context);
6690 /* If a super class has been specified in the implementation,
6691 insure it conforms to the one specified in the interface. */
6694 && (super_name != CLASS_SUPER_NAME (implementation_template)))
6696 tree previous_name = CLASS_SUPER_NAME (implementation_template);
6697 const char *const name =
6698 previous_name ? IDENTIFIER_POINTER (previous_name) : "";
6699 error ("conflicting super class name `%s'",
6700 IDENTIFIER_POINTER (super_name));
6701 error ("previous declaration of `%s'", name);
6704 else if (! super_name)
6706 CLASS_SUPER_NAME (objc_implementation_context)
6707 = CLASS_SUPER_NAME (implementation_template);
6711 else if (code == CLASS_INTERFACE_TYPE)
6713 if (lookup_interface (class_name))
6715 error ("duplicate interface declaration for class `%s'",
6717 warning ("duplicate interface declaration for class `%s'",
6719 IDENTIFIER_POINTER (class_name));
6724 CLASS_PROTOCOL_LIST (class)
6725 = lookup_and_install_protocols (protocol_list);
6728 else if (code == CATEGORY_INTERFACE_TYPE)
6730 tree class_category_is_assoc_with;
6732 /* For a category, class_name is really the name of the class that
6733 the following set of methods will be associated with. We must
6734 find the interface so that can derive the objects template. */
6736 if (!(class_category_is_assoc_with = lookup_interface (class_name)))
6738 error ("cannot find interface declaration for `%s'",
6739 IDENTIFIER_POINTER (class_name));
6740 exit (FATAL_EXIT_CODE);
6743 add_category (class_category_is_assoc_with, class);
6746 CLASS_PROTOCOL_LIST (class)
6747 = lookup_and_install_protocols (protocol_list);
6750 else if (code == CATEGORY_IMPLEMENTATION_TYPE)
6752 /* Reset for multiple classes per file. */
6755 objc_implementation_context = class;
6757 /* For a category, class_name is really the name of the class that
6758 the following set of methods will be associated with. We must
6759 find the interface so that can derive the objects template. */
6761 if (!(implementation_template = lookup_interface (class_name)))
6763 error ("cannot find interface declaration for `%s'",
6764 IDENTIFIER_POINTER (class_name));
6765 exit (FATAL_EXIT_CODE);
6772 continue_class (tree class)
6774 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6775 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6777 struct imp_entry *imp_entry;
6780 /* Check consistency of the instance variables. */
6782 if (CLASS_RAW_IVARS (class))
6783 check_ivars (implementation_template, class);
6785 /* code generation */
6788 push_lang_context (lang_name_c);
6791 ivar_context = build_private_template (implementation_template);
6793 imp_entry = (struct imp_entry *) ggc_alloc (sizeof (struct imp_entry));
6795 imp_entry->next = imp_list;
6796 imp_entry->imp_context = class;
6797 imp_entry->imp_template = implementation_template;
6799 synth_forward_declarations ();
6800 imp_entry->class_decl = UOBJC_CLASS_decl;
6801 imp_entry->meta_decl = UOBJC_METACLASS_decl;
6803 /* Append to front and increment count. */
6804 imp_list = imp_entry;
6805 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6811 pop_lang_context ();
6812 #endif /* OBJCPLUS */
6814 return ivar_context;
6817 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE)
6820 push_lang_context (lang_name_c);
6821 #endif /* OBJCPLUS */
6823 if (!CLASS_STATIC_TEMPLATE (class))
6825 tree record = start_struct (RECORD_TYPE, CLASS_NAME (class));
6826 finish_struct (record, get_class_ivars (class), NULL_TREE);
6827 CLASS_STATIC_TEMPLATE (class) = record;
6829 /* Mark this record as a class template for static typing. */
6830 TREE_STATIC_TEMPLATE (record) = 1;
6834 pop_lang_context ();
6835 #endif /* OBJCPLUS */
6841 return error_mark_node;
6844 /* This is called once we see the "@end" in an interface/implementation. */
6847 finish_class (tree class)
6849 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE)
6851 /* All code generation is done in finish_objc. */
6853 if (implementation_template != objc_implementation_context)
6855 /* Ensure that all method listed in the interface contain bodies. */
6856 check_methods (CLASS_CLS_METHODS (implementation_template),
6857 CLASS_CLS_METHODS (objc_implementation_context), '+');
6858 check_methods (CLASS_NST_METHODS (implementation_template),
6859 CLASS_NST_METHODS (objc_implementation_context), '-');
6861 if (CLASS_PROTOCOL_LIST (implementation_template))
6862 check_protocols (CLASS_PROTOCOL_LIST (implementation_template),
6864 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context)));
6868 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE)
6870 tree category = lookup_category (implementation_template, CLASS_SUPER_NAME (class));
6874 /* Ensure all method listed in the interface contain bodies. */
6875 check_methods (CLASS_CLS_METHODS (category),
6876 CLASS_CLS_METHODS (objc_implementation_context), '+');
6877 check_methods (CLASS_NST_METHODS (category),
6878 CLASS_NST_METHODS (objc_implementation_context), '-');
6880 if (CLASS_PROTOCOL_LIST (category))
6881 check_protocols (CLASS_PROTOCOL_LIST (category),
6883 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
6889 add_protocol (tree protocol)
6891 /* Put protocol on list in reverse order. */
6892 TREE_CHAIN (protocol) = protocol_chain;
6893 protocol_chain = protocol;
6894 return protocol_chain;
6898 lookup_protocol (tree ident)
6902 for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain))
6903 if (ident == PROTOCOL_NAME (chain))
6909 /* This function forward declares the protocols named by NAMES. If
6910 they are already declared or defined, the function has no effect. */
6913 objc_declare_protocols (tree names)
6918 if (current_namespace != global_namespace) {
6919 error ("Objective-C declarations may only appear in global scope");
6921 #endif /* OBJCPLUS */
6923 for (list = names; list; list = TREE_CHAIN (list))
6925 tree name = TREE_VALUE (list);
6927 if (lookup_protocol (name) == NULL_TREE)
6929 tree protocol = make_node (PROTOCOL_INTERFACE_TYPE);
6931 TYPE_LANG_SLOT_1 (protocol)
6932 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
6933 PROTOCOL_NAME (protocol) = name;
6934 PROTOCOL_LIST (protocol) = NULL_TREE;
6935 add_protocol (protocol);
6936 PROTOCOL_DEFINED (protocol) = 0;
6937 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6943 start_protocol (enum tree_code code, tree name, tree list)
6948 if (current_namespace != global_namespace) {
6949 error ("Objective-C declarations may only appear in global scope");
6951 #endif /* OBJCPLUS */
6953 protocol = lookup_protocol (name);
6957 protocol = make_node (code);
6958 TYPE_LANG_SLOT_1 (protocol) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS);
6960 PROTOCOL_NAME (protocol) = name;
6961 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6962 add_protocol (protocol);
6963 PROTOCOL_DEFINED (protocol) = 1;
6964 PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE;
6966 check_protocol_recursively (protocol, list);
6968 else if (! PROTOCOL_DEFINED (protocol))
6970 PROTOCOL_DEFINED (protocol) = 1;
6971 PROTOCOL_LIST (protocol) = lookup_and_install_protocols (list);
6973 check_protocol_recursively (protocol, list);
6977 warning ("duplicate declaration for protocol `%s'",
6978 IDENTIFIER_POINTER (name));
6984 /* "Encode" a data type into a string, which grows in util_obstack.
6985 ??? What is the FORMAT? Someone please document this! */
6988 encode_type_qualifiers (tree declspecs)
6992 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
6994 if (ridpointers[(int) RID_IN] == TREE_VALUE (spec))
6995 obstack_1grow (&util_obstack, 'n');
6996 else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec))
6997 obstack_1grow (&util_obstack, 'N');
6998 else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec))
6999 obstack_1grow (&util_obstack, 'o');
7000 else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec))
7001 obstack_1grow (&util_obstack, 'O');
7002 else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec))
7003 obstack_1grow (&util_obstack, 'R');
7004 else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec))
7005 obstack_1grow (&util_obstack, 'V');
7009 /* Encode a pointer type. */
7012 encode_pointer (tree type, int curtype, int format)
7014 tree pointer_to = TREE_TYPE (type);
7016 if (TREE_CODE (pointer_to) == RECORD_TYPE)
7018 if (OBJC_TYPE_NAME (pointer_to)
7019 && TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE)
7021 const char *name = IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to));
7023 if (strcmp (name, TAG_OBJECT) == 0) /* '@' */
7025 obstack_1grow (&util_obstack, '@');
7028 else if (TREE_STATIC_TEMPLATE (pointer_to))
7030 if (generating_instance_variables)
7032 obstack_1grow (&util_obstack, '@');
7033 obstack_1grow (&util_obstack, '"');
7034 obstack_grow (&util_obstack, name, strlen (name));
7035 obstack_1grow (&util_obstack, '"');
7040 obstack_1grow (&util_obstack, '@');
7044 else if (strcmp (name, TAG_CLASS) == 0) /* '#' */
7046 obstack_1grow (&util_obstack, '#');
7049 else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */
7051 obstack_1grow (&util_obstack, ':');
7056 else if (TREE_CODE (pointer_to) == INTEGER_TYPE
7057 && TYPE_MODE (pointer_to) == QImode)
7059 tree pname = TREE_CODE (OBJC_TYPE_NAME (pointer_to)) == IDENTIFIER_NODE
7060 ? OBJC_TYPE_NAME (pointer_to)
7061 : DECL_NAME (OBJC_TYPE_NAME (pointer_to));
7063 if (!flag_next_runtime || strcmp (IDENTIFIER_POINTER (pname), "BOOL"))
7065 /* It appears that "r*" means "const char *" rather than
7067 if (TYPE_READONLY (pointer_to))
7068 obstack_1grow (&util_obstack, 'r');
7070 obstack_1grow (&util_obstack, '*');
7075 /* We have a type that does not get special treatment. */
7077 /* NeXT extension */
7078 obstack_1grow (&util_obstack, '^');
7079 encode_type (pointer_to, curtype, format);
7083 encode_array (tree type, int curtype, int format)
7085 tree an_int_cst = TYPE_SIZE (type);
7086 tree array_of = TREE_TYPE (type);
7089 /* An incomplete array is treated like a pointer. */
7090 if (an_int_cst == NULL)
7092 encode_pointer (type, curtype, format);
7096 sprintf (buffer, "[" HOST_WIDE_INT_PRINT_DEC,
7097 (TREE_INT_CST_LOW (an_int_cst)
7098 / TREE_INT_CST_LOW (TYPE_SIZE (array_of))));
7100 obstack_grow (&util_obstack, buffer, strlen (buffer));
7101 encode_type (array_of, curtype, format);
7102 obstack_1grow (&util_obstack, ']');
7107 encode_aggregate_within (tree type, int curtype, int format, int left,
7111 /* NB: aggregates that are pointed to have slightly different encoding
7112 rules in that you never encode the names of instance variables. */
7114 = (obstack_object_size (&util_obstack) > 0
7115 && *(obstack_next_free (&util_obstack) - 1) == '^');
7117 = ((format == OBJC_ENCODE_INLINE_DEFS || generating_instance_variables)
7118 && (!pointed_to || obstack_object_size (&util_obstack) - curtype == 1));
7120 /* Traverse struct aliases; it is important to get the
7121 original struct and its tag name (if any). */
7122 type = TYPE_MAIN_VARIANT (type);
7123 name = OBJC_TYPE_NAME (type);
7124 /* Open parenth/bracket. */
7125 obstack_1grow (&util_obstack, left);
7127 /* Encode the struct/union tag name, or '?' if a tag was
7128 not provided. Typedef aliases do not qualify. */
7129 if (name && TREE_CODE (name) == IDENTIFIER_NODE
7131 /* Did this struct have a tag? */
7132 && !TYPE_WAS_ANONYMOUS (type)
7135 obstack_grow (&util_obstack,
7136 IDENTIFIER_POINTER (name),
7137 strlen (IDENTIFIER_POINTER (name)));
7139 obstack_1grow (&util_obstack, '?');
7141 /* Encode the types (and possibly names) of the inner fields,
7143 if (inline_contents)
7145 tree fields = TYPE_FIELDS (type);
7147 obstack_1grow (&util_obstack, '=');
7148 for (; fields; fields = TREE_CHAIN (fields))
7151 /* C++ static members, and things that are not fields at all,
7152 should not appear in the encoding. */
7153 if (TREE_CODE (fields) != FIELD_DECL || TREE_STATIC (fields))
7156 if (generating_instance_variables && !pointed_to)
7158 tree fname = DECL_NAME (fields);
7160 obstack_1grow (&util_obstack, '"');
7161 if (fname && TREE_CODE (fname) == IDENTIFIER_NODE)
7162 obstack_grow (&util_obstack,
7163 IDENTIFIER_POINTER (fname),
7164 strlen (IDENTIFIER_POINTER (fname)));
7165 obstack_1grow (&util_obstack, '"');
7167 encode_field_decl (fields, curtype, format);
7170 /* Close parenth/bracket. */
7171 obstack_1grow (&util_obstack, right);
7175 encode_aggregate (tree type, int curtype, int format)
7177 enum tree_code code = TREE_CODE (type);
7183 encode_aggregate_within (type, curtype, format, '{', '}');
7188 encode_aggregate_within (type, curtype, format, '(', ')');
7193 obstack_1grow (&util_obstack, 'i');
7201 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
7205 encode_next_bitfield (int width)
7208 sprintf (buffer, "b%d", width);
7209 obstack_grow (&util_obstack, buffer, strlen (buffer));
7212 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
7214 encode_type (tree type, int curtype, int format)
7216 enum tree_code code = TREE_CODE (type);
7219 if (TYPE_READONLY (type))
7220 obstack_1grow (&util_obstack, 'r');
7222 if (code == INTEGER_TYPE)
7224 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
7226 case 8: c = TYPE_UNSIGNED (type) ? 'C' : 'c'; break;
7227 case 16: c = TYPE_UNSIGNED (type) ? 'S' : 's'; break;
7229 if (type == long_unsigned_type_node
7230 || type == long_integer_type_node)
7231 c = TYPE_UNSIGNED (type) ? 'L' : 'l';
7233 c = TYPE_UNSIGNED (type) ? 'I' : 'i';
7235 case 64: c = TYPE_UNSIGNED (type) ? 'Q' : 'q'; break;
7238 obstack_1grow (&util_obstack, c);
7241 else if (code == REAL_TYPE)
7243 /* Floating point types. */
7244 switch (GET_MODE_BITSIZE (TYPE_MODE (type)))
7246 case 32: c = 'f'; break;
7248 case 128: c = 'd'; break;
7251 obstack_1grow (&util_obstack, c);
7254 else if (code == VOID_TYPE)
7255 obstack_1grow (&util_obstack, 'v');
7257 else if (code == BOOLEAN_TYPE)
7258 obstack_1grow (&util_obstack, 'B');
7260 else if (code == ARRAY_TYPE)
7261 encode_array (type, curtype, format);
7263 else if (code == POINTER_TYPE)
7264 encode_pointer (type, curtype, format);
7266 else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE)
7267 encode_aggregate (type, curtype, format);
7269 else if (code == FUNCTION_TYPE) /* '?' */
7270 obstack_1grow (&util_obstack, '?');
7274 encode_gnu_bitfield (int position, tree type, int size)
7276 enum tree_code code = TREE_CODE (type);
7278 char charType = '?';
7280 if (code == INTEGER_TYPE)
7282 if (integer_zerop (TYPE_MIN_VALUE (type)))
7284 /* Unsigned integer types. */
7286 if (TYPE_MODE (type) == QImode)
7288 else if (TYPE_MODE (type) == HImode)
7290 else if (TYPE_MODE (type) == SImode)
7292 if (type == long_unsigned_type_node)
7297 else if (TYPE_MODE (type) == DImode)
7302 /* Signed integer types. */
7304 if (TYPE_MODE (type) == QImode)
7306 else if (TYPE_MODE (type) == HImode)
7308 else if (TYPE_MODE (type) == SImode)
7310 if (type == long_integer_type_node)
7316 else if (TYPE_MODE (type) == DImode)
7320 else if (code == ENUMERAL_TYPE)
7325 sprintf (buffer, "b%d%c%d", position, charType, size);
7326 obstack_grow (&util_obstack, buffer, strlen (buffer));
7330 encode_field_decl (tree field_decl, int curtype, int format)
7335 /* C++ static members, and things that are not fields at all,
7336 should not appear in the encoding. */
7337 if (TREE_CODE (field_decl) != FIELD_DECL || TREE_STATIC (field_decl))
7341 type = TREE_TYPE (field_decl);
7343 /* Generate the bitfield typing information, if needed. Note the difference
7344 between GNU and NeXT runtimes. */
7345 if (DECL_BIT_FIELD_TYPE (field_decl))
7347 int size = tree_low_cst (DECL_SIZE (field_decl), 1);
7349 if (flag_next_runtime)
7350 encode_next_bitfield (size);
7352 encode_gnu_bitfield (int_bit_position (field_decl),
7353 DECL_BIT_FIELD_TYPE (field_decl), size);
7356 encode_type (TREE_TYPE (field_decl), curtype, format);
7359 static GTY(()) tree objc_parmlist = NULL_TREE;
7361 /* Append PARM to a list of formal parameters of a method, making a necessary
7362 array-to-pointer adjustment along the way. */
7365 objc_push_parm (tree parm)
7367 /* Convert array parameters of unknown size into pointers. */
7368 if (TREE_CODE (TREE_TYPE (parm)) == ARRAY_TYPE
7369 && !TYPE_SIZE (TREE_TYPE (parm)))
7370 TREE_TYPE (parm) = build_pointer_type (TREE_TYPE (TREE_TYPE (parm)));
7372 objc_parmlist = chainon (objc_parmlist, parm);
7375 /* Retrieve the formal parameter list constructed via preceding calls to
7376 objc_push_parm(). */
7380 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED)
7382 static struct c_arg_info *
7383 objc_get_parm_info (int have_ellipsis)
7387 tree parm_info = objc_parmlist;
7388 objc_parmlist = NULL_TREE;
7392 tree parm_info = objc_parmlist;
7393 struct c_arg_info *arg_info;
7394 /* The C front-end requires an elaborate song and dance at
7397 declare_parm_level ();
7400 tree next = TREE_CHAIN (parm_info);
7402 TREE_CHAIN (parm_info) = NULL_TREE;
7403 pushdecl (parm_info);
7406 arg_info = get_parm_info (have_ellipsis);
7408 objc_parmlist = NULL_TREE;
7413 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
7414 method definitions. In the case of instance methods, we can be more
7415 specific as to the type of 'self'. */
7418 synth_self_and_ucmd_args (void)
7422 if (objc_method_context
7423 && TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL)
7424 self_type = objc_instance_type;
7426 /* Really a `struct objc_class *'. However, we allow people to
7427 assign to self, which changes its type midstream. */
7428 self_type = objc_object_type;
7431 objc_push_parm (build_decl (PARM_DECL, self_id, self_type));
7434 objc_push_parm (build_decl (PARM_DECL, ucmd_id, objc_selector_type));
7437 /* Transform an Objective-C method definition into a static C function
7438 definition, synthesizing the first two arguments, "self" and "_cmd",
7442 start_method_def (tree method)
7448 struct c_arg_info *parm_info;
7450 int have_ellipsis = 0;
7452 /* Required to implement _msgSuper. */
7453 objc_method_context = method;
7454 UOBJC_SUPER_decl = NULL_TREE;
7456 /* Generate prototype declarations for arguments..."new-style". */
7457 synth_self_and_ucmd_args ();
7459 /* Generate argument declarations if a keyword_decl. */
7460 parmlist = METHOD_SEL_ARGS (method);
7463 tree parm = build_decl (PARM_DECL, KEYWORD_ARG_NAME (parmlist),
7464 TREE_VALUE (TREE_TYPE (parmlist)));
7466 objc_push_parm (parm);
7467 parmlist = TREE_CHAIN (parmlist);
7470 if (METHOD_ADD_ARGS (method))
7474 for (akey = TREE_CHAIN (METHOD_ADD_ARGS (method));
7475 akey; akey = TREE_CHAIN (akey))
7477 objc_push_parm (TREE_VALUE (akey));
7480 if (TREE_OVERFLOW (METHOD_ADD_ARGS (method)))
7484 parm_info = objc_get_parm_info (have_ellipsis);
7486 really_start_method (objc_method_context, parm_info);
7490 warn_with_method (const char *message, int mtype, tree method)
7492 /* Add a readable method name to the warning. */
7493 warning ("%J%s `%c%s'", method,
7494 message, mtype, gen_method_decl (method));
7497 /* Return 1 if TYPE1 is equivalent to TYPE2
7498 for purposes of method overloading. */
7501 objc_types_are_equivalent (tree type1, tree type2)
7506 /* Strip away indirections. */
7507 while ((TREE_CODE (type1) == ARRAY_TYPE || TREE_CODE (type1) == POINTER_TYPE)
7508 && (TREE_CODE (type1) == TREE_CODE (type2)))
7509 type1 = TREE_TYPE (type1), type2 = TREE_TYPE (type2);
7510 if (TYPE_MAIN_VARIANT (type1) != TYPE_MAIN_VARIANT (type2))
7513 type1 = TYPE_PROTOCOL_LIST (type1);
7514 type2 = TYPE_PROTOCOL_LIST (type2);
7515 if (list_length (type1) == list_length (type2))
7517 for (; type2; type2 = TREE_CHAIN (type2))
7518 if (!lookup_protocol_in_reflist (type1, TREE_VALUE (type2)))
7525 /* Return 1 if PROTO1 is equivalent to PROTO2
7526 for purposes of method overloading. */
7529 comp_proto_with_proto (tree proto1, tree proto2)
7533 /* The following test is needed in case there are hashing
7535 if (METHOD_SEL_NAME (proto1) != METHOD_SEL_NAME (proto2))
7538 /* Compare return types. */
7539 type1 = TREE_VALUE (TREE_TYPE (proto1));
7540 type2 = TREE_VALUE (TREE_TYPE (proto2));
7542 if (!objc_types_are_equivalent (type1, type2))
7545 /* Compare argument types. */
7546 for (type1 = get_arg_type_list (proto1, METHOD_REF, 0),
7547 type2 = get_arg_type_list (proto2, METHOD_REF, 0);
7549 type1 = TREE_CHAIN (type1), type2 = TREE_CHAIN (type2))
7551 if (!objc_types_are_equivalent (TREE_VALUE (type1), TREE_VALUE (type2)))
7555 return (!type1 && !type2);
7558 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
7559 this occurs. ObjC method dispatches are _not_ like C++ virtual
7560 member function dispatches, and we account for the difference here. */
7563 objc_fold_obj_type_ref (tree ref, tree known_type)
7565 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED,
7566 tree known_type ATTRIBUTE_UNUSED)
7570 tree v = BINFO_VIRTUALS (TYPE_BINFO (known_type));
7572 /* If the receiver does not have virtual member functions, there
7573 is nothing we can (or need to) do here. */
7577 /* Let C++ handle C++ virtual functions. */
7578 return cp_fold_obj_type_ref (ref, known_type);
7580 /* For plain ObjC, we currently do not need to do anything. */
7586 objc_start_function (tree name, tree type, tree attrs,
7590 struct c_arg_info *params
7594 tree fndecl = build_decl (FUNCTION_DECL, name, type);
7597 DECL_ARGUMENTS (fndecl) = params;
7599 DECL_INITIAL (fndecl) = error_mark_node;
7600 DECL_EXTERNAL (fndecl) = 0;
7601 TREE_STATIC (fndecl) = 1;
7604 retrofit_lang_decl (fndecl);
7605 cplus_decl_attributes (&fndecl, attrs, 0);
7606 start_preparsed_function (fndecl, attrs, /*flags=*/SF_DEFAULT);
7608 decl_attributes (&fndecl, attrs, 0);
7609 announce_function (fndecl);
7610 current_function_decl = pushdecl (fndecl);
7612 declare_parm_level ();
7613 DECL_RESULT (current_function_decl)
7614 = build_decl (RESULT_DECL, NULL_TREE,
7615 TREE_TYPE (TREE_TYPE (current_function_decl)));
7616 start_fname_decls ();
7617 store_parm_decls_from (params);
7620 TREE_USED (current_function_decl) = 1;
7623 /* - Generate an identifier for the function. the format is "_n_cls",
7624 where 1 <= n <= nMethods, and cls is the name the implementation we
7626 - Install the return type from the method declaration.
7627 - If we have a prototype, check for type consistency. */
7630 really_start_method (tree method,
7634 struct c_arg_info *parmlist
7638 tree ret_type, meth_type;
7640 const char *sel_name, *class_name, *cat_name;
7643 /* Synth the storage class & assemble the return type. */
7644 ret_type = TREE_VALUE (TREE_TYPE (method));
7646 sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method));
7647 class_name = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context));
7648 cat_name = ((TREE_CODE (objc_implementation_context)
7649 == CLASS_IMPLEMENTATION_TYPE)
7651 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context)));
7654 /* Make sure this is big enough for any plausible method label. */
7655 buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name)
7656 + (cat_name ? strlen (cat_name) : 0));
7658 OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL,
7659 class_name, cat_name, sel_name, method_slot);
7661 method_id = get_identifier (buf);
7664 /* Objective-C methods cannot be overloaded, so we don't need
7665 the type encoding appended. It looks bad anyway... */
7666 push_lang_context (lang_name_c);
7670 = build_function_type (ret_type,
7671 get_arg_type_list (method, METHOD_DEF, 0));
7672 objc_start_function (method_id, meth_type, NULL_TREE, parmlist);
7674 /* Set self_decl from the first argument. */
7675 self_decl = DECL_ARGUMENTS (current_function_decl);
7677 /* Suppress unused warnings. */
7678 TREE_USED (self_decl) = 1;
7679 TREE_USED (TREE_CHAIN (self_decl)) = 1;
7681 pop_lang_context ();
7684 METHOD_DEFINITION (method) = current_function_decl;
7686 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7688 if (implementation_template != objc_implementation_context)
7691 = lookup_method_static (implementation_template,
7692 METHOD_SEL_NAME (method),
7693 TREE_CODE (method) == CLASS_METHOD_DECL);
7697 if (!comp_proto_with_proto (method, proto))
7699 char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+');
7701 warn_with_method ("conflicting types for", type, method);
7702 warn_with_method ("previous declaration of", type, proto);
7707 /* We have a method @implementation even though we did not
7708 see a corresponding @interface declaration (which is allowed
7709 by Objective-C rules). Go ahead and place the method in
7710 the @interface anyway, so that message dispatch lookups
7712 tree interface = implementation_template;
7714 if (TREE_CODE (objc_implementation_context)
7715 == CATEGORY_IMPLEMENTATION_TYPE)
7716 interface = lookup_category
7718 CLASS_SUPER_NAME (objc_implementation_context));
7721 objc_add_method (interface, copy_node (method),
7722 TREE_CODE (method) == CLASS_METHOD_DECL);
7727 static void *UOBJC_SUPER_scope = 0;
7729 /* _n_Method (id self, SEL sel, ...)
7731 struct objc_super _S;
7732 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7736 get_super_receiver (void)
7738 if (objc_method_context)
7740 tree super_expr, super_expr_list;
7742 if (!UOBJC_SUPER_decl)
7744 UOBJC_SUPER_decl = build_decl (VAR_DECL, get_identifier (TAG_SUPER),
7745 objc_super_template);
7746 /* This prevents `unused variable' warnings when compiling with -Wall. */
7747 TREE_USED (UOBJC_SUPER_decl) = 1;
7748 lang_hooks.decls.pushdecl (UOBJC_SUPER_decl);
7749 finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE);
7750 UOBJC_SUPER_scope = objc_get_current_scope ();
7753 /* Set receiver to self. */
7754 super_expr = build_component_ref (UOBJC_SUPER_decl, self_id);
7755 super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl);
7756 super_expr_list = super_expr;
7758 /* Set class to begin searching. */
7759 super_expr = build_component_ref (UOBJC_SUPER_decl,
7760 get_identifier ("super_class"));
7762 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
7764 /* [_cls, __cls]Super are "pre-built" in
7765 synth_forward_declarations. */
7767 super_expr = build_modify_expr (super_expr, NOP_EXPR,
7768 ((TREE_CODE (objc_method_context)
7769 == INSTANCE_METHOD_DECL)
7771 : uucls_super_ref));
7775 /* We have a category. */
7777 tree super_name = CLASS_SUPER_NAME (implementation_template);
7780 /* Barf if super used in a category of Object. */
7783 error ("no super class declared in interface for `%s'",
7784 IDENTIFIER_POINTER (CLASS_NAME (implementation_template)));
7785 return error_mark_node;
7788 if (flag_next_runtime && !flag_zero_link)
7790 super_class = objc_get_class_reference (super_name);
7791 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL)
7792 /* If we are in a class method, we must retrieve the
7793 _metaclass_ for the current class, pointed at by
7794 the class's "isa" pointer. The following assumes that
7795 "isa" is the first ivar in a class (which it must be). */
7797 = build_indirect_ref
7798 (build_c_cast (build_pointer_type (objc_class_type),
7799 super_class), "unary *");
7803 add_class_reference (super_name);
7804 super_class = (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
7805 ? objc_get_class_decl : objc_get_meta_class_decl);
7806 assemble_external (super_class);
7808 = build_function_call
7812 my_build_string (IDENTIFIER_LENGTH (super_name) + 1,
7813 IDENTIFIER_POINTER (super_name))));
7817 = build_modify_expr (super_expr, NOP_EXPR,
7818 build_c_cast (TREE_TYPE (super_expr),
7822 super_expr_list = build_compound_expr (super_expr_list, super_expr);
7824 super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0);
7825 super_expr_list = build_compound_expr (super_expr_list, super_expr);
7827 return super_expr_list;
7831 error ("[super ...] must appear in a method context");
7832 return error_mark_node;
7836 /* When exiting a scope, sever links to a 'super' declaration (if any)
7837 therein contained. */
7840 objc_clear_super_receiver (void)
7842 if (objc_method_context
7843 && UOBJC_SUPER_scope == objc_get_current_scope ()) {
7844 UOBJC_SUPER_decl = 0;
7845 UOBJC_SUPER_scope = 0;
7850 objc_finish_method_definition (tree fndecl)
7852 /* We cannot validly inline ObjC methods, at least not without a language
7853 extension to declare that a method need not be dynamically
7854 dispatched, so suppress all thoughts of doing so. */
7855 DECL_INLINE (fndecl) = 0;
7856 DECL_UNINLINABLE (fndecl) = 1;
7859 /* The C++ front-end will have called finish_function() for us. */
7863 METHOD_ENCODING (objc_method_context)
7864 = encode_method_prototype (objc_method_context);
7866 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7867 since the optimizer may find "may be used before set" errors. */
7868 objc_method_context = NULL_TREE;
7873 lang_report_error_function (tree decl)
7875 if (objc_method_context)
7877 fprintf (stderr, "In method `%s'\n",
7878 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context)));
7887 /* Given a tree DECL node, produce a printable description of it in the given
7888 buffer, overwriting the buffer. */
7891 gen_declaration (tree decl)
7897 gen_type_name_0 (TREE_TYPE (decl));
7899 if (DECL_NAME (decl))
7901 if (!POINTER_TYPE_P (TREE_TYPE (decl)))
7902 strcat (errbuf, " ");
7904 strcat (errbuf, IDENTIFIER_POINTER (DECL_NAME (decl)));
7907 if (DECL_INITIAL (decl)
7908 && TREE_CODE (DECL_INITIAL (decl)) == INTEGER_CST)
7909 sprintf (errbuf + strlen (errbuf), ": " HOST_WIDE_INT_PRINT_DEC,
7910 TREE_INT_CST_LOW (DECL_INITIAL (decl)));
7916 /* Given a tree TYPE node, produce a printable description of it in the given
7917 buffer, overwriting the buffer. */
7920 gen_type_name_0 (tree type)
7922 tree orig = type, proto;
7924 if (TYPE_P (type) && TYPE_NAME (type))
7925 type = TYPE_NAME (type);
7926 else if (POINTER_TYPE_P (type))
7928 gen_type_name_0 (TREE_TYPE (type));
7930 if (!POINTER_TYPE_P (TREE_TYPE (type)))
7931 strcat (errbuf, " ");
7933 strcat (errbuf, "*");
7937 if (TREE_CODE (type) == TYPE_DECL && DECL_NAME (type))
7938 type = DECL_NAME (type);
7940 strcat (errbuf, IDENTIFIER_POINTER (type));
7941 proto = TYPE_PROTOCOL_LIST (orig);
7945 strcat (errbuf, " <");
7949 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto))));
7950 proto = TREE_CHAIN (proto);
7951 strcat (errbuf, proto ? ", " : ">");
7960 gen_type_name (tree type)
7964 return gen_type_name_0 (type);
7967 /* Given a method tree, put a printable description into the given
7968 buffer (overwriting) and return a pointer to the buffer. */
7971 gen_method_decl (tree method)
7975 strcpy (errbuf, "("); /* NB: Do _not_ call strcat() here. */
7976 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method)));
7977 strcat (errbuf, ")");
7978 chain = METHOD_SEL_ARGS (method);
7982 /* We have a chain of keyword_decls. */
7985 if (KEYWORD_KEY_NAME (chain))
7986 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain)));
7988 strcat (errbuf, ":(");
7989 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain)));
7990 strcat (errbuf, ")");
7992 strcat (errbuf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain)));
7993 if ((chain = TREE_CHAIN (chain)))
7994 strcat (errbuf, " ");
7998 if (METHOD_ADD_ARGS (method))
8000 chain = TREE_CHAIN (METHOD_ADD_ARGS (method));
8002 /* Know we have a chain of parm_decls. */
8005 strcat (errbuf, ", ");
8006 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain)));
8007 chain = TREE_CHAIN (chain);
8010 if (TREE_OVERFLOW (METHOD_ADD_ARGS (method)))
8011 strcat (errbuf, ", ...");
8016 /* We have a unary selector. */
8017 strcat (errbuf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method)));
8025 /* Dump an @interface declaration of the supplied class CHAIN to the
8026 supplied file FP. Used to implement the -gen-decls option (which
8027 prints out an @interface declaration of all classes compiled in
8028 this run); potentially useful for debugging the compiler too. */
8030 dump_interface (FILE *fp, tree chain)
8032 /* FIXME: A heap overflow here whenever a method (or ivar)
8033 declaration is so long that it doesn't fit in the buffer. The
8034 code and all the related functions should be rewritten to avoid
8035 using fixed size buffers. */
8036 const char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain));
8037 tree ivar_decls = CLASS_RAW_IVARS (chain);
8038 tree nst_methods = CLASS_NST_METHODS (chain);
8039 tree cls_methods = CLASS_CLS_METHODS (chain);
8041 fprintf (fp, "\n@interface %s", my_name);
8043 /* CLASS_SUPER_NAME is used to store the superclass name for
8044 classes, and the category name for categories. */
8045 if (CLASS_SUPER_NAME (chain))
8047 const char *name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain));
8049 if (TREE_CODE (chain) == CATEGORY_IMPLEMENTATION_TYPE
8050 || TREE_CODE (chain) == CATEGORY_INTERFACE_TYPE)
8052 fprintf (fp, " (%s)\n", name);
8056 fprintf (fp, " : %s\n", name);
8062 /* FIXME - the following doesn't seem to work at the moment. */
8065 fprintf (fp, "{\n");
8068 fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls));
8069 ivar_decls = TREE_CHAIN (ivar_decls);
8072 fprintf (fp, "}\n");
8077 fprintf (fp, "- %s;\n", gen_method_decl (nst_methods));
8078 nst_methods = TREE_CHAIN (nst_methods);
8083 fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods));
8084 cls_methods = TREE_CHAIN (cls_methods);
8087 fprintf (fp, "@end\n");
8090 /* Demangle function for Objective-C */
8092 objc_demangle (const char *mangled)
8094 char *demangled, *cp;
8096 if (mangled[0] == '_' &&
8097 (mangled[1] == 'i' || mangled[1] == 'c') &&
8100 cp = demangled = xmalloc(strlen(mangled) + 2);
8101 if (mangled[1] == 'i')
8102 *cp++ = '-'; /* for instance method */
8104 *cp++ = '+'; /* for class method */
8105 *cp++ = '['; /* opening left brace */
8106 strcpy(cp, mangled+3); /* tack on the rest of the mangled name */
8107 while (*cp && *cp == '_')
8108 cp++; /* skip any initial underbars in class name */
8109 cp = strchr(cp, '_'); /* find first non-initial underbar */
8112 free(demangled); /* not mangled name */
8115 if (cp[1] == '_') /* easy case: no category name */
8117 *cp++ = ' '; /* replace two '_' with one ' ' */
8118 strcpy(cp, mangled + (cp - demangled) + 2);
8122 *cp++ = '('; /* less easy case: category name */
8123 cp = strchr(cp, '_');
8126 free(demangled); /* not mangled name */
8130 *cp++ = ' '; /* overwriting 1st char of method name... */
8131 strcpy(cp, mangled + (cp - demangled)); /* get it back */
8133 while (*cp && *cp == '_')
8134 cp++; /* skip any initial underbars in method name */
8137 *cp = ':'; /* replace remaining '_' with ':' */
8138 *cp++ = ']'; /* closing right brace */
8139 *cp++ = 0; /* string terminator */
8143 return mangled; /* not an objc mangled name */
8147 objc_printable_name (tree decl, int kind ATTRIBUTE_UNUSED)
8149 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl)));
8155 gcc_obstack_init (&util_obstack);
8156 util_firstobj = (char *) obstack_finish (&util_obstack);
8158 errbuf = (char *) xmalloc (1024 * 10);
8160 synth_module_prologue ();
8166 struct imp_entry *impent;
8168 /* The internally generated initializers appear to have missing braces.
8169 Don't warn about this. */
8170 int save_warn_missing_braces = warn_missing_braces;
8171 warn_missing_braces = 0;
8173 /* A missing @end may not be detected by the parser. */
8174 if (objc_implementation_context)
8176 warning ("`@end' missing in implementation context");
8177 finish_class (objc_implementation_context);
8178 objc_ivar_chain = NULL_TREE;
8179 objc_implementation_context = NULL_TREE;
8182 /* Process the static instances here because initialization of objc_symtab
8184 if (objc_static_instances)
8185 generate_static_references ();
8187 if (imp_list || class_names_chain
8188 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8189 generate_objc_symtab_decl ();
8191 for (impent = imp_list; impent; impent = impent->next)
8193 objc_implementation_context = impent->imp_context;
8194 implementation_template = impent->imp_template;
8196 UOBJC_CLASS_decl = impent->class_decl;
8197 UOBJC_METACLASS_decl = impent->meta_decl;
8199 /* Dump the @interface of each class as we compile it, if the
8200 -gen-decls option is in use. TODO: Dump the classes in the
8201 order they were found, rather than in reverse order as we
8203 if (flag_gen_declaration)
8205 dump_interface (gen_declaration_file, objc_implementation_context);
8208 if (TREE_CODE (objc_implementation_context) == CLASS_IMPLEMENTATION_TYPE)
8210 /* all of the following reference the string pool... */
8211 generate_ivar_lists ();
8212 generate_dispatch_tables ();
8213 generate_shared_structures ();
8217 generate_dispatch_tables ();
8218 generate_category (objc_implementation_context);
8222 /* If we are using an array of selectors, we must always
8223 finish up the array decl even if no selectors were used. */
8224 if (! flag_next_runtime || sel_ref_chain)
8225 build_selector_translation_table ();
8228 generate_protocols ();
8230 if (flag_replace_objc_classes && imp_list)
8231 generate_objc_image_info ();
8233 /* Arrange for ObjC data structures to be initialized at run time. */
8234 if (objc_implementation_context || class_names_chain || objc_static_instances
8235 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
8237 build_module_descriptor ();
8239 if (!flag_next_runtime)
8240 build_module_initializer_routine ();
8243 /* Dump the class references. This forces the appropriate classes
8244 to be linked into the executable image, preserving unix archive
8245 semantics. This can be removed when we move to a more dynamically
8246 linked environment. */
8248 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
8250 handle_class_ref (chain);
8251 if (TREE_PURPOSE (chain))
8252 generate_classref_translation_entry (chain);
8255 for (impent = imp_list; impent; impent = impent->next)
8256 handle_impent (impent);
8258 /* Dump the string table last. */
8260 generate_strings ();
8267 /* Run through the selector hash tables and print a warning for any
8268 selector which has multiple methods. */
8270 for (slot = 0; slot < SIZEHASHTABLE; slot++)
8272 for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next)
8273 check_duplicates (hsh, 0, 1);
8274 for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next)
8275 check_duplicates (hsh, 0, 1);
8279 warn_missing_braces = save_warn_missing_braces;
8282 /* Subroutines of finish_objc. */
8285 generate_classref_translation_entry (tree chain)
8287 tree expr, decl, type;
8289 decl = TREE_PURPOSE (chain);
8290 type = TREE_TYPE (decl);
8292 expr = add_objc_string (TREE_VALUE (chain), class_names);
8293 expr = convert (type, expr); /* cast! */
8295 /* The decl that is the one that we
8296 forward declared in build_class_reference. */
8297 finish_var_decl (decl, expr);
8302 handle_class_ref (tree chain)
8304 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
8305 char *string = (char *) alloca (strlen (name) + 30);
8309 sprintf (string, "%sobjc_class_name_%s",
8310 (flag_next_runtime ? "." : "__"), name);
8312 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8313 if (flag_next_runtime)
8315 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file, string);
8320 /* Make a decl for this name, so we can use its address in a tree. */
8321 decl = build_decl (VAR_DECL, get_identifier (string), char_type_node);
8322 DECL_EXTERNAL (decl) = 1;
8323 TREE_PUBLIC (decl) = 1;
8326 rest_of_decl_compilation (decl, 0, 0);
8328 /* Make a decl for the address. */
8329 sprintf (string, "%sobjc_class_ref_%s",
8330 (flag_next_runtime ? "." : "__"), name);
8331 exp = build1 (ADDR_EXPR, string_type_node, decl);
8332 decl = build_decl (VAR_DECL, get_identifier (string), string_type_node);
8333 DECL_INITIAL (decl) = exp;
8334 TREE_STATIC (decl) = 1;
8335 TREE_USED (decl) = 1;
8338 rest_of_decl_compilation (decl, 0, 0);
8342 handle_impent (struct imp_entry *impent)
8346 objc_implementation_context = impent->imp_context;
8347 implementation_template = impent->imp_template;
8349 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
8351 const char *const class_name =
8352 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8354 string = (char *) alloca (strlen (class_name) + 30);
8356 sprintf (string, "%sobjc_class_name_%s",
8357 (flag_next_runtime ? "." : "__"), class_name);
8359 else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
8361 const char *const class_name =
8362 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
8363 const char *const class_super_name =
8364 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
8366 string = (char *) alloca (strlen (class_name)
8367 + strlen (class_super_name) + 30);
8369 /* Do the same for categories. Even though no references to
8370 these symbols are generated automatically by the compiler, it
8371 gives you a handle to pull them into an archive by hand. */
8372 sprintf (string, "*%sobjc_category_name_%s_%s",
8373 (flag_next_runtime ? "." : "__"), class_name, class_super_name);
8378 #ifdef ASM_DECLARE_CLASS_REFERENCE
8379 if (flag_next_runtime)
8381 ASM_DECLARE_CLASS_REFERENCE (asm_out_file, string);
8389 init = build_int_cst (c_common_type_for_size (BITS_PER_WORD, 1), 0);
8390 decl = build_decl (VAR_DECL, get_identifier (string), TREE_TYPE (init));
8391 TREE_PUBLIC (decl) = 1;
8392 TREE_READONLY (decl) = 1;
8393 TREE_USED (decl) = 1;
8394 TREE_CONSTANT (decl) = 1;
8395 DECL_CONTEXT (decl) = 0;
8396 DECL_ARTIFICIAL (decl) = 1;
8397 DECL_INITIAL (decl) = init;
8398 assemble_variable (decl, 1, 0, 0);
8402 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
8403 later requires that ObjC translation units participating in F&C be
8404 specially marked. The following routine accomplishes this. */
8406 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
8409 generate_objc_image_info (void)
8411 tree decl, initlist;
8413 decl = start_var_decl (build_array_type
8415 build_index_type (build_int_cst (NULL_TREE, 2 - 1))),
8416 "_OBJC_IMAGE_INFO");
8418 initlist = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, 0));
8419 initlist = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, 1), initlist);
8420 initlist = objc_build_constructor (TREE_TYPE (decl), nreverse (initlist));
8422 finish_var_decl (decl, initlist);
8425 /* Look up ID as an instance variable. OTHER contains the result of
8426 the C or C++ lookup, which we may want to use instead. */
8429 objc_lookup_ivar (tree other, tree id)
8433 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */
8434 if (!objc_method_context)
8437 if (!strcmp (IDENTIFIER_POINTER (id), "super"))
8438 /* We have a message to super. */
8439 return get_super_receiver ();
8441 /* In a class method, look up an instance variable only as a last
8443 if (TREE_CODE (objc_method_context) == CLASS_METHOD_DECL
8444 && other && other != error_mark_node)
8447 /* Look up the ivar, but do not use it if it is not accessible. */
8448 ivar = is_ivar (objc_ivar_chain, id);
8450 if (!ivar || is_private (ivar))
8453 /* In an instance method, a local variable (or parameter) may hide the
8454 instance variable. */
8455 if (TREE_CODE (objc_method_context) == INSTANCE_METHOD_DECL
8456 && other && other != error_mark_node && !DECL_FILE_SCOPE_P (other))
8458 warning ("local declaration of %qs hides instance variable",
8459 IDENTIFIER_POINTER (id));
8464 /* At this point, we are either in an instance method with no obscuring
8465 local definitions, or in a class method with no alternate definitions
8467 return build_ivar_reference (id);
8470 #include "gt-objc-objc-act.h"