1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* Purpose: This module implements the Objective-C 4.0 language.
25 compatibility issues (with the Stepstone translator):
27 - does not recognize the following 3.3 constructs.
28 @requires, @classes, @messages, = (...)
29 - methods with variable arguments must conform to ANSI standard.
30 - tagged structure definitions that appear in BOTH the interface
31 and implementation are not allowed.
32 - public/private: all instance variables are public within the
33 context of the implementation...I consider this to be a bug in
35 - statically allocated objects are not supported. the user will
36 receive an error if this service is requested.
38 code generation `options':
44 #include "coretypes.h"
60 #include "langhooks.h"
71 #include "diagnostic.h"
73 #include "tree-iterator.h"
77 #define OBJC_VOID_AT_END void_list_node
79 /* When building Objective-C++, we are not linking against the C front-end
80 and so need to replicate the C tree-construction functions in some way. */
82 #define OBJCP_REMAP_FUNCTIONS
83 #include "objcp-decl.h"
86 /* This is the default way of generating a method name. */
87 /* I am not sure it is really correct.
88 Perhaps there's a danger that it will make name conflicts
89 if method names contain underscores. -- rms. */
90 #ifndef OBJC_GEN_METHOD_LABEL
91 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
94 sprintf ((BUF), "_%s_%s_%s_%s", \
95 ((IS_INST) ? "i" : "c"), \
97 ((CAT_NAME)? (CAT_NAME) : ""), \
99 for (temp = (BUF); *temp; temp++) \
100 if (*temp == ':') *temp = '_'; \
104 /* These need specifying. */
105 #ifndef OBJC_FORWARDING_STACK_OFFSET
106 #define OBJC_FORWARDING_STACK_OFFSET 0
109 #ifndef OBJC_FORWARDING_MIN_OFFSET
110 #define OBJC_FORWARDING_MIN_OFFSET 0
113 /* Set up for use of obstacks. */
117 /* This obstack is used to accumulate the encoding of a data type. */
118 static struct obstack util_obstack
;
120 /* This points to the beginning of obstack contents, so we can free
121 the whole contents. */
124 /* The version identifies which language generation and runtime
125 the module (file) was compiled for, and is recorded in the
126 module descriptor. */
128 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
129 #define PROTOCOL_VERSION 2
131 /* (Decide if these can ever be validly changed.) */
132 #define OBJC_ENCODE_INLINE_DEFS 0
133 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
135 /*** Private Interface (procedures) ***/
137 /* Used by compile_file. */
139 static void init_objc (void);
140 static void finish_objc (void);
142 /* Code generation. */
144 static void synth_module_prologue (void);
145 static tree
objc_build_constructor (tree
, tree
);
146 static void build_module_descriptor (void);
147 static void build_module_initializer_routine (void);
148 static tree
init_module_descriptor (tree
);
149 static tree
build_objc_method_call (int, tree
, tree
, tree
, tree
);
150 static void generate_strings (void);
151 static tree
get_proto_encoding (tree
);
152 static void build_selector_translation_table (void);
153 static tree
lookup_interface (tree
);
154 static tree
objc_add_static_instance (tree
, tree
);
156 static tree
start_class (enum tree_code
, tree
, tree
, tree
);
157 static tree
continue_class (tree
);
158 static void finish_class (tree
);
159 static void start_method_def (tree
);
161 static void objc_start_function (tree
, tree
, tree
, tree
);
163 static void objc_start_function (tree
, tree
, tree
, struct c_arg_info
*);
165 static tree
start_protocol (enum tree_code
, tree
, tree
);
166 static tree
build_method_decl (enum tree_code
, tree
, tree
, tree
);
167 static tree
objc_add_method (tree
, tree
, int);
168 static tree
add_instance_variable (tree
, int, tree
);
169 static tree
build_ivar_reference (tree
);
170 static tree
is_ivar (tree
, tree
);
171 static int is_private (tree
);
172 static tree
get_super_receiver (void);
174 static void build_objc_exception_stuff (void);
175 static void build_next_objc_exception_stuff (void);
177 static tree
build_ivar_template (void);
178 static tree
build_method_template (void);
179 static void build_private_template (tree
);
180 static void build_class_template (void);
181 static void build_selector_template (void);
182 static void build_category_template (void);
183 static tree
lookup_method_in_hash_lists (tree
, int);
184 static void build_super_template (void);
185 static tree
build_category_initializer (tree
, tree
, tree
, tree
, tree
, tree
);
186 static tree
build_protocol_initializer (tree
, tree
, tree
, tree
, tree
);
187 static void synth_forward_declarations (void);
188 static int ivar_list_length (tree
);
189 static tree
get_class_ivars (tree
);
190 static void generate_ivar_lists (void);
191 static void generate_dispatch_tables (void);
192 static void generate_shared_structures (void);
193 static tree
generate_protocol_list (tree
);
194 static void build_protocol_reference (tree
);
196 static tree
build_keyword_selector (tree
);
197 static const char *synth_id_with_class_suffix (const char *, tree
);
199 static void generate_static_references (void);
200 static int check_methods_accessible (tree
, tree
, int);
201 static void encode_aggregate_within (tree
, int, int, int, int);
202 static const char *objc_demangle (const char *);
204 /* Hash tables to manage the global pool of method prototypes. */
206 hash
*nst_method_hash_list
= 0;
207 hash
*cls_method_hash_list
= 0;
209 static size_t hash_func (tree
);
210 static void hash_init (void);
211 static void hash_enter (hash
*, tree
);
212 static hash
hash_lookup (hash
*, tree
);
213 static void hash_add_attr (hash
, tree
);
214 static tree
lookup_method (tree
, tree
);
215 static tree
lookup_method_static (tree
, tree
, int);
216 static void add_method_to_hash_list (hash
*, tree
);
217 static tree
add_class (tree
);
218 static void add_category (tree
, tree
);
219 static inline tree
lookup_category (tree
, tree
);
223 class_names
, /* class, category, protocol, module names */
224 meth_var_names
, /* method and variable names */
225 meth_var_types
/* method and variable type descriptors */
228 static tree
add_objc_string (tree
, enum string_section
);
229 static tree
get_objc_string_decl (tree
, enum string_section
);
230 static tree
build_objc_string_decl (enum string_section
);
231 static tree
build_selector_reference_decl (void);
232 static void build_selector_table_decl (void);
234 /* Protocol additions. */
236 static tree
add_protocol (tree
);
237 static tree
lookup_protocol (tree
);
238 static void check_protocol_recursively (tree
, tree
);
239 static tree
lookup_and_install_protocols (tree
);
243 static void encode_type_qualifiers (tree
);
244 static void encode_pointer (tree
, int, int);
245 static void encode_array (tree
, int, int);
246 static void encode_aggregate (tree
, int, int);
247 static void encode_next_bitfield (int);
248 static void encode_gnu_bitfield (int, tree
, int);
249 static void encode_type (tree
, int, int);
250 static void encode_field_decl (tree
, int, int);
253 static void really_start_method (tree
, tree
);
255 static void really_start_method (tree
, struct c_arg_info
*);
257 static int objc_types_are_equivalent (tree
, tree
);
258 static int comp_proto_with_proto (tree
, tree
);
259 static tree
get_arg_type_list (tree
, int, int);
260 static void objc_push_parm (tree
);
262 static tree
objc_get_parm_info (int);
264 static struct c_arg_info
*objc_get_parm_info (int);
266 static void synth_self_and_ucmd_args (void);
268 /* Utilities for debugging and error diagnostics. */
270 static void warn_with_method (const char *, int, tree
);
271 static void error_with_ivar (const char *, tree
);
272 static char *gen_type_name (tree
);
273 static char *gen_type_name_0 (tree
);
274 static char *gen_method_decl (tree
);
275 static char *gen_declaration (tree
);
276 static void dump_interface (FILE *, tree
);
278 /* Everything else. */
280 static tree
lookup_method_in_protocol_list (tree
, tree
, int);
281 static tree
lookup_protocol_in_reflist (tree
, tree
);
282 static tree
start_var_decl (tree
, const char *);
283 static void finish_var_decl (tree
, tree
);
284 static tree
create_field_decl (tree
, const char *);
285 static tree
setup_string_decl (void);
286 static int check_string_class_template (void);
287 static tree
my_build_string (int, const char *);
288 static void build_objc_symtab_template (void);
289 static tree
init_def_list (tree
);
290 static tree
init_objc_symtab (tree
);
291 static tree
build_metadata_decl (const char *, tree
);
292 static void forward_declare_categories (void);
293 static void generate_objc_symtab_decl (void);
294 static tree
build_selector (tree
);
295 static tree
build_typed_selector_reference (tree
, tree
);
296 static tree
build_selector_reference (tree
);
297 static tree
build_class_reference_decl (void);
298 static void add_class_reference (tree
);
299 static void build_protocol_template (void);
300 static tree
build_descriptor_table_initializer (tree
, tree
);
301 static tree
build_method_prototype_list_template (tree
, int);
302 static tree
build_method_prototype_template (void);
303 static tree
objc_method_parm_type (tree
);
304 static int objc_encoded_type_size (tree
);
305 static tree
encode_method_prototype (tree
);
306 static tree
generate_descriptor_table (tree
, const char *, int, tree
, tree
);
307 static void generate_method_descriptors (tree
);
308 static void generate_protocol_references (tree
);
309 static void generate_protocols (void);
310 static void check_ivars (tree
, tree
);
311 static tree
build_ivar_list_template (tree
, int);
312 static tree
build_method_list_template (tree
, int);
313 static tree
build_ivar_list_initializer (tree
, tree
);
314 static tree
generate_ivars_list (tree
, const char *, int, tree
);
315 static tree
build_dispatch_table_initializer (tree
, tree
);
316 static tree
generate_dispatch_table (tree
, const char *, int, tree
);
317 static tree
build_shared_structure_initializer (tree
, tree
, tree
, tree
,
318 tree
, int, tree
, tree
, tree
);
319 static void generate_category (tree
);
320 static tree
adjust_type_for_id_default (tree
);
321 static tree
check_duplicates (hash
, int, int);
322 static tree
receiver_is_class_object (tree
, int, int);
323 static int check_methods (tree
, tree
, int);
324 static int conforms_to_protocol (tree
, tree
);
325 static void check_protocol (tree
, const char *, const char *);
326 static void check_protocols (tree
, const char *, const char *);
327 static void generate_classref_translation_entry (tree
);
328 static void handle_class_ref (tree
);
329 static void generate_struct_by_value_array (void)
331 static void mark_referenced_methods (void);
332 static void generate_objc_image_info (void);
334 /*** Private Interface (data) ***/
336 /* Reserved tag definitions. */
338 #define OBJECT_TYPEDEF_NAME "id"
339 #define CLASS_TYPEDEF_NAME "Class"
341 #define TAG_OBJECT "objc_object"
342 #define TAG_CLASS "objc_class"
343 #define TAG_SUPER "objc_super"
344 #define TAG_SELECTOR "objc_selector"
346 #define UTAG_CLASS "_objc_class"
347 #define UTAG_IVAR "_objc_ivar"
348 #define UTAG_IVAR_LIST "_objc_ivar_list"
349 #define UTAG_METHOD "_objc_method"
350 #define UTAG_METHOD_LIST "_objc_method_list"
351 #define UTAG_CATEGORY "_objc_category"
352 #define UTAG_MODULE "_objc_module"
353 #define UTAG_SYMTAB "_objc_symtab"
354 #define UTAG_SUPER "_objc_super"
355 #define UTAG_SELECTOR "_objc_selector"
357 #define UTAG_PROTOCOL "_objc_protocol"
358 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
359 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
361 /* Note that the string object global name is only needed for the
363 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
365 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
367 static const char *TAG_GETCLASS
;
368 static const char *TAG_GETMETACLASS
;
369 static const char *TAG_MSGSEND
;
370 static const char *TAG_MSGSENDSUPER
;
371 /* The NeXT Objective-C messenger may have two extra entry points, for use
372 when returning a structure. */
373 static const char *TAG_MSGSEND_STRET
;
374 static const char *TAG_MSGSENDSUPER_STRET
;
375 static const char *default_constant_string_class_name
;
377 /* Runtime metadata flags. */
378 #define CLS_FACTORY 0x0001L
379 #define CLS_META 0x0002L
381 #define OBJC_MODIFIER_STATIC 0x00000001
382 #define OBJC_MODIFIER_FINAL 0x00000002
383 #define OBJC_MODIFIER_PUBLIC 0x00000004
384 #define OBJC_MODIFIER_PRIVATE 0x00000008
385 #define OBJC_MODIFIER_PROTECTED 0x00000010
386 #define OBJC_MODIFIER_NATIVE 0x00000020
387 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
388 #define OBJC_MODIFIER_ABSTRACT 0x00000080
389 #define OBJC_MODIFIER_VOLATILE 0x00000100
390 #define OBJC_MODIFIER_TRANSIENT 0x00000200
391 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
393 /* NeXT-specific tags. */
395 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
396 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
397 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
398 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
399 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
400 #define TAG_EXCEPTIONMATCH "objc_exception_match"
401 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
402 #define TAG_SYNCENTER "objc_sync_enter"
403 #define TAG_SYNCEXIT "objc_sync_exit"
404 #define TAG_SETJMP "_setjmp"
405 #define UTAG_EXCDATA "_objc_exception_data"
407 /* GNU-specific tags. */
409 #define TAG_EXECCLASS "__objc_exec_class"
410 #define TAG_GNUINIT "__objc_gnu_init"
412 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
413 tree objc_global_trees
[OCTI_MAX
];
415 static void handle_impent (struct imp_entry
*);
417 struct imp_entry
*imp_list
= 0;
418 int imp_count
= 0; /* `@implementation' */
419 int cat_count
= 0; /* `@category' */
421 enum tree_code objc_inherit_code
;
422 int objc_public_flag
;
424 /* Use to generate method labels. */
425 static int method_slot
= 0;
429 static char *errbuf
; /* Buffer for error diagnostics */
431 /* Data imported from tree.c. */
433 extern enum debug_info_type write_symbols
;
435 /* Data imported from toplev.c. */
437 extern const char *dump_base_name
;
439 static int flag_typed_selectors
;
441 /* Store all constructed constant strings in a hash table so that
442 they get uniqued properly. */
444 struct string_descriptor
GTY(())
446 /* The literal argument . */
449 /* The resulting constant string. */
453 static GTY((param_is (struct string_descriptor
))) htab_t string_htab
;
455 static hashval_t
string_hash (const void *);
456 static int string_eq (const void *, const void *);
458 FILE *gen_declaration_file
;
460 /* Tells "encode_pointer/encode_aggregate" whether we are generating
461 type descriptors for instance variables (as opposed to methods).
462 Type descriptors for instance variables contain more information
463 than methods (for static typing and embedded structures). */
465 static int generating_instance_variables
= 0;
467 /* Some platforms pass small structures through registers versus
468 through an invisible pointer. Determine at what size structure is
469 the transition point between the two possibilities. */
472 generate_struct_by_value_array (void)
475 tree field_decl
, field_decl_chain
;
477 int aggregate_in_mem
[32];
480 /* Presumably no platform passes 32 byte structures in a register. */
481 for (i
= 1; i
< 32; i
++)
485 /* Create an unnamed struct that has `i' character components */
486 type
= start_struct (RECORD_TYPE
, NULL_TREE
);
488 strcpy (buffer
, "c1");
489 field_decl
= create_field_decl (char_type_node
,
491 field_decl_chain
= field_decl
;
493 for (j
= 1; j
< i
; j
++)
495 sprintf (buffer
, "c%d", j
+ 1);
496 field_decl
= create_field_decl (char_type_node
,
498 chainon (field_decl_chain
, field_decl
);
500 finish_struct (type
, field_decl_chain
, NULL_TREE
);
502 aggregate_in_mem
[i
] = aggregate_value_p (type
, 0);
503 if (!aggregate_in_mem
[i
])
507 /* We found some structures that are returned in registers instead of memory
508 so output the necessary data. */
511 for (i
= 31; i
>= 0; i
--)
512 if (!aggregate_in_mem
[i
])
514 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i
);
516 /* The first member of the structure is always 0 because we don't handle
517 structures with 0 members */
518 printf ("static int struct_forward_array[] = {\n 0");
520 for (j
= 1; j
<= i
; j
++)
521 printf (", %d", aggregate_in_mem
[j
]);
532 if (cxx_init () == false)
534 if (c_objc_common_init () == false)
538 #ifndef USE_MAPPED_LOCATION
539 /* Force the line number back to 0; check_newline will have
540 raised it to 1, which will make the builtin functions appear
541 not to be built in. */
545 /* If gen_declaration desired, open the output file. */
546 if (flag_gen_declaration
)
548 register char * const dumpname
= concat (dump_base_name
, ".decl", NULL
);
549 gen_declaration_file
= fopen (dumpname
, "w");
550 if (gen_declaration_file
== 0)
551 fatal_error ("can't open %s: %m", dumpname
);
555 if (flag_next_runtime
)
557 TAG_GETCLASS
= "objc_getClass";
558 TAG_GETMETACLASS
= "objc_getMetaClass";
559 TAG_MSGSEND
= "objc_msgSend";
560 TAG_MSGSENDSUPER
= "objc_msgSendSuper";
561 TAG_MSGSEND_STRET
= "objc_msgSend_stret";
562 TAG_MSGSENDSUPER_STRET
= "objc_msgSendSuper_stret";
563 default_constant_string_class_name
= "NSConstantString";
567 TAG_GETCLASS
= "objc_get_class";
568 TAG_GETMETACLASS
= "objc_get_meta_class";
569 TAG_MSGSEND
= "objc_msg_lookup";
570 TAG_MSGSENDSUPER
= "objc_msg_lookup_super";
571 /* GNU runtime does not provide special functions to support
572 structure-returning methods. */
573 default_constant_string_class_name
= "NXConstantString";
574 flag_typed_selectors
= 1;
579 if (print_struct_values
)
580 generate_struct_by_value_array ();
586 objc_finish_file (void)
588 mark_referenced_methods ();
591 /* We need to instantiate templates _before_ we emit ObjC metadata;
592 if we do not, some metadata (such as selectors) may go missing. */
593 instantiate_pending_templates (0);
596 /* Finalize Objective-C runtime data. No need to generate tables
597 and code if only checking syntax. */
598 if (!flag_syntax_only
)
601 if (gen_declaration_file
)
602 fclose (gen_declaration_file
);
609 /* Return the first occurrence of a method declaration corresponding
610 to sel_name in rproto_list. Search rproto_list recursively.
611 If is_class is 0, search for instance methods, otherwise for class
614 lookup_method_in_protocol_list (tree rproto_list
, tree sel_name
,
620 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
622 p
= TREE_VALUE (rproto
);
624 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
626 if ((fnd
= lookup_method (is_class
627 ? PROTOCOL_CLS_METHODS (p
)
628 : PROTOCOL_NST_METHODS (p
), sel_name
)))
630 else if (PROTOCOL_LIST (p
))
631 fnd
= lookup_method_in_protocol_list (PROTOCOL_LIST (p
),
636 ; /* An identifier...if we could not find a protocol. */
647 lookup_protocol_in_reflist (tree rproto_list
, tree lproto
)
651 /* Make sure the protocol is supported by the object on the rhs. */
652 if (TREE_CODE (lproto
) == PROTOCOL_INTERFACE_TYPE
)
655 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
657 p
= TREE_VALUE (rproto
);
659 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
664 else if (PROTOCOL_LIST (p
))
665 fnd
= lookup_protocol_in_reflist (PROTOCOL_LIST (p
), lproto
);
674 ; /* An identifier...if we could not find a protocol. */
681 objc_start_class_interface (tree
class, tree super_class
, tree protos
)
683 objc_interface_context
685 = start_class (CLASS_INTERFACE_TYPE
, class, super_class
, protos
);
686 objc_public_flag
= 0;
690 objc_start_category_interface (tree
class, tree categ
, tree protos
)
692 objc_interface_context
693 = start_class (CATEGORY_INTERFACE_TYPE
, class, categ
, protos
);
695 = continue_class (objc_interface_context
);
699 objc_start_protocol (tree name
, tree protos
)
701 objc_interface_context
702 = start_protocol (PROTOCOL_INTERFACE_TYPE
, name
, protos
);
706 objc_continue_interface (void)
709 = continue_class (objc_interface_context
);
713 objc_finish_interface (void)
715 finish_class (objc_interface_context
);
716 objc_interface_context
= NULL_TREE
;
720 objc_start_class_implementation (tree
class, tree super_class
)
722 objc_implementation_context
724 = start_class (CLASS_IMPLEMENTATION_TYPE
, class, super_class
, NULL_TREE
);
725 objc_public_flag
= 0;
729 objc_start_category_implementation (tree
class, tree categ
)
731 objc_implementation_context
732 = start_class (CATEGORY_IMPLEMENTATION_TYPE
, class, categ
, NULL_TREE
);
734 = continue_class (objc_implementation_context
);
738 objc_continue_implementation (void)
741 = continue_class (objc_implementation_context
);
745 objc_finish_implementation (void)
747 if (objc_implementation_context
)
749 finish_class (objc_implementation_context
);
750 objc_ivar_chain
= NULL_TREE
;
751 objc_implementation_context
= NULL_TREE
;
754 warning ("%<@end%> must appear in an @implementation context");
758 objc_set_visibility (int visibility
)
760 objc_public_flag
= visibility
;
764 objc_set_method_type (enum tree_code type
)
766 objc_inherit_code
= (type
== PLUS_EXPR
768 : INSTANCE_METHOD_DECL
);
772 objc_build_method_signature (tree rettype
, tree selector
, tree optparms
)
774 return build_method_decl (objc_inherit_code
, rettype
, selector
, optparms
);
778 objc_add_method_declaration (tree decl
)
780 if (!objc_interface_context
)
781 fatal_error ("method declaration not in @interface context");
783 objc_add_method (objc_interface_context
,
785 objc_inherit_code
== CLASS_METHOD_DECL
);
789 objc_start_method_definition (tree decl
)
791 if (!objc_implementation_context
)
792 fatal_error ("method definition not in @implementation context");
794 objc_add_method (objc_implementation_context
,
796 objc_inherit_code
== CLASS_METHOD_DECL
);
797 start_method_def (decl
);
801 objc_add_instance_variable (tree decl
)
803 (void) add_instance_variable (objc_ivar_context
,
808 /* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of
812 objc_is_reserved_word (tree ident
)
814 unsigned char code
= C_RID_CODE (ident
);
816 return (OBJC_IS_AT_KEYWORD (code
)
818 || code
== RID_CLASS
|| code
== RID_PUBLIC
819 || code
== RID_PROTECTED
|| code
== RID_PRIVATE
820 || code
== RID_TRY
|| code
== RID_THROW
|| code
== RID_CATCH
825 /* Return true if TYPE is 'id'. */
828 objc_is_object_id (tree type
)
830 return OBJC_TYPE_NAME (type
) == objc_object_id
;
834 objc_is_class_id (tree type
)
836 return OBJC_TYPE_NAME (type
) == objc_class_id
;
839 /* Return 1 if LHS and RHS are compatible types for assignment or
840 various other operations. Return 0 if they are incompatible, and
841 return -1 if we choose to not decide (because the types are really
842 just C types, not ObjC specific ones). When the operation is
843 REFLEXIVE (typically comparisons), check for compatibility in
844 either direction; when it's not (typically assignments), don't.
846 This function is called in two cases: when both lhs and rhs are
847 pointers to records (in which case we check protocols too), and
848 when both lhs and rhs are records (in which case we check class
851 Warnings about classes/protocols not implementing a protocol are
852 emitted here (multiple of those warnings might be emitted for a
853 single line!); generic warnings about incompatible assignments and
854 lacks of casts in comparisons are/must be emitted by the caller if
859 objc_comptypes (tree lhs
, tree rhs
, int reflexive
)
861 /* New clause for protocols. */
863 /* Here we manage the case of a POINTER_TYPE = POINTER_TYPE. We only
864 manage the ObjC ones, and leave the rest to the C code. */
865 if (TREE_CODE (lhs
) == POINTER_TYPE
866 && TREE_CODE (TREE_TYPE (lhs
)) == RECORD_TYPE
867 && TREE_CODE (rhs
) == POINTER_TYPE
868 && TREE_CODE (TREE_TYPE (rhs
)) == RECORD_TYPE
)
870 int lhs_is_proto
= IS_PROTOCOL_QUALIFIED_UNTYPED (lhs
);
871 int rhs_is_proto
= IS_PROTOCOL_QUALIFIED_UNTYPED (rhs
);
875 tree lproto
, lproto_list
= TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (lhs
));
876 tree rproto
, rproto_list
;
879 /* <Protocol> = <Protocol> */
882 /* Class <Protocol> != id <Protocol>;
883 id <Protocol> != Class <Protocol> */
884 if (IS_ID (lhs
) != IS_ID (rhs
))
887 rproto_list
= TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rhs
));
891 /* An assignment between objects of type 'id
892 <Protocol>'; make sure the protocol on the lhs is
893 supported by the object on the rhs. */
894 for (lproto
= lproto_list
; lproto
;
895 lproto
= TREE_CHAIN (lproto
))
897 p
= TREE_VALUE (lproto
);
898 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
902 ("object does not conform to the %qs protocol",
903 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
909 /* Obscure case - a comparison between two objects
910 of type 'id <Protocol>'. Check that either the
911 protocol on the lhs is supported by the object on
912 the rhs, or viceversa. */
914 /* Check if the protocol on the lhs is supported by the
915 object on the rhs. */
916 for (lproto
= lproto_list
; lproto
;
917 lproto
= TREE_CHAIN (lproto
))
919 p
= TREE_VALUE (lproto
);
920 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
924 /* Check failed - check if the protocol on the rhs
925 is supported by the object on the lhs. */
926 for (rproto
= rproto_list
; rproto
;
927 rproto
= TREE_CHAIN (rproto
))
929 p
= TREE_VALUE (rproto
);
930 lproto
= lookup_protocol_in_reflist (lproto_list
,
935 /* This check failed too: incompatible */
945 /* <Protocol> = <class> * */
946 else if (TYPED_OBJECT (TREE_TYPE (rhs
)))
948 tree rname
= OBJC_TYPE_NAME (TREE_TYPE (rhs
));
951 /* Class <Protocol> != <class> * */
955 /* Make sure the protocol is supported by the object on
957 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
959 p
= TREE_VALUE (lproto
);
961 rinter
= lookup_interface (rname
);
963 while (rinter
&& !rproto
)
967 rproto_list
= CLASS_PROTOCOL_LIST (rinter
);
968 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
969 /* If the underlying ObjC class does not have
970 the protocol we're looking for, check for "one-off"
971 protocols (e.g., `NSObject<MyProt> *foo;') attached
973 if (!rproto
&& TYPE_HAS_OBJC_INFO (TREE_TYPE (rhs
)))
975 rproto_list
= TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rhs
));
976 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
979 /* Check for protocols adopted by categories. */
980 cat
= CLASS_CATEGORY_LIST (rinter
);
981 while (cat
&& !rproto
)
983 rproto_list
= CLASS_PROTOCOL_LIST (cat
);
984 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
985 cat
= CLASS_CATEGORY_LIST (cat
);
988 rinter
= lookup_interface (CLASS_SUPER_NAME (rinter
));
992 warning ("class %qs does not implement the %qs protocol",
993 IDENTIFIER_POINTER (OBJC_TYPE_NAME (TREE_TYPE (rhs
))),
994 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
998 /* id <Protocol> = id; Class <Protocol> = id */
999 else if (objc_is_object_id (TREE_TYPE (rhs
)))
1003 /* id <Protocol> != Class; Class <Protocol> = Class */
1004 else if (objc_is_class_id (TREE_TYPE (rhs
)))
1006 return IS_CLASS (lhs
);
1008 /* <Protocol> = ?? : let comptypes decide. */
1011 else if (rhs_is_proto
)
1013 /* <class> * = <Protocol> */
1014 if (TYPED_OBJECT (TREE_TYPE (lhs
)))
1016 /* <class> * != Class <Protocol> */
1022 tree rname
= OBJC_TYPE_NAME (TREE_TYPE (lhs
));
1024 tree rproto
, rproto_list
= TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rhs
));
1026 /* Make sure the protocol is supported by the object on
1028 for (rproto
= rproto_list
; rproto
;
1029 rproto
= TREE_CHAIN (rproto
))
1031 tree p
= TREE_VALUE (rproto
);
1033 rinter
= lookup_interface (rname
);
1035 while (rinter
&& !lproto
)
1039 tree lproto_list
= CLASS_PROTOCOL_LIST (rinter
);
1040 lproto
= lookup_protocol_in_reflist (lproto_list
, p
);
1041 /* If the underlying ObjC class does not
1042 have the protocol we're looking for,
1043 check for "one-off" protocols (e.g.,
1044 `NSObject<MyProt> *foo;') attached to the
1046 if (!lproto
&& TYPE_HAS_OBJC_INFO (TREE_TYPE (lhs
)))
1048 lproto_list
= TYPE_OBJC_PROTOCOL_LIST
1050 lproto
= lookup_protocol_in_reflist
1054 /* Check for protocols adopted by categories. */
1055 cat
= CLASS_CATEGORY_LIST (rinter
);
1056 while (cat
&& !lproto
)
1058 lproto_list
= CLASS_PROTOCOL_LIST (cat
);
1059 lproto
= lookup_protocol_in_reflist (lproto_list
,
1061 cat
= CLASS_CATEGORY_LIST (cat
);
1064 rinter
= lookup_interface (CLASS_SUPER_NAME
1069 warning ("class %qs does not implement the %qs protocol",
1070 IDENTIFIER_POINTER (OBJC_TYPE_NAME
1072 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
1079 /* id = id <Protocol>; id = Class <Protocol> */
1080 else if (objc_is_object_id (TREE_TYPE (lhs
)))
1084 /* Class != id <Protocol>; Class = Class <Protocol> */
1085 else if (objc_is_class_id (TREE_TYPE (lhs
)))
1087 return IS_CLASS (rhs
);
1089 /* ??? = <Protocol> : let comptypes decide */
1097 /* Attention: we shouldn't defer to comptypes here. One bad
1098 side effect would be that we might loose the REFLEXIVE
1101 lhs
= TREE_TYPE (lhs
);
1102 rhs
= TREE_TYPE (rhs
);
1106 if (TREE_CODE (lhs
) != RECORD_TYPE
|| TREE_CODE (rhs
) != RECORD_TYPE
)
1108 /* Nothing to do with ObjC - let immediately comptypes take
1109 responsibility for checking. */
1113 /* `id' = `<class> *' `<class> *' = `id': always allow it.
1115 'Object *o = [[Object alloc] init]; falls
1116 in the case <class> * = `id'.
1118 if ((objc_is_object_id (lhs
) && TYPED_OBJECT (rhs
))
1119 || (objc_is_object_id (rhs
) && TYPED_OBJECT (lhs
)))
1122 /* `id' = `Class', `Class' = `id' */
1124 else if ((objc_is_object_id (lhs
) && objc_is_class_id (rhs
))
1125 || (objc_is_class_id (lhs
) && objc_is_object_id (rhs
)))
1128 /* `Class' != `<class> *' && `<class> *' != `Class'! */
1129 else if ((OBJC_TYPE_NAME (lhs
) == objc_class_id
&& TYPED_OBJECT (rhs
))
1130 || (OBJC_TYPE_NAME (rhs
) == objc_class_id
&& TYPED_OBJECT (lhs
)))
1133 /* `<class> *' = `<class> *' */
1135 else if (TYPED_OBJECT (lhs
) && TYPED_OBJECT (rhs
))
1137 tree lname
= OBJC_TYPE_NAME (lhs
);
1138 tree rname
= OBJC_TYPE_NAME (rhs
);
1144 /* If the left hand side is a super class of the right hand side,
1146 for (inter
= lookup_interface (rname
); inter
;
1147 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
1148 if (lname
== CLASS_SUPER_NAME (inter
))
1151 /* Allow the reverse when reflexive. */
1153 for (inter
= lookup_interface (lname
); inter
;
1154 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
1155 if (rname
== CLASS_SUPER_NAME (inter
))
1161 /* Not an ObjC type - let comptypes do the check. */
1165 /* Called from finish_decl. */
1168 objc_check_decl (tree decl
)
1170 tree type
= TREE_TYPE (decl
);
1172 if (TREE_CODE (type
) != RECORD_TYPE
)
1174 if (OBJC_TYPE_NAME (type
) && (type
= objc_is_class_name (OBJC_TYPE_NAME (type
))))
1175 error ("statically allocated instance of Objective-C class %qs",
1176 IDENTIFIER_POINTER (type
));
1179 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1180 either name an Objective-C class, or refer to the special 'id' or 'Class'
1181 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
1184 objc_get_protocol_qualified_type (tree interface
, tree protocols
)
1186 /* If INTERFACE is not provided, default to 'id'. */
1187 tree type
= (interface
? objc_is_id (interface
) : objc_object_type
);
1188 bool is_ptr
= (type
!= NULL_TREE
);
1192 type
= objc_is_class_name (interface
);
1195 type
= xref_tag (RECORD_TYPE
, type
);
1202 type
= build_variant_type_copy (type
);
1204 /* For pointers (i.e., 'id' or 'Class'), attach the protocol(s)
1208 TREE_TYPE (type
) = build_variant_type_copy (TREE_TYPE (type
));
1209 TYPE_POINTER_TO (TREE_TYPE (type
)) = type
;
1210 type
= TREE_TYPE (type
);
1213 /* Look up protocols and install in lang specific list. */
1214 DUP_TYPE_OBJC_INFO (type
, TYPE_MAIN_VARIANT (type
));
1215 TYPE_OBJC_PROTOCOL_LIST (type
) = lookup_and_install_protocols (protocols
);
1217 /* For RECORD_TYPEs, point to the @interface; for 'id' and 'Class',
1218 return the pointer to the new pointee variant. */
1220 type
= TYPE_POINTER_TO (type
);
1222 TYPE_OBJC_INTERFACE (type
)
1223 = TYPE_OBJC_INTERFACE (TYPE_MAIN_VARIANT (type
));
1229 /* Check for circular dependencies in protocols. The arguments are
1230 PROTO, the protocol to check, and LIST, a list of protocol it
1234 check_protocol_recursively (tree proto
, tree list
)
1238 for (p
= list
; p
; p
= TREE_CHAIN (p
))
1240 tree pp
= TREE_VALUE (p
);
1242 if (TREE_CODE (pp
) == IDENTIFIER_NODE
)
1243 pp
= lookup_protocol (pp
);
1246 fatal_error ("protocol %qs has circular dependency",
1247 IDENTIFIER_POINTER (PROTOCOL_NAME (pp
)));
1249 check_protocol_recursively (proto
, PROTOCOL_LIST (pp
));
1253 /* Look up PROTOCOLS, and return a list of those that are found.
1254 If none are found, return NULL. */
1257 lookup_and_install_protocols (tree protocols
)
1260 tree return_value
= NULL_TREE
;
1262 for (proto
= protocols
; proto
; proto
= TREE_CHAIN (proto
))
1264 tree ident
= TREE_VALUE (proto
);
1265 tree p
= lookup_protocol (ident
);
1268 error ("cannot find protocol declaration for %qs",
1269 IDENTIFIER_POINTER (ident
));
1271 return_value
= chainon (return_value
,
1272 build_tree_list (NULL_TREE
, p
));
1275 return return_value
;
1278 /* Create a declaration for field NAME of a given TYPE. */
1281 create_field_decl (tree type
, const char *name
)
1283 return build_decl (FIELD_DECL
, get_identifier (name
), type
);
1286 /* Create a global, static declaration for variable NAME of a given TYPE. The
1287 finish_var_decl() routine will need to be called on it afterwards. */
1290 start_var_decl (tree type
, const char *name
)
1292 tree var
= build_decl (VAR_DECL
, get_identifier (name
), type
);
1294 TREE_STATIC (var
) = 1;
1295 DECL_INITIAL (var
) = error_mark_node
; /* A real initializer is coming... */
1296 DECL_IGNORED_P (var
) = 1;
1297 DECL_ARTIFICIAL (var
) = 1;
1298 DECL_CONTEXT (var
) = NULL_TREE
;
1300 DECL_THIS_STATIC (var
) = 1; /* squash redeclaration errors */
1306 /* Finish off the variable declaration created by start_var_decl(). */
1309 finish_var_decl (tree var
, tree initializer
)
1311 finish_decl (var
, initializer
, NULL_TREE
);
1312 /* Ensure that the variable actually gets output. */
1313 mark_decl_referenced (var
);
1314 /* Mark the decl to avoid "defined but not used" warning. */
1315 TREE_USED (var
) = 1;
1318 /* Find the decl for the constant string class reference. This is only
1319 used for the NeXT runtime. */
1322 setup_string_decl (void)
1327 /* %s in format will provide room for terminating null */
1328 length
= strlen (STRING_OBJECT_GLOBAL_FORMAT
)
1329 + strlen (constant_string_class_name
);
1330 name
= xmalloc (length
);
1331 sprintf (name
, STRING_OBJECT_GLOBAL_FORMAT
,
1332 constant_string_class_name
);
1333 constant_string_global_id
= get_identifier (name
);
1334 string_class_decl
= lookup_name (constant_string_global_id
);
1336 return string_class_decl
;
1339 /* Purpose: "play" parser, creating/installing representations
1340 of the declarations that are required by Objective-C.
1344 type_spec--------->sc_spec
1345 (tree_list) (tree_list)
1348 identifier_node identifier_node */
1351 synth_module_prologue (void)
1354 enum debug_info_type save_write_symbols
= write_symbols
;
1355 const struct gcc_debug_hooks
*const save_hooks
= debug_hooks
;
1357 /* Suppress outputting debug symbols, because
1358 dbxout_init hasn'r been called yet. */
1359 write_symbols
= NO_DEBUG
;
1360 debug_hooks
= &do_nothing_debug_hooks
;
1363 push_lang_context (lang_name_c
); /* extern "C" */
1366 /* The following are also defined in <objc/objc.h> and friends. */
1368 objc_object_id
= get_identifier (TAG_OBJECT
);
1369 objc_class_id
= get_identifier (TAG_CLASS
);
1371 objc_object_reference
= xref_tag (RECORD_TYPE
, objc_object_id
);
1372 objc_class_reference
= xref_tag (RECORD_TYPE
, objc_class_id
);
1374 objc_object_type
= build_pointer_type (objc_object_reference
);
1375 objc_class_type
= build_pointer_type (objc_class_reference
);
1377 objc_object_name
= get_identifier (OBJECT_TYPEDEF_NAME
);
1378 objc_class_name
= get_identifier (CLASS_TYPEDEF_NAME
);
1380 /* Declare the 'id' and 'Class' typedefs. */
1382 type
= lang_hooks
.decls
.pushdecl (build_decl (TYPE_DECL
,
1385 DECL_IN_SYSTEM_HEADER (type
) = 1;
1386 type
= lang_hooks
.decls
.pushdecl (build_decl (TYPE_DECL
,
1389 DECL_IN_SYSTEM_HEADER (type
) = 1;
1391 /* Forward-declare '@interface Protocol'. */
1393 type
= get_identifier (PROTOCOL_OBJECT_CLASS_NAME
);
1394 objc_declare_class (tree_cons (NULL_TREE
, type
, NULL_TREE
));
1395 objc_protocol_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
1398 /* Declare type of selector-objects that represent an operation name. */
1400 if (flag_next_runtime
)
1401 /* `struct objc_selector *' */
1403 = build_pointer_type (xref_tag (RECORD_TYPE
,
1404 get_identifier (TAG_SELECTOR
)));
1406 /* `const struct objc_selector *' */
1408 = build_pointer_type
1409 (build_qualified_type (xref_tag (RECORD_TYPE
,
1410 get_identifier (TAG_SELECTOR
)),
1413 /* Declare receiver type used for dispatching messages to 'super'. */
1415 /* `struct objc_super *' */
1416 objc_super_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
1417 get_identifier (TAG_SUPER
)));
1419 if (flag_next_runtime
)
1421 /* NB: In order to call one of the ..._stret (struct-returning)
1422 functions, the function *MUST* first be cast to a signature that
1423 corresponds to the actual ObjC method being invoked. This is
1424 what is done by the build_objc_method_call() routine below. */
1426 /* id objc_msgSend (id, SEL, ...); */
1427 /* id objc_msgSendNonNil (id, SEL, ...); */
1428 /* id objc_msgSend_stret (id, SEL, ...); */
1429 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1431 = build_function_type (objc_object_type
,
1432 tree_cons (NULL_TREE
, objc_object_type
,
1433 tree_cons (NULL_TREE
, objc_selector_type
,
1435 umsg_decl
= builtin_function (TAG_MSGSEND
,
1436 type
, 0, NOT_BUILT_IN
,
1438 umsg_nonnil_decl
= builtin_function (TAG_MSGSEND_NONNIL
,
1439 type
, 0, NOT_BUILT_IN
,
1441 umsg_stret_decl
= builtin_function (TAG_MSGSEND_STRET
,
1442 type
, 0, NOT_BUILT_IN
,
1444 umsg_nonnil_stret_decl
= builtin_function (TAG_MSGSEND_NONNIL_STRET
,
1445 type
, 0, NOT_BUILT_IN
,
1448 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1449 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1451 = build_function_type (objc_object_type
,
1452 tree_cons (NULL_TREE
, objc_super_type
,
1453 tree_cons (NULL_TREE
, objc_selector_type
,
1455 umsg_super_decl
= builtin_function (TAG_MSGSENDSUPER
,
1456 type
, 0, NOT_BUILT_IN
,
1458 umsg_super_stret_decl
= builtin_function (TAG_MSGSENDSUPER_STRET
,
1459 type
, 0, NOT_BUILT_IN
, 0,
1464 /* GNU runtime messenger entry points. */
1466 /* typedef id (*IMP)(id, SEL, ...); */
1468 = build_pointer_type
1469 (build_function_type (objc_object_type
,
1470 tree_cons (NULL_TREE
, objc_object_type
,
1471 tree_cons (NULL_TREE
, objc_selector_type
,
1474 /* IMP objc_msg_lookup (id, SEL); */
1476 = build_function_type (IMP_type
,
1477 tree_cons (NULL_TREE
, objc_object_type
,
1478 tree_cons (NULL_TREE
, objc_selector_type
,
1479 OBJC_VOID_AT_END
)));
1480 umsg_decl
= builtin_function (TAG_MSGSEND
,
1481 type
, 0, NOT_BUILT_IN
,
1484 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1486 = build_function_type (IMP_type
,
1487 tree_cons (NULL_TREE
, objc_super_type
,
1488 tree_cons (NULL_TREE
, objc_selector_type
,
1489 OBJC_VOID_AT_END
)));
1490 umsg_super_decl
= builtin_function (TAG_MSGSENDSUPER
,
1491 type
, 0, NOT_BUILT_IN
,
1494 /* The following GNU runtime entry point is called to initialize
1497 __objc_exec_class (void *); */
1499 = build_function_type (void_type_node
,
1500 tree_cons (NULL_TREE
, ptr_type_node
,
1502 execclass_decl
= builtin_function (TAG_EXECCLASS
,
1503 type
, 0, NOT_BUILT_IN
,
1507 /* id objc_getClass (const char *); */
1509 type
= build_function_type (objc_object_type
,
1510 tree_cons (NULL_TREE
,
1511 const_string_type_node
,
1515 = builtin_function (TAG_GETCLASS
, type
, 0, NOT_BUILT_IN
,
1518 /* id objc_getMetaClass (const char *); */
1520 objc_get_meta_class_decl
1521 = builtin_function (TAG_GETMETACLASS
, type
, 0, NOT_BUILT_IN
, NULL
, NULL_TREE
);
1523 build_class_template ();
1524 build_super_template ();
1525 build_protocol_template ();
1526 build_category_template ();
1527 build_objc_exception_stuff ();
1529 if (flag_next_runtime
)
1530 build_next_objc_exception_stuff ();
1532 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1534 if (! flag_next_runtime
)
1535 build_selector_table_decl ();
1537 /* Forward declare constant_string_id and constant_string_type. */
1538 if (!constant_string_class_name
)
1539 constant_string_class_name
= default_constant_string_class_name
;
1541 constant_string_id
= get_identifier (constant_string_class_name
);
1542 objc_declare_class (tree_cons (NULL_TREE
, constant_string_id
, NULL_TREE
));
1544 /* Pre-build the following entities - for speed/convenience. */
1545 self_id
= get_identifier ("self");
1546 ucmd_id
= get_identifier ("_cmd");
1548 /* The C++ front-end does not appear to grok __attribute__((__unused__)). */
1549 unused_list
= build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
1553 pop_lang_context ();
1556 write_symbols
= save_write_symbols
;
1557 debug_hooks
= save_hooks
;
1560 /* Ensure that the ivar list for NSConstantString/NXConstantString
1561 (or whatever was specified via `-fconstant-string-class')
1562 contains fields at least as large as the following three, so that
1563 the runtime can stomp on them with confidence:
1565 struct STRING_OBJECT_CLASS_NAME
1569 unsigned int length;
1573 check_string_class_template (void)
1575 tree field_decl
= TYPE_FIELDS (constant_string_type
);
1577 #define AT_LEAST_AS_LARGE_AS(F, T) \
1578 (F && TREE_CODE (F) == FIELD_DECL \
1579 && (TREE_INT_CST_LOW (DECL_SIZE (F)) \
1580 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1582 if (!AT_LEAST_AS_LARGE_AS (field_decl
, ptr_type_node
))
1585 field_decl
= TREE_CHAIN (field_decl
);
1586 if (!AT_LEAST_AS_LARGE_AS (field_decl
, ptr_type_node
))
1589 field_decl
= TREE_CHAIN (field_decl
);
1590 return AT_LEAST_AS_LARGE_AS (field_decl
, unsigned_type_node
);
1592 #undef AT_LEAST_AS_LARGE_AS
1595 /* Avoid calling `check_string_class_template ()' more than once. */
1596 static GTY(()) int string_layout_checked
;
1598 /* Custom build_string which sets TREE_TYPE! */
1601 my_build_string (int len
, const char *str
)
1603 return fix_string_type (build_string (len
, str
));
1608 string_hash (const void *ptr
)
1610 tree str
= ((struct string_descriptor
*)ptr
)->literal
;
1611 const unsigned char *p
= (const unsigned char *) TREE_STRING_POINTER (str
);
1612 int i
, len
= TREE_STRING_LENGTH (str
);
1615 for (i
= 0; i
< len
; i
++)
1616 h
= ((h
* 613) + p
[i
]);
1622 string_eq (const void *ptr1
, const void *ptr2
)
1624 tree str1
= ((struct string_descriptor
*)ptr1
)->literal
;
1625 tree str2
= ((struct string_descriptor
*)ptr2
)->literal
;
1626 int len1
= TREE_STRING_LENGTH (str1
);
1628 return (len1
== TREE_STRING_LENGTH (str2
)
1629 && !memcmp (TREE_STRING_POINTER (str1
), TREE_STRING_POINTER (str2
),
1633 /* Given a chain of STRING_CST's, build a static instance of
1634 NXConstantString which points at the concatenation of those
1635 strings. We place the string object in the __string_objects
1636 section of the __OBJC segment. The Objective-C runtime will
1637 initialize the isa pointers of the string objects to point at the
1638 NXConstantString class object. */
1641 objc_build_string_object (tree string
)
1643 tree initlist
, constructor
, constant_string_class
;
1646 struct string_descriptor
*desc
, key
;
1649 /* Prep the string argument. */
1650 string
= fix_string_type (string
);
1651 TREE_SET_CODE (string
, STRING_CST
);
1652 length
= TREE_STRING_LENGTH (string
) - 1;
1654 /* Check whether the string class being used actually exists and has the
1655 correct ivar layout. */
1656 if (!string_layout_checked
)
1658 string_layout_checked
= -1;
1659 constant_string_class
= lookup_interface (constant_string_id
);
1661 if (!constant_string_class
1662 || !(constant_string_type
1663 = CLASS_STATIC_TEMPLATE (constant_string_class
)))
1664 error ("cannot find interface declaration for %qs",
1665 IDENTIFIER_POINTER (constant_string_id
));
1666 /* The NSConstantString/NXConstantString ivar layout is now known. */
1667 else if (!check_string_class_template ())
1668 error ("interface %qs does not have valid constant string layout",
1669 IDENTIFIER_POINTER (constant_string_id
));
1670 /* For the NeXT runtime, we can generate a literal reference
1671 to the string class, don't need to run a constructor. */
1672 else if (flag_next_runtime
&& !setup_string_decl ())
1673 error ("cannot find reference tag for class %qs",
1674 IDENTIFIER_POINTER (constant_string_id
));
1677 string_layout_checked
= 1; /* Success! */
1678 add_class_reference (constant_string_id
);
1682 if (string_layout_checked
== -1)
1683 return error_mark_node
;
1685 /* Perhaps we already constructed a constant string just like this one? */
1686 key
.literal
= string
;
1687 loc
= htab_find_slot (string_htab
, &key
, INSERT
);
1693 *loc
= desc
= ggc_alloc (sizeof (*desc
));
1694 desc
->literal
= string
;
1696 /* GNU: & ((NXConstantString) { NULL, string, length }) */
1697 /* NeXT: & ((NSConstantString) { isa, string, length }) */
1698 fields
= TYPE_FIELDS (constant_string_type
);
1700 = build_tree_list (fields
,
1702 ? build_unary_op (ADDR_EXPR
, string_class_decl
, 0)
1703 : build_int_cst (NULL_TREE
, 0));
1704 fields
= TREE_CHAIN (fields
);
1705 initlist
= tree_cons (fields
, build_unary_op (ADDR_EXPR
, string
, 1),
1707 fields
= TREE_CHAIN (fields
);
1708 initlist
= tree_cons (fields
, build_int_cst (NULL_TREE
, length
),
1710 constructor
= objc_build_constructor (constant_string_type
,
1711 nreverse (initlist
));
1712 TREE_INVARIANT (constructor
) = true;
1714 if (!flag_next_runtime
)
1716 = objc_add_static_instance (constructor
, constant_string_type
);
1719 var
= build_decl (CONST_DECL
, NULL
, TREE_TYPE (constructor
));
1720 DECL_INITIAL (var
) = constructor
;
1721 TREE_STATIC (var
) = 1;
1722 pushdecl_top_level (var
);
1725 desc
->constructor
= constructor
;
1728 addr
= build_unary_op (ADDR_EXPR
, desc
->constructor
, 1);
1733 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1735 static GTY(()) int num_static_inst
;
1738 objc_add_static_instance (tree constructor
, tree class_decl
)
1743 /* Find the list of static instances for the CLASS_DECL. Create one if
1745 for (chain
= &objc_static_instances
;
1746 *chain
&& TREE_VALUE (*chain
) != class_decl
;
1747 chain
= &TREE_CHAIN (*chain
));
1750 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
1751 add_objc_string (OBJC_TYPE_NAME (class_decl
), class_names
);
1754 sprintf (buf
, "_OBJC_INSTANCE_%d", num_static_inst
++);
1755 decl
= build_decl (VAR_DECL
, get_identifier (buf
), class_decl
);
1756 DECL_COMMON (decl
) = 1;
1757 TREE_STATIC (decl
) = 1;
1758 DECL_ARTIFICIAL (decl
) = 1;
1759 DECL_INITIAL (decl
) = constructor
;
1761 /* We may be writing something else just now.
1762 Postpone till end of input. */
1763 DECL_DEFER_OUTPUT (decl
) = 1;
1764 pushdecl_top_level (decl
);
1765 rest_of_decl_compilation (decl
, 1, 0);
1767 /* Add the DECL to the head of this CLASS' list. */
1768 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
1773 /* Build a static constant CONSTRUCTOR
1774 with type TYPE and elements ELTS. */
1777 objc_build_constructor (tree type
, tree elts
)
1779 tree constructor
= build_constructor (type
, elts
);
1781 TREE_CONSTANT (constructor
) = 1;
1782 TREE_STATIC (constructor
) = 1;
1783 TREE_READONLY (constructor
) = 1;
1786 /* Adjust for impedance mismatch. We should figure out how to build
1787 CONSTRUCTORs that consistently please both the C and C++ gods. */
1788 if (!TREE_PURPOSE (elts
))
1789 TREE_TYPE (constructor
) = NULL_TREE
;
1790 TREE_HAS_CONSTRUCTOR (constructor
) = 1;
1796 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1798 /* Predefine the following data type:
1806 void *defs[cls_def_cnt + cat_def_cnt];
1810 build_objc_symtab_template (void)
1812 tree field_decl
, field_decl_chain
;
1814 objc_symtab_template
1815 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SYMTAB
));
1817 /* long sel_ref_cnt; */
1818 field_decl
= create_field_decl (long_integer_type_node
, "sel_ref_cnt");
1819 field_decl_chain
= field_decl
;
1822 field_decl
= create_field_decl (build_pointer_type (objc_selector_type
),
1824 chainon (field_decl_chain
, field_decl
);
1826 /* short cls_def_cnt; */
1827 field_decl
= create_field_decl (short_integer_type_node
, "cls_def_cnt");
1828 chainon (field_decl_chain
, field_decl
);
1830 /* short cat_def_cnt; */
1831 field_decl
= create_field_decl (short_integer_type_node
,
1833 chainon (field_decl_chain
, field_decl
);
1835 if (imp_count
|| cat_count
|| !flag_next_runtime
)
1837 /* void *defs[imp_count + cat_count (+ 1)]; */
1838 /* NB: The index is one less than the size of the array. */
1839 int index
= imp_count
+ cat_count
1840 + (flag_next_runtime
? -1: 0);
1841 field_decl
= create_field_decl
1844 build_index_type (build_int_cst (NULL_TREE
, index
))),
1846 chainon (field_decl_chain
, field_decl
);
1849 finish_struct (objc_symtab_template
, field_decl_chain
, NULL_TREE
);
1852 /* Create the initial value for the `defs' field of _objc_symtab.
1853 This is a CONSTRUCTOR. */
1856 init_def_list (tree type
)
1858 tree expr
, initlist
= NULL_TREE
;
1859 struct imp_entry
*impent
;
1862 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1864 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
1866 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1867 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1872 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1874 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1876 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1877 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1881 if (!flag_next_runtime
)
1883 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1886 if (static_instances_decl
)
1887 expr
= build_unary_op (ADDR_EXPR
, static_instances_decl
, 0);
1889 expr
= build_int_cst (NULL_TREE
, 0);
1891 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1894 return objc_build_constructor (type
, nreverse (initlist
));
1897 /* Construct the initial value for all of _objc_symtab. */
1900 init_objc_symtab (tree type
)
1904 /* sel_ref_cnt = { ..., 5, ... } */
1906 initlist
= build_tree_list (NULL_TREE
,
1907 build_int_cst (long_integer_type_node
, 0));
1909 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1911 if (flag_next_runtime
|| ! sel_ref_chain
)
1912 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
1915 = tree_cons (NULL_TREE
,
1916 convert (build_pointer_type (objc_selector_type
),
1917 build_unary_op (ADDR_EXPR
,
1918 UOBJC_SELECTOR_TABLE_decl
, 1)),
1921 /* cls_def_cnt = { ..., 5, ... } */
1923 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, imp_count
), initlist
);
1925 /* cat_def_cnt = { ..., 5, ... } */
1927 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, cat_count
), initlist
);
1929 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1931 if (imp_count
|| cat_count
|| !flag_next_runtime
)
1934 tree field
= TYPE_FIELDS (type
);
1935 field
= TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field
))));
1937 initlist
= tree_cons (NULL_TREE
, init_def_list (TREE_TYPE (field
)),
1941 return objc_build_constructor (type
, nreverse (initlist
));
1944 /* Generate forward declarations for metadata such as
1945 'OBJC_CLASS_...'. */
1948 build_metadata_decl (const char *name
, tree type
)
1952 /* struct TYPE NAME_<name>; */
1953 decl
= start_var_decl (type
, synth_id_with_class_suffix
1955 objc_implementation_context
));
1960 /* Push forward-declarations of all the categories so that
1961 init_def_list can use them in a CONSTRUCTOR. */
1964 forward_declare_categories (void)
1966 struct imp_entry
*impent
;
1967 tree sav
= objc_implementation_context
;
1969 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1971 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1973 /* Set an invisible arg to synth_id_with_class_suffix. */
1974 objc_implementation_context
= impent
->imp_context
;
1975 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
1976 impent
->class_decl
= build_metadata_decl ("_OBJC_CATEGORY",
1977 objc_category_template
);
1980 objc_implementation_context
= sav
;
1983 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
1984 and initialized appropriately. */
1987 generate_objc_symtab_decl (void)
1989 /* forward declare categories */
1991 forward_declare_categories ();
1993 build_objc_symtab_template ();
1994 UOBJC_SYMBOLS_decl
= start_var_decl (objc_symtab_template
, "_OBJC_SYMBOLS");
1995 finish_var_decl (UOBJC_SYMBOLS_decl
,
1996 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)));
2000 init_module_descriptor (tree type
)
2002 tree initlist
, expr
;
2004 /* version = { 1, ... } */
2006 expr
= build_int_cst (long_integer_type_node
, OBJC_VERSION
);
2007 initlist
= build_tree_list (NULL_TREE
, expr
);
2009 /* size = { ..., sizeof (struct _objc_module), ... } */
2011 expr
= convert (long_integer_type_node
,
2012 size_in_bytes (objc_module_template
));
2013 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2015 /* name = { ..., "foo.m", ... } */
2017 expr
= add_objc_string (get_identifier (input_filename
), class_names
);
2018 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2020 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2022 if (UOBJC_SYMBOLS_decl
)
2023 expr
= build_unary_op (ADDR_EXPR
, UOBJC_SYMBOLS_decl
, 0);
2025 expr
= build_int_cst (NULL_TREE
, 0);
2026 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2028 return objc_build_constructor (type
, nreverse (initlist
));
2031 /* Write out the data structures to describe Objective C classes defined.
2033 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2036 build_module_descriptor (void)
2038 tree field_decl
, field_decl_chain
;
2041 push_lang_context (lang_name_c
); /* extern "C" */
2044 objc_module_template
2045 = start_struct (RECORD_TYPE
, get_identifier (UTAG_MODULE
));
2048 field_decl
= create_field_decl (long_integer_type_node
, "version");
2049 field_decl_chain
= field_decl
;
2052 field_decl
= create_field_decl (long_integer_type_node
, "size");
2053 chainon (field_decl_chain
, field_decl
);
2056 field_decl
= create_field_decl (string_type_node
, "name");
2057 chainon (field_decl_chain
, field_decl
);
2059 /* struct _objc_symtab *symtab; */
2061 = create_field_decl (build_pointer_type
2062 (xref_tag (RECORD_TYPE
,
2063 get_identifier (UTAG_SYMTAB
))),
2065 chainon (field_decl_chain
, field_decl
);
2067 finish_struct (objc_module_template
, field_decl_chain
, NULL_TREE
);
2069 /* Create an instance of "_objc_module". */
2070 UOBJC_MODULES_decl
= start_var_decl (objc_module_template
, "_OBJC_MODULES");
2071 finish_var_decl (UOBJC_MODULES_decl
,
2072 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl
)));
2075 pop_lang_context ();
2079 /* The GNU runtime requires us to provide a static initializer function
2082 static void __objc_gnu_init (void) {
2083 __objc_exec_class (&L_OBJC_MODULES);
2087 build_module_initializer_routine (void)
2092 push_lang_context (lang_name_c
); /* extern "C" */
2095 objc_push_parm (build_decl (PARM_DECL
, NULL_TREE
, void_type_node
));
2096 objc_start_function (get_identifier (TAG_GNUINIT
),
2097 build_function_type (void_type_node
,
2099 NULL_TREE
, objc_get_parm_info (0));
2101 body
= c_begin_compound_stmt (true);
2102 add_stmt (build_function_call
2106 build_unary_op (ADDR_EXPR
,
2107 UOBJC_MODULES_decl
, 0))));
2108 add_stmt (c_end_compound_stmt (body
, true));
2110 TREE_PUBLIC (current_function_decl
) = 0;
2113 /* For Objective-C++, we will need to call __objc_gnu_init
2114 from objc_generate_static_init_call() below. */
2115 DECL_STATIC_CONSTRUCTOR (current_function_decl
) = 1;
2118 GNU_INIT_decl
= current_function_decl
;
2122 pop_lang_context ();
2127 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2128 to be called by the module initializer routine. */
2131 objc_static_init_needed_p (void)
2133 return (GNU_INIT_decl
!= NULL_TREE
);
2136 /* Generate a call to the __objc_gnu_init initializer function. */
2139 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED
)
2141 add_stmt (build_stmt (EXPR_STMT
,
2142 build_function_call (GNU_INIT_decl
, NULL_TREE
)));
2146 #endif /* OBJCPLUS */
2148 /* Return the DECL of the string IDENT in the SECTION. */
2151 get_objc_string_decl (tree ident
, enum string_section section
)
2155 if (section
== class_names
)
2156 chain
= class_names_chain
;
2157 else if (section
== meth_var_names
)
2158 chain
= meth_var_names_chain
;
2159 else if (section
== meth_var_types
)
2160 chain
= meth_var_types_chain
;
2164 for (; chain
!= 0; chain
= TREE_CHAIN (chain
))
2165 if (TREE_VALUE (chain
) == ident
)
2166 return (TREE_PURPOSE (chain
));
2172 /* Output references to all statically allocated objects. Return the DECL
2173 for the array built. */
2176 generate_static_references (void)
2178 tree decls
= NULL_TREE
, expr
= NULL_TREE
;
2179 tree class_name
, class, decl
, initlist
;
2180 tree cl_chain
, in_chain
, type
2181 = build_array_type (build_pointer_type (void_type_node
), NULL_TREE
);
2182 int num_inst
, num_class
;
2185 if (flag_next_runtime
)
2188 for (cl_chain
= objc_static_instances
, num_class
= 0;
2189 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
2191 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
2192 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
2194 sprintf (buf
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
2195 decl
= start_var_decl (type
, buf
);
2197 /* Output {class_name, ...}. */
2198 class = TREE_VALUE (cl_chain
);
2199 class_name
= get_objc_string_decl (OBJC_TYPE_NAME (class), class_names
);
2200 initlist
= build_tree_list (NULL_TREE
,
2201 build_unary_op (ADDR_EXPR
, class_name
, 1));
2203 /* Output {..., instance, ...}. */
2204 for (in_chain
= TREE_PURPOSE (cl_chain
);
2205 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
2207 expr
= build_unary_op (ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
2208 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2211 /* Output {..., NULL}. */
2212 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
2214 expr
= objc_build_constructor (TREE_TYPE (decl
), nreverse (initlist
));
2215 finish_var_decl (decl
, expr
);
2217 = tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, decl
, 1), decls
);
2220 decls
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), decls
);
2221 expr
= objc_build_constructor (type
, nreverse (decls
));
2222 static_instances_decl
= start_var_decl (type
, "_OBJC_STATIC_INSTANCES");
2223 finish_var_decl (static_instances_decl
, expr
);
2226 /* Output all strings. */
2229 generate_strings (void)
2231 tree chain
, string_expr
;
2232 tree string
, decl
, type
;
2234 for (chain
= class_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
2236 string
= TREE_VALUE (chain
);
2237 decl
= TREE_PURPOSE (chain
);
2238 type
= build_array_type
2241 (build_int_cst (NULL_TREE
,
2242 IDENTIFIER_LENGTH (string
))));
2243 decl
= start_var_decl (type
, IDENTIFIER_POINTER (DECL_NAME (decl
)));
2244 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
2245 IDENTIFIER_POINTER (string
));
2246 finish_var_decl (decl
, string_expr
);
2249 for (chain
= meth_var_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
2251 string
= TREE_VALUE (chain
);
2252 decl
= TREE_PURPOSE (chain
);
2253 type
= build_array_type
2256 (build_int_cst (NULL_TREE
,
2257 IDENTIFIER_LENGTH (string
))));
2258 decl
= start_var_decl (type
, IDENTIFIER_POINTER (DECL_NAME (decl
)));
2259 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
2260 IDENTIFIER_POINTER (string
));
2261 finish_var_decl (decl
, string_expr
);
2264 for (chain
= meth_var_types_chain
; chain
; chain
= TREE_CHAIN (chain
))
2266 string
= TREE_VALUE (chain
);
2267 decl
= TREE_PURPOSE (chain
);
2268 type
= build_array_type
2271 (build_int_cst (NULL_TREE
,
2272 IDENTIFIER_LENGTH (string
))));
2273 decl
= start_var_decl (type
, IDENTIFIER_POINTER (DECL_NAME (decl
)));
2274 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
2275 IDENTIFIER_POINTER (string
));
2276 finish_var_decl (decl
, string_expr
);
2280 static GTY(()) int selector_reference_idx
;
2283 build_selector_reference_decl (void)
2288 sprintf (buf
, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx
++);
2289 decl
= start_var_decl (objc_selector_type
, buf
);
2295 build_selector_table_decl (void)
2299 if (flag_typed_selectors
)
2301 build_selector_template ();
2302 temp
= build_array_type (objc_selector_template
, NULL_TREE
);
2305 temp
= build_array_type (objc_selector_type
, NULL_TREE
);
2307 UOBJC_SELECTOR_TABLE_decl
= start_var_decl (temp
, "_OBJC_SELECTOR_TABLE");
2310 /* Just a handy wrapper for add_objc_string. */
2313 build_selector (tree ident
)
2315 return convert (objc_selector_type
,
2316 add_objc_string (ident
, meth_var_names
));
2320 build_selector_translation_table (void)
2322 tree chain
, initlist
= NULL_TREE
;
2324 tree decl
= NULL_TREE
;
2326 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
2330 if (warn_selector
&& objc_implementation_context
)
2334 for (method_chain
= meth_var_names_chain
;
2336 method_chain
= TREE_CHAIN (method_chain
))
2338 if (TREE_VALUE (method_chain
) == TREE_VALUE (chain
))
2345 warning ("%Jcreating selector for nonexistent method %qE",
2346 TREE_PURPOSE (chain
), TREE_VALUE (chain
));
2349 expr
= build_selector (TREE_VALUE (chain
));
2350 /* add one for the '\0' character */
2351 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (chain
)) + 1;
2353 if (flag_next_runtime
)
2355 decl
= TREE_PURPOSE (chain
);
2356 finish_var_decl (decl
, expr
);
2360 if (flag_typed_selectors
)
2362 tree eltlist
= NULL_TREE
;
2363 tree encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
2364 eltlist
= tree_cons (NULL_TREE
, expr
, NULL_TREE
);
2365 eltlist
= tree_cons (NULL_TREE
, encoding
, eltlist
);
2366 expr
= objc_build_constructor (objc_selector_template
,
2367 nreverse (eltlist
));
2370 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2374 if (! flag_next_runtime
)
2376 /* Cause the selector table (previously forward-declared)
2377 to be actually output. */
2378 initlist
= tree_cons (NULL_TREE
,
2379 flag_typed_selectors
2380 ? objc_build_constructor
2381 (objc_selector_template
,
2382 tree_cons (NULL_TREE
,
2383 build_int_cst (NULL_TREE
, 0),
2384 tree_cons (NULL_TREE
,
2385 build_int_cst (NULL_TREE
, 0),
2387 : build_int_cst (NULL_TREE
, 0), initlist
);
2388 initlist
= objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
2389 nreverse (initlist
));
2390 finish_var_decl (UOBJC_SELECTOR_TABLE_decl
, initlist
);
2395 get_proto_encoding (tree proto
)
2400 if (! METHOD_ENCODING (proto
))
2402 encoding
= encode_method_prototype (proto
);
2403 METHOD_ENCODING (proto
) = encoding
;
2406 encoding
= METHOD_ENCODING (proto
);
2408 return add_objc_string (encoding
, meth_var_types
);
2411 return build_int_cst (NULL_TREE
, 0);
2414 /* sel_ref_chain is a list whose "value" fields will be instances of
2415 identifier_node that represent the selector. */
2418 build_typed_selector_reference (tree ident
, tree prototype
)
2420 tree
*chain
= &sel_ref_chain
;
2426 if (TREE_PURPOSE (*chain
) == prototype
&& TREE_VALUE (*chain
) == ident
)
2427 goto return_at_index
;
2430 chain
= &TREE_CHAIN (*chain
);
2433 *chain
= tree_cons (prototype
, ident
, NULL_TREE
);
2436 expr
= build_unary_op (ADDR_EXPR
,
2437 build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2438 build_int_cst (NULL_TREE
, index
)),
2440 return convert (objc_selector_type
, expr
);
2444 build_selector_reference (tree ident
)
2446 tree
*chain
= &sel_ref_chain
;
2452 if (TREE_VALUE (*chain
) == ident
)
2453 return (flag_next_runtime
2454 ? TREE_PURPOSE (*chain
)
2455 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2456 build_int_cst (NULL_TREE
, index
)));
2459 chain
= &TREE_CHAIN (*chain
);
2462 expr
= (flag_next_runtime
? build_selector_reference_decl (): NULL_TREE
);
2464 *chain
= tree_cons (expr
, ident
, NULL_TREE
);
2466 return (flag_next_runtime
2468 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2469 build_int_cst (NULL_TREE
, index
)));
2472 static GTY(()) int class_reference_idx
;
2475 build_class_reference_decl (void)
2480 sprintf (buf
, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx
++);
2481 decl
= start_var_decl (objc_class_type
, buf
);
2486 /* Create a class reference, but don't create a variable to reference
2490 add_class_reference (tree ident
)
2494 if ((chain
= cls_ref_chain
))
2499 if (ident
== TREE_VALUE (chain
))
2503 chain
= TREE_CHAIN (chain
);
2507 /* Append to the end of the list */
2508 TREE_CHAIN (tail
) = tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2511 cls_ref_chain
= tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2514 /* Get a class reference, creating it if necessary. Also create the
2515 reference variable. */
2518 objc_get_class_reference (tree ident
)
2523 if (processing_template_decl
)
2524 /* Must wait until template instantiation time. */
2525 return build_min_nt (CLASS_REFERENCE_EXPR
, ident
);
2526 if (TREE_CODE (ident
) == TYPE_DECL
)
2527 ident
= DECL_NAME (ident
);
2531 if (!(ident
= objc_is_class_name (ident
)))
2533 error ("%qs is not an Objective-C class name or alias",
2534 IDENTIFIER_POINTER (orig_ident
));
2535 return error_mark_node
;
2538 if (flag_next_runtime
&& !flag_zero_link
)
2543 for (chain
= &cls_ref_chain
; *chain
; chain
= &TREE_CHAIN (*chain
))
2544 if (TREE_VALUE (*chain
) == ident
)
2546 if (! TREE_PURPOSE (*chain
))
2547 TREE_PURPOSE (*chain
) = build_class_reference_decl ();
2549 return TREE_PURPOSE (*chain
);
2552 decl
= build_class_reference_decl ();
2553 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2560 add_class_reference (ident
);
2562 params
= build_tree_list (NULL_TREE
,
2563 my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
2564 IDENTIFIER_POINTER (ident
)));
2566 assemble_external (objc_get_class_decl
);
2567 return build_function_call (objc_get_class_decl
, params
);
2571 /* For each string section we have a chain which maps identifier nodes
2572 to decls for the strings. */
2575 add_objc_string (tree ident
, enum string_section section
)
2579 if (section
== class_names
)
2580 chain
= &class_names_chain
;
2581 else if (section
== meth_var_names
)
2582 chain
= &meth_var_names_chain
;
2583 else if (section
== meth_var_types
)
2584 chain
= &meth_var_types_chain
;
2590 if (TREE_VALUE (*chain
) == ident
)
2591 return convert (string_type_node
,
2592 build_unary_op (ADDR_EXPR
, TREE_PURPOSE (*chain
), 1));
2594 chain
= &TREE_CHAIN (*chain
);
2597 decl
= build_objc_string_decl (section
);
2599 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2601 return convert (string_type_node
, build_unary_op (ADDR_EXPR
, decl
, 1));
2604 static GTY(()) int class_names_idx
;
2605 static GTY(()) int meth_var_names_idx
;
2606 static GTY(()) int meth_var_types_idx
;
2609 build_objc_string_decl (enum string_section section
)
2614 if (section
== class_names
)
2615 sprintf (buf
, "_OBJC_CLASS_NAME_%d", class_names_idx
++);
2616 else if (section
== meth_var_names
)
2617 sprintf (buf
, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx
++);
2618 else if (section
== meth_var_types
)
2619 sprintf (buf
, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx
++);
2621 ident
= get_identifier (buf
);
2623 decl
= build_decl (VAR_DECL
, ident
, build_array_type (char_type_node
, 0));
2624 DECL_EXTERNAL (decl
) = 1;
2625 TREE_PUBLIC (decl
) = 0;
2626 TREE_USED (decl
) = 1;
2627 TREE_CONSTANT (decl
) = 1;
2628 DECL_CONTEXT (decl
) = 0;
2629 DECL_ARTIFICIAL (decl
) = 1;
2631 DECL_THIS_STATIC (decl
) = 1; /* squash redeclaration errors */
2634 make_decl_rtl (decl
);
2635 pushdecl_top_level (decl
);
2642 objc_declare_alias (tree alias_ident
, tree class_ident
)
2644 tree underlying_class
;
2647 if (current_namespace
!= global_namespace
) {
2648 error ("Objective-C declarations may only appear in global scope");
2650 #endif /* OBJCPLUS */
2652 if (!(underlying_class
= objc_is_class_name (class_ident
)))
2653 warning ("cannot find class %qs", IDENTIFIER_POINTER (class_ident
));
2654 else if (objc_is_class_name (alias_ident
))
2655 warning ("class %qs already exists", IDENTIFIER_POINTER (alias_ident
));
2657 alias_chain
= tree_cons (underlying_class
, alias_ident
, alias_chain
);
2661 objc_declare_class (tree ident_list
)
2665 if (current_namespace
!= global_namespace
) {
2666 error ("Objective-C declarations may only appear in global scope");
2668 #endif /* OBJCPLUS */
2670 for (list
= ident_list
; list
; list
= TREE_CHAIN (list
))
2672 tree ident
= TREE_VALUE (list
);
2674 if (! objc_is_class_name (ident
))
2676 tree record
= lookup_name (ident
), type
= record
;
2680 if (TREE_CODE (record
) == TYPE_DECL
)
2681 type
= DECL_ORIGINAL_TYPE (record
);
2683 if (!TYPE_HAS_OBJC_INFO (type
)
2684 || !TYPE_OBJC_INTERFACE (type
))
2686 error ("%qs redeclared as different kind of symbol",
2687 IDENTIFIER_POINTER (ident
));
2688 error ("%Jprevious declaration of '%D'",
2693 record
= xref_tag (RECORD_TYPE
, ident
);
2694 INIT_TYPE_OBJC_INFO (record
);
2695 TYPE_OBJC_INTERFACE (record
) = ident
;
2696 class_chain
= tree_cons (NULL_TREE
, ident
, class_chain
);
2702 objc_is_class_name (tree ident
)
2706 if (ident
&& TREE_CODE (ident
) == IDENTIFIER_NODE
2707 && identifier_global_value (ident
))
2708 ident
= identifier_global_value (ident
);
2709 while (ident
&& TREE_CODE (ident
) == TYPE_DECL
&& DECL_ORIGINAL_TYPE (ident
))
2710 ident
= OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident
));
2712 if (ident
&& TREE_CODE (ident
) == RECORD_TYPE
)
2713 ident
= OBJC_TYPE_NAME (ident
);
2715 if (ident
&& TREE_CODE (ident
) == TYPE_DECL
)
2716 ident
= DECL_NAME (ident
);
2718 if (!ident
|| TREE_CODE (ident
) != IDENTIFIER_NODE
)
2721 if (lookup_interface (ident
))
2724 for (chain
= class_chain
; chain
; chain
= TREE_CHAIN (chain
))
2726 if (ident
== TREE_VALUE (chain
))
2730 for (chain
= alias_chain
; chain
; chain
= TREE_CHAIN (chain
))
2732 if (ident
== TREE_VALUE (chain
))
2733 return TREE_PURPOSE (chain
);
2739 /* Check whether TYPE is either 'id' or 'Class'. */
2742 objc_is_id (tree type
)
2744 if (type
&& TREE_CODE (type
) == IDENTIFIER_NODE
2745 && identifier_global_value (type
))
2746 type
= identifier_global_value (type
);
2748 if (type
&& TREE_CODE (type
) == TYPE_DECL
)
2749 type
= TREE_TYPE (type
);
2751 /* NB: This function may be called before the ObjC front-end has
2752 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
2753 return (objc_object_type
&& type
2754 && (IS_ID (type
) || IS_CLASS (type
) || IS_SUPER (type
))
2759 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
2760 class instance. This is needed by other parts of the compiler to
2761 handle ObjC types gracefully. */
2764 objc_is_object_ptr (tree type
)
2768 type
= TYPE_MAIN_VARIANT (type
);
2769 if (!POINTER_TYPE_P (type
))
2772 ret
= objc_is_id (type
);
2774 ret
= objc_is_class_name (TREE_TYPE (type
));
2780 lookup_interface (tree ident
)
2785 if (ident
&& TREE_CODE (ident
) == TYPE_DECL
)
2786 ident
= DECL_NAME (ident
);
2788 for (chain
= interface_chain
; chain
; chain
= TREE_CHAIN (chain
))
2790 if (ident
== CLASS_NAME (chain
))
2796 /* Implement @defs (<classname>) within struct bodies. */
2799 objc_get_class_ivars (tree class_name
)
2801 tree interface
= lookup_interface (class_name
);
2804 return get_class_ivars (interface
);
2806 error ("cannot find interface declaration for %qs",
2807 IDENTIFIER_POINTER (class_name
));
2809 return error_mark_node
;
2812 /* Used by: build_private_template, continue_class,
2813 and for @defs constructs. */
2816 get_class_ivars (tree interface
)
2818 tree ivar_chain
= copy_list (CLASS_RAW_IVARS (interface
));
2820 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
2821 by the current class (i.e., they do not include super-class ivars).
2822 However, the CLASS_IVARS list will be side-effected by a call to
2823 finish_struct(), which will fill in field offsets. */
2824 if (!CLASS_IVARS (interface
))
2825 CLASS_IVARS (interface
) = ivar_chain
;
2827 while (CLASS_SUPER_NAME (interface
))
2829 /* Prepend super-class ivars. */
2830 interface
= lookup_interface (CLASS_SUPER_NAME (interface
));
2831 ivar_chain
= chainon (copy_list (CLASS_RAW_IVARS (interface
)),
2839 objc_create_temporary_var (tree type
)
2843 decl
= build_decl (VAR_DECL
, NULL_TREE
, type
);
2844 TREE_USED (decl
) = 1;
2845 DECL_ARTIFICIAL (decl
) = 1;
2846 DECL_IGNORED_P (decl
) = 1;
2847 DECL_CONTEXT (decl
) = current_function_decl
;
2852 /* Exception handling constructs. We begin by having the parser do most
2853 of the work and passing us blocks. What we do next depends on whether
2854 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
2855 We abstract all of this in a handful of appropriately named routines. */
2857 /* Stack of open try blocks. */
2859 struct objc_try_context
2861 struct objc_try_context
*outer
;
2863 /* Statements (or statement lists) as processed by the parser. */
2867 /* Some file position locations. */
2868 location_t try_locus
;
2869 location_t end_try_locus
;
2870 location_t end_catch_locus
;
2871 location_t finally_locus
;
2872 location_t end_finally_locus
;
2874 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
2875 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
2878 /* The CATCH_EXPR of an open @catch clause. */
2881 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
2887 static struct objc_try_context
*cur_try_context
;
2889 /* This hook, called via lang_eh_runtime_type, generates a runtime object
2890 that represents TYPE. For Objective-C, this is just the class name. */
2891 /* ??? Isn't there a class object or some such? Is it easy to get? */
2895 objc_eh_runtime_type (tree type
)
2897 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type
)), class_names
);
2901 /* Initialize exception handling. */
2904 objc_init_exceptions (void)
2906 static bool done
= false;
2911 if (flag_objc_sjlj_exceptions
)
2913 /* On Darwin, ObjC exceptions require a sufficiently recent
2914 version of the runtime, so the user must ask for them explicitly. */
2915 if (!flag_objc_exceptions
)
2916 warning ("use %<-fobjc-exceptions%> to enable Objective-C "
2917 "exception syntax");
2922 c_eh_initialized_p
= true;
2923 eh_personality_libfunc
2924 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
2925 ? "__gnu_objc_personality_sj0"
2926 : "__gnu_objc_personality_v0");
2927 using_eh_for_cleanups ();
2928 lang_eh_runtime_type
= objc_eh_runtime_type
;
2933 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
2934 we'll arrange for it to be initialized (and associated with a binding)
2938 objc_build_exc_ptr (void)
2940 if (flag_objc_sjlj_exceptions
)
2942 tree var
= cur_try_context
->caught_decl
;
2945 var
= objc_create_temporary_var (objc_object_type
);
2946 cur_try_context
->caught_decl
= var
;
2951 return build (EXC_PTR_EXPR
, objc_object_type
);
2954 /* Build "objc_exception_try_exit(&_stack)". */
2957 next_sjlj_build_try_exit (void)
2960 t
= build_fold_addr_expr (cur_try_context
->stack_decl
);
2961 t
= tree_cons (NULL
, t
, NULL
);
2962 t
= build_function_call (objc_exception_try_exit_decl
, t
);
2967 objc_exception_try_enter (&_stack);
2968 if (_setjmp(&_stack.buf))
2972 Return the COND_EXPR. Note that the THEN and ELSE fields are left
2973 empty, ready for the caller to fill them in. */
2976 next_sjlj_build_enter_and_setjmp (void)
2978 tree t
, enter
, sj
, cond
;
2980 t
= build_fold_addr_expr (cur_try_context
->stack_decl
);
2981 t
= tree_cons (NULL
, t
, NULL
);
2982 enter
= build_function_call (objc_exception_try_enter_decl
, t
);
2984 t
= build_component_ref (cur_try_context
->stack_decl
,
2985 get_identifier ("buf"));
2986 t
= build_fold_addr_expr (t
);
2987 t
= convert (ptr_type_node
, t
);
2988 t
= tree_cons (NULL
, t
, NULL
);
2989 sj
= build_function_call (objc_setjmp_decl
, t
);
2991 cond
= build (COMPOUND_EXPR
, TREE_TYPE (sj
), enter
, sj
);
2992 cond
= lang_hooks
.truthvalue_conversion (cond
);
2994 return build (COND_EXPR
, void_type_node
, cond
, NULL
, NULL
);
2998 DECL = objc_exception_extract(&_stack);
3002 next_sjlj_build_exc_extract (tree decl
)
3006 t
= build_fold_addr_expr (cur_try_context
->stack_decl
);
3007 t
= tree_cons (NULL
, t
, NULL
);
3008 t
= build_function_call (objc_exception_extract_decl
, t
);
3009 t
= convert (TREE_TYPE (decl
), t
);
3010 t
= build (MODIFY_EXPR
, void_type_node
, decl
, t
);
3016 if (objc_exception_match(obj_get_class(TYPE), _caught)
3023 objc_exception_try_exit(&_stack);
3025 from the sequence of CATCH_EXPRs in the current try context. */
3028 next_sjlj_build_catch_list (void)
3030 tree_stmt_iterator i
= tsi_start (cur_try_context
->catch_list
);
3032 tree
*last
= &catch_seq
;
3033 bool saw_id
= false;
3035 for (; !tsi_end_p (i
); tsi_next (&i
))
3037 tree stmt
= tsi_stmt (i
);
3038 tree type
= CATCH_TYPES (stmt
);
3039 tree body
= CATCH_BODY (stmt
);
3051 if (type
== error_mark_node
)
3052 cond
= error_mark_node
;
3055 args
= tree_cons (NULL
, cur_try_context
->caught_decl
, NULL
);
3056 t
= objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type
)));
3057 args
= tree_cons (NULL
, t
, args
);
3058 t
= build_function_call (objc_exception_match_decl
, args
);
3059 cond
= lang_hooks
.truthvalue_conversion (t
);
3061 t
= build (COND_EXPR
, void_type_node
, cond
, body
, NULL
);
3062 SET_EXPR_LOCUS (t
, EXPR_LOCUS (stmt
));
3065 last
= &COND_EXPR_ELSE (t
);
3071 t
= build (MODIFY_EXPR
, void_type_node
, cur_try_context
->rethrow_decl
,
3072 cur_try_context
->caught_decl
);
3073 SET_EXPR_LOCATION (t
, cur_try_context
->end_catch_locus
);
3074 append_to_statement_list (t
, last
);
3076 t
= next_sjlj_build_try_exit ();
3077 SET_EXPR_LOCATION (t
, cur_try_context
->end_catch_locus
);
3078 append_to_statement_list (t
, last
);
3084 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
3085 exception handling. We aim to build:
3088 struct _objc_exception_data _stack;
3089 id volatile _rethrow = 0;
3092 objc_exception_try_enter (&_stack);
3093 if (_setjmp(&_stack.buf))
3095 id _caught = objc_exception_extract(&_stack);
3096 objc_exception_try_enter (&_stack);
3097 if (_setjmp(&_stack.buf))
3098 _rethrow = objc_exception_extract(&_stack);
3108 objc_exception_try_exit(&_stack);
3111 objc_exception_throw(_rethrow);
3115 If CATCH-LIST is empty, we can omit all of the block containing
3116 "_caught" except for the setting of _rethrow. Note the use of
3117 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
3118 but handles goto and other exits from the block. */
3121 next_sjlj_build_try_catch_finally (void)
3123 tree rethrow_decl
, stack_decl
, t
;
3124 tree catch_seq
, try_fin
, bind
;
3126 /* Create the declarations involved. */
3127 t
= xref_tag (RECORD_TYPE
, get_identifier (UTAG_EXCDATA
));
3128 stack_decl
= objc_create_temporary_var (t
);
3129 cur_try_context
->stack_decl
= stack_decl
;
3131 rethrow_decl
= objc_create_temporary_var (objc_object_type
);
3132 cur_try_context
->rethrow_decl
= rethrow_decl
;
3133 TREE_THIS_VOLATILE (rethrow_decl
) = 1;
3134 TREE_CHAIN (rethrow_decl
) = stack_decl
;
3136 /* Build the outermost variable binding level. */
3137 bind
= build (BIND_EXPR
, void_type_node
, rethrow_decl
, NULL
, NULL
);
3138 SET_EXPR_LOCATION (bind
, cur_try_context
->try_locus
);
3139 TREE_SIDE_EFFECTS (bind
) = 1;
3141 /* Initialize rethrow_decl. */
3142 t
= build (MODIFY_EXPR
, void_type_node
, rethrow_decl
,
3143 convert (objc_object_type
, null_pointer_node
));
3144 SET_EXPR_LOCATION (t
, cur_try_context
->try_locus
);
3145 append_to_statement_list (t
, &BIND_EXPR_BODY (bind
));
3147 /* Build the outermost TRY_FINALLY_EXPR. */
3148 try_fin
= build (TRY_FINALLY_EXPR
, void_type_node
, NULL
, NULL
);
3149 SET_EXPR_LOCATION (try_fin
, cur_try_context
->try_locus
);
3150 TREE_SIDE_EFFECTS (try_fin
) = 1;
3151 append_to_statement_list (try_fin
, &BIND_EXPR_BODY (bind
));
3153 /* Create the complete catch sequence. */
3154 if (cur_try_context
->catch_list
)
3156 tree caught_decl
= objc_build_exc_ptr ();
3157 catch_seq
= build_stmt (BIND_EXPR
, caught_decl
, NULL
, NULL
);
3159 t
= next_sjlj_build_exc_extract (caught_decl
);
3160 append_to_statement_list (t
, &BIND_EXPR_BODY (catch_seq
));
3162 t
= next_sjlj_build_enter_and_setjmp ();
3163 COND_EXPR_THEN (t
) = next_sjlj_build_exc_extract (rethrow_decl
);
3164 COND_EXPR_ELSE (t
) = next_sjlj_build_catch_list ();
3165 append_to_statement_list (t
, &BIND_EXPR_BODY (catch_seq
));
3168 catch_seq
= next_sjlj_build_exc_extract (rethrow_decl
);
3169 SET_EXPR_LOCATION (catch_seq
, cur_try_context
->end_try_locus
);
3171 /* Build the main register-and-try if statement. */
3172 t
= next_sjlj_build_enter_and_setjmp ();
3173 SET_EXPR_LOCATION (t
, cur_try_context
->try_locus
);
3174 COND_EXPR_THEN (t
) = catch_seq
;
3175 COND_EXPR_ELSE (t
) = cur_try_context
->try_body
;
3176 TREE_OPERAND (try_fin
, 0) = t
;
3178 /* Build the complete FINALLY statement list. */
3179 t
= next_sjlj_build_try_exit ();
3180 t
= build_stmt (COND_EXPR
,
3181 lang_hooks
.truthvalue_conversion (rethrow_decl
),
3183 SET_EXPR_LOCATION (t
, cur_try_context
->finally_locus
);
3184 append_to_statement_list (t
, &TREE_OPERAND (try_fin
, 1));
3186 append_to_statement_list (cur_try_context
->finally_body
,
3187 &TREE_OPERAND (try_fin
, 1));
3189 t
= tree_cons (NULL
, rethrow_decl
, NULL
);
3190 t
= build_function_call (objc_exception_throw_decl
, t
);
3191 t
= build_stmt (COND_EXPR
,
3192 lang_hooks
.truthvalue_conversion (rethrow_decl
),
3194 SET_EXPR_LOCATION (t
, cur_try_context
->end_finally_locus
);
3195 append_to_statement_list (t
, &TREE_OPERAND (try_fin
, 1));
3200 /* Called just after parsing the @try and its associated BODY. We now
3201 must prepare for the tricky bits -- handling the catches and finally. */
3204 objc_begin_try_stmt (location_t try_locus
, tree body
)
3206 struct objc_try_context
*c
= xcalloc (1, sizeof (*c
));
3207 c
->outer
= cur_try_context
;
3209 c
->try_locus
= try_locus
;
3210 c
->end_try_locus
= input_location
;
3211 cur_try_context
= c
;
3213 objc_init_exceptions ();
3216 /* Called just after parsing "@catch (parm)". Open a binding level,
3217 enter DECL into the binding level, and initialize it. Leave the
3218 binding level open while the body of the compound statement is parsed. */
3221 objc_begin_catch_clause (tree decl
)
3223 tree compound
, type
, t
;
3225 /* Begin a new scope that the entire catch clause will live in. */
3226 compound
= c_begin_compound_stmt (true);
3228 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
3229 decl
= build_decl (VAR_DECL
, DECL_NAME (decl
), TREE_TYPE (decl
));
3230 lang_hooks
.decls
.pushdecl (decl
);
3232 /* Since a decl is required here by syntax, don't warn if its unused. */
3233 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3234 be what the previous objc implementation did. */
3235 TREE_USED (decl
) = 1;
3237 /* Verify that the type of the catch is valid. It must be a pointer
3238 to an Objective-C class, or "id" (which is catch-all). */
3239 type
= TREE_TYPE (decl
);
3241 if (POINTER_TYPE_P (type
) && objc_is_object_id (TREE_TYPE (type
)))
3243 else if (!POINTER_TYPE_P (type
) || !TYPED_OBJECT (TREE_TYPE (type
)))
3245 error ("@catch parameter is not a known Objective-C class type");
3246 type
= error_mark_node
;
3248 else if (cur_try_context
->catch_list
)
3250 /* Examine previous @catch clauses and see if we've already
3251 caught the type in question. */
3252 tree_stmt_iterator i
= tsi_start (cur_try_context
->catch_list
);
3253 for (; !tsi_end_p (i
); tsi_next (&i
))
3255 tree stmt
= tsi_stmt (i
);
3256 t
= CATCH_TYPES (stmt
);
3257 if (t
== error_mark_node
)
3259 if (!t
|| objc_comptypes (TREE_TYPE (t
), TREE_TYPE (type
), 0) == 1)
3261 warning ("exception of type %<%T%> will be caught",
3263 warning ("%H by earlier handler for %<%T%>",
3264 EXPR_LOCUS (stmt
), TREE_TYPE (t
? t
: objc_object_type
));
3270 /* Record the data for the catch in the try context so that we can
3271 finalize it later. */
3272 t
= build_stmt (CATCH_EXPR
, type
, compound
);
3273 cur_try_context
->current_catch
= t
;
3275 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3276 t
= objc_build_exc_ptr ();
3277 t
= convert (TREE_TYPE (decl
), t
);
3278 t
= build (MODIFY_EXPR
, void_type_node
, decl
, t
);
3282 /* Called just after parsing the closing brace of a @catch clause. Close
3283 the open binding level, and record a CATCH_EXPR for it. */
3286 objc_finish_catch_clause (void)
3288 tree c
= cur_try_context
->current_catch
;
3289 cur_try_context
->current_catch
= NULL
;
3290 cur_try_context
->end_catch_locus
= input_location
;
3292 CATCH_BODY (c
) = c_end_compound_stmt (CATCH_BODY (c
), 1);
3293 append_to_statement_list (c
, &cur_try_context
->catch_list
);
3296 /* Called after parsing a @finally clause and its associated BODY.
3297 Record the body for later placement. */
3300 objc_build_finally_clause (location_t finally_locus
, tree body
)
3302 cur_try_context
->finally_body
= body
;
3303 cur_try_context
->finally_locus
= finally_locus
;
3304 cur_try_context
->end_finally_locus
= input_location
;
3307 /* Called to finalize a @try construct. */
3310 objc_finish_try_stmt (void)
3312 struct objc_try_context
*c
= cur_try_context
;
3315 if (c
->catch_list
== NULL
&& c
->finally_body
== NULL
)
3316 error ("%<@try%> without %<@catch%> or %<@finally%>");
3318 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3319 if (flag_objc_sjlj_exceptions
)
3321 if (!cur_try_context
->finally_body
)
3323 cur_try_context
->finally_locus
= input_location
;
3324 cur_try_context
->end_finally_locus
= input_location
;
3326 stmt
= next_sjlj_build_try_catch_finally ();
3330 /* Otherwise, nest the CATCH inside a FINALLY. */
3334 stmt
= build_stmt (TRY_CATCH_EXPR
, stmt
, c
->catch_list
);
3335 SET_EXPR_LOCATION (stmt
, cur_try_context
->try_locus
);
3337 if (c
->finally_body
)
3339 stmt
= build_stmt (TRY_FINALLY_EXPR
, stmt
, c
->finally_body
);
3340 SET_EXPR_LOCATION (stmt
, cur_try_context
->try_locus
);
3345 cur_try_context
= c
->outer
;
3350 objc_build_throw_stmt (tree throw_expr
)
3354 objc_init_exceptions ();
3356 if (throw_expr
== NULL
)
3358 /* If we're not inside a @catch block, there is no "current
3359 exception" to be rethrown. */
3360 if (cur_try_context
== NULL
3361 || cur_try_context
->current_catch
== NULL
)
3363 error ("%<@throw%> (rethrow) used outside of a @catch block");
3367 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3368 value that we get from the runtime. */
3369 throw_expr
= objc_build_exc_ptr ();
3372 /* A throw is just a call to the runtime throw function with the
3373 object as a parameter. */
3374 args
= tree_cons (NULL
, throw_expr
, NULL
);
3375 return add_stmt (build_function_call (objc_exception_throw_decl
, args
));
3379 objc_build_synchronized (location_t start_locus
, tree mutex
, tree body
)
3383 /* First lock the mutex. */
3384 mutex
= save_expr (mutex
);
3385 args
= tree_cons (NULL
, mutex
, NULL
);
3386 call
= build_function_call (objc_sync_enter_decl
, args
);
3387 SET_EXPR_LOCATION (call
, start_locus
);
3390 /* Build the mutex unlock. */
3391 args
= tree_cons (NULL
, mutex
, NULL
);
3392 call
= build_function_call (objc_sync_exit_decl
, args
);
3393 SET_EXPR_LOCATION (call
, input_location
);
3395 /* Put the that and the body in a TRY_FINALLY. */
3396 objc_begin_try_stmt (start_locus
, body
);
3397 objc_build_finally_clause (input_location
, call
);
3398 objc_finish_try_stmt ();
3402 /* Predefine the following data type:
3404 struct _objc_exception_data
3410 /* The following yuckiness should prevent users from having to #include
3411 <setjmp.h> in their code... */
3413 #ifdef TARGET_POWERPC
3414 /* snarfed from /usr/include/ppc/setjmp.h */
3415 #define _JBLEN (26 + 36 + 129 + 1)
3417 /* snarfed from /usr/include/i386/{setjmp,signal}.h */
3422 build_next_objc_exception_stuff (void)
3424 tree field_decl
, field_decl_chain
, index
, temp_type
;
3426 objc_exception_data_template
3427 = start_struct (RECORD_TYPE
, get_identifier (UTAG_EXCDATA
));
3429 /* int buf[_JBLEN]; */
3431 index
= build_index_type (build_int_cst (NULL_TREE
, _JBLEN
- 1));
3432 field_decl
= create_field_decl (build_array_type (integer_type_node
, index
),
3434 field_decl_chain
= field_decl
;
3436 /* void *pointers[4]; */
3438 index
= build_index_type (build_int_cst (NULL_TREE
, 4 - 1));
3439 field_decl
= create_field_decl (build_array_type (ptr_type_node
, index
),
3441 chainon (field_decl_chain
, field_decl
);
3443 finish_struct (objc_exception_data_template
, field_decl_chain
, NULL_TREE
);
3445 /* int _setjmp(...); */
3446 /* If the user includes <setjmp.h>, this shall be superseded by
3447 'int _setjmp(jmp_buf);' */
3448 temp_type
= build_function_type (integer_type_node
, NULL_TREE
);
3450 = builtin_function (TAG_SETJMP
, temp_type
, 0, NOT_BUILT_IN
, NULL
, NULL_TREE
);
3452 /* id objc_exception_extract(struct _objc_exception_data *); */
3454 = build_function_type (objc_object_type
,
3455 tree_cons (NULL_TREE
,
3456 build_pointer_type (objc_exception_data_template
),
3458 objc_exception_extract_decl
3459 = builtin_function (TAG_EXCEPTIONEXTRACT
, temp_type
, 0, NOT_BUILT_IN
, NULL
, NULL_TREE
);
3460 /* void objc_exception_try_enter(struct _objc_exception_data *); */
3461 /* void objc_exception_try_exit(struct _objc_exception_data *); */
3463 = build_function_type (void_type_node
,
3464 tree_cons (NULL_TREE
,
3465 build_pointer_type (objc_exception_data_template
),
3467 objc_exception_try_enter_decl
3468 = builtin_function (TAG_EXCEPTIONTRYENTER
, temp_type
, 0, NOT_BUILT_IN
, NULL
, NULL_TREE
);
3469 objc_exception_try_exit_decl
3470 = builtin_function (TAG_EXCEPTIONTRYEXIT
, temp_type
, 0, NOT_BUILT_IN
, NULL
, NULL_TREE
);
3472 /* int objc_exception_match(id, id); */
3474 = build_function_type (integer_type_node
,
3475 tree_cons (NULL_TREE
, objc_object_type
,
3476 tree_cons (NULL_TREE
, objc_object_type
,
3477 OBJC_VOID_AT_END
)));
3478 objc_exception_match_decl
3479 = builtin_function (TAG_EXCEPTIONMATCH
, temp_type
, 0, NOT_BUILT_IN
, NULL
, NULL_TREE
);
3483 build_objc_exception_stuff (void)
3485 tree noreturn_list
, nothrow_list
, temp_type
;
3487 noreturn_list
= tree_cons (get_identifier ("noreturn"), NULL
, NULL
);
3488 nothrow_list
= tree_cons (get_identifier ("nothrow"), NULL
, NULL
);
3490 /* void objc_exception_throw(id) __attribute__((noreturn)); */
3491 /* void objc_sync_enter(id); */
3492 /* void objc_sync_exit(id); */
3493 temp_type
= build_function_type (void_type_node
,
3494 tree_cons (NULL_TREE
, objc_object_type
,
3496 objc_exception_throw_decl
3497 = builtin_function (TAG_EXCEPTIONTHROW
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
3499 objc_sync_enter_decl
3500 = builtin_function (TAG_SYNCENTER
, temp_type
, 0, NOT_BUILT_IN
,
3501 NULL
, nothrow_list
);
3503 = builtin_function (TAG_SYNCEXIT
, temp_type
, 0, NOT_BUILT_IN
,
3504 NULL
, nothrow_list
);
3507 /* Construct a C struct corresponding to ObjC class CLASS, with the same
3510 struct <classname> {
3511 struct _objc_class *isa;
3516 build_private_template (tree
class)
3518 if (!CLASS_STATIC_TEMPLATE (class))
3520 tree record
= start_struct (RECORD_TYPE
, CLASS_NAME (class));
3522 finish_struct (record
, get_class_ivars (class), NULL_TREE
);
3523 /* mark this record as class template - for class type checking */
3524 INIT_TYPE_OBJC_INFO (record
);
3525 TYPE_OBJC_INTERFACE (record
) = class;
3526 CLASS_STATIC_TEMPLATE (class) = record
;
3530 /* Begin code generation for protocols... */
3532 /* struct _objc_protocol {
3533 struct _objc_class *isa;
3534 char *protocol_name;
3535 struct _objc_protocol **protocol_list;
3536 struct _objc__method_prototype_list *instance_methods;
3537 struct _objc__method_prototype_list *class_methods;
3541 build_protocol_template (void)
3543 tree field_decl
, field_decl_chain
;
3545 objc_protocol_template
= start_struct (RECORD_TYPE
,
3546 get_identifier (UTAG_PROTOCOL
));
3548 /* struct _objc_class *isa; */
3549 field_decl
= create_field_decl (build_pointer_type
3550 (xref_tag (RECORD_TYPE
,
3551 get_identifier (UTAG_CLASS
))),
3553 field_decl_chain
= field_decl
;
3555 /* char *protocol_name; */
3556 field_decl
= create_field_decl (string_type_node
, "protocol_name");
3557 chainon (field_decl_chain
, field_decl
);
3559 /* struct _objc_protocol **protocol_list; */
3560 field_decl
= create_field_decl (build_pointer_type
3562 (objc_protocol_template
)),
3564 chainon (field_decl_chain
, field_decl
);
3566 /* struct objc_method_list *instance_methods; */
3567 field_decl
= create_field_decl (build_pointer_type
3568 (xref_tag (RECORD_TYPE
,
3570 (UTAG_METHOD_PROTOTYPE_LIST
))),
3571 "instance_methods");
3572 chainon (field_decl_chain
, field_decl
);
3574 /* struct objc_method_list *class_methods; */
3575 field_decl
= create_field_decl (build_pointer_type
3576 (xref_tag (RECORD_TYPE
,
3578 (UTAG_METHOD_PROTOTYPE_LIST
))),
3580 chainon (field_decl_chain
, field_decl
);
3582 finish_struct (objc_protocol_template
, field_decl_chain
, NULL_TREE
);
3586 build_descriptor_table_initializer (tree type
, tree entries
)
3588 tree initlist
= NULL_TREE
;
3592 tree eltlist
= NULL_TREE
;
3595 = tree_cons (NULL_TREE
,
3596 build_selector (METHOD_SEL_NAME (entries
)), NULL_TREE
);
3598 = tree_cons (NULL_TREE
,
3599 add_objc_string (METHOD_ENCODING (entries
),
3604 = tree_cons (NULL_TREE
,
3605 objc_build_constructor (type
, nreverse (eltlist
)),
3608 entries
= TREE_CHAIN (entries
);
3612 return objc_build_constructor (build_array_type (type
, 0),
3613 nreverse (initlist
));
3616 /* struct objc_method_prototype_list {
3618 struct objc_method_prototype {
3625 build_method_prototype_list_template (tree list_type
, int size
)
3627 tree objc_ivar_list_record
;
3628 tree field_decl
, field_decl_chain
;
3630 /* Generate an unnamed struct definition. */
3632 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3634 /* int method_count; */
3635 field_decl
= create_field_decl (integer_type_node
, "method_count");
3636 field_decl_chain
= field_decl
;
3638 /* struct objc_method method_list[]; */
3639 field_decl
= create_field_decl (build_array_type
3642 (build_int_cst (NULL_TREE
, size
- 1))),
3644 chainon (field_decl_chain
, field_decl
);
3646 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3648 return objc_ivar_list_record
;
3652 build_method_prototype_template (void)
3655 tree field_decl
, field_decl_chain
;
3658 = start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD_PROTOTYPE
));
3661 field_decl
= create_field_decl (objc_selector_type
, "_cmd");
3662 field_decl_chain
= field_decl
;
3664 /* char *method_types; */
3665 field_decl
= create_field_decl (string_type_node
, "method_types");
3666 chainon (field_decl_chain
, field_decl
);
3668 finish_struct (proto_record
, field_decl_chain
, NULL_TREE
);
3670 return proto_record
;
3674 objc_method_parm_type (tree type
)
3676 type
= TREE_VALUE (TREE_TYPE (type
));
3677 if (TREE_CODE (type
) == TYPE_DECL
)
3678 type
= TREE_TYPE (type
);
3679 return TYPE_MAIN_VARIANT (type
);
3683 objc_encoded_type_size (tree type
)
3685 int sz
= int_size_in_bytes (type
);
3687 /* Make all integer and enum types at least as large
3689 if (sz
> 0 && INTEGRAL_TYPE_P (type
))
3690 sz
= MAX (sz
, int_size_in_bytes (integer_type_node
));
3691 /* Treat arrays as pointers, since that's how they're
3693 else if (TREE_CODE (type
) == ARRAY_TYPE
)
3694 sz
= int_size_in_bytes (ptr_type_node
);
3699 encode_method_prototype (tree method_decl
)
3706 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
3707 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl
)));
3709 /* Encode return type. */
3710 encode_type (objc_method_parm_type (method_decl
),
3711 obstack_object_size (&util_obstack
),
3712 OBJC_ENCODE_INLINE_DEFS
);
3715 /* The first two arguments (self and _cmd) are pointers; account for
3717 i
= int_size_in_bytes (ptr_type_node
);
3718 parm_offset
= 2 * i
;
3719 for (parms
= METHOD_SEL_ARGS (method_decl
); parms
;
3720 parms
= TREE_CHAIN (parms
))
3722 tree type
= objc_method_parm_type (parms
);
3723 int sz
= objc_encoded_type_size (type
);
3725 /* If a type size is not known, bail out. */
3728 error ("%Jtype '%D' does not have a known size",
3730 /* Pretend that the encoding succeeded; the compilation will
3731 fail nevertheless. */
3732 goto finish_encoding
;
3737 sprintf (buf
, "%d@0:%d", parm_offset
, i
);
3738 obstack_grow (&util_obstack
, buf
, strlen (buf
));
3740 /* Argument types. */
3741 parm_offset
= 2 * i
;
3742 for (parms
= METHOD_SEL_ARGS (method_decl
); parms
;
3743 parms
= TREE_CHAIN (parms
))
3745 tree type
= objc_method_parm_type (parms
);
3747 /* Process argument qualifiers for user supplied arguments. */
3748 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms
)));
3751 encode_type (type
, obstack_object_size (&util_obstack
),
3752 OBJC_ENCODE_INLINE_DEFS
);
3754 /* Compute offset. */
3755 sprintf (buf
, "%d", parm_offset
);
3756 parm_offset
+= objc_encoded_type_size (type
);
3758 obstack_grow (&util_obstack
, buf
, strlen (buf
));
3762 obstack_1grow (&util_obstack
, '\0');
3763 result
= get_identifier (obstack_finish (&util_obstack
));
3764 obstack_free (&util_obstack
, util_firstobj
);
3769 generate_descriptor_table (tree type
, const char *name
, int size
, tree list
,
3772 tree decl
, initlist
;
3774 decl
= start_var_decl (type
, synth_id_with_class_suffix (name
, proto
));
3776 initlist
= build_tree_list (NULL_TREE
, build_int_cst (NULL_TREE
, size
));
3777 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3779 finish_var_decl (decl
, objc_build_constructor (type
, nreverse (initlist
)));
3785 generate_method_descriptors (tree protocol
)
3787 tree initlist
, chain
, method_list_template
;
3790 if (!objc_method_prototype_template
)
3791 objc_method_prototype_template
= build_method_prototype_template ();
3793 chain
= PROTOCOL_CLS_METHODS (protocol
);
3796 size
= list_length (chain
);
3798 method_list_template
3799 = build_method_prototype_list_template (objc_method_prototype_template
,
3803 = build_descriptor_table_initializer (objc_method_prototype_template
,
3806 UOBJC_CLASS_METHODS_decl
3807 = generate_descriptor_table (method_list_template
,
3808 "_OBJC_PROTOCOL_CLASS_METHODS",
3809 size
, initlist
, protocol
);
3812 UOBJC_CLASS_METHODS_decl
= 0;
3814 chain
= PROTOCOL_NST_METHODS (protocol
);
3817 size
= list_length (chain
);
3819 method_list_template
3820 = build_method_prototype_list_template (objc_method_prototype_template
,
3823 = build_descriptor_table_initializer (objc_method_prototype_template
,
3826 UOBJC_INSTANCE_METHODS_decl
3827 = generate_descriptor_table (method_list_template
,
3828 "_OBJC_PROTOCOL_INSTANCE_METHODS",
3829 size
, initlist
, protocol
);
3832 UOBJC_INSTANCE_METHODS_decl
= 0;
3836 generate_protocol_references (tree plist
)
3840 /* Forward declare protocols referenced. */
3841 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
3843 tree proto
= TREE_VALUE (lproto
);
3845 if (TREE_CODE (proto
) == PROTOCOL_INTERFACE_TYPE
3846 && PROTOCOL_NAME (proto
))
3848 if (! PROTOCOL_FORWARD_DECL (proto
))
3849 build_protocol_reference (proto
);
3851 if (PROTOCOL_LIST (proto
))
3852 generate_protocol_references (PROTOCOL_LIST (proto
));
3857 /* For each protocol which was referenced either from a @protocol()
3858 expression, or because a class/category implements it (then a
3859 pointer to the protocol is stored in the struct describing the
3860 class/category), we create a statically allocated instance of the
3861 Protocol class. The code is written in such a way as to generate
3862 as few Protocol objects as possible; we generate a unique Protocol
3863 instance for each protocol, and we don't generate a Protocol
3864 instance if the protocol is never referenced (either from a
3865 @protocol() or from a class/category implementation). These
3866 statically allocated objects can be referred to via the static
3867 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
3869 The statically allocated Protocol objects that we generate here
3870 need to be fixed up at runtime in order to be used: the 'isa'
3871 pointer of the objects need to be set up to point to the 'Protocol'
3872 class, as known at runtime.
3874 The NeXT runtime fixes up all protocols at program startup time,
3875 before main() is entered. It uses a low-level trick to look up all
3876 those symbols, then loops on them and fixes them up.
3878 The GNU runtime as well fixes up all protocols before user code
3879 from the module is executed; it requires pointers to those symbols
3880 to be put in the objc_symtab (which is then passed as argument to
3881 the function __objc_exec_class() which the compiler sets up to be
3882 executed automatically when the module is loaded); setup of those
3883 Protocol objects happen in two ways in the GNU runtime: all
3884 Protocol objects referred to by a class or category implementation
3885 are fixed up when the class/category is loaded; all Protocol
3886 objects referred to by a @protocol() expression are added by the
3887 compiler to the list of statically allocated instances to fixup
3888 (the same list holding the statically allocated constant string
3889 objects). Because, as explained above, the compiler generates as
3890 few Protocol objects as possible, some Protocol object might end up
3891 being referenced multiple times when compiled with the GNU runtime,
3892 and end up being fixed up multiple times at runtime initialization.
3893 But that doesn't hurt, it's just a little inefficient. */
3896 generate_protocols (void)
3900 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
3902 /* If a protocol was directly referenced, pull in indirect references. */
3903 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3904 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
3905 generate_protocol_references (PROTOCOL_LIST (p
));
3907 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3909 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
3910 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
3912 /* If protocol wasn't referenced, don't generate any code. */
3913 decl
= PROTOCOL_FORWARD_DECL (p
);
3918 /* Make sure we link in the Protocol class. */
3919 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
3923 if (! METHOD_ENCODING (nst_methods
))
3925 encoding
= encode_method_prototype (nst_methods
);
3926 METHOD_ENCODING (nst_methods
) = encoding
;
3928 nst_methods
= TREE_CHAIN (nst_methods
);
3933 if (! METHOD_ENCODING (cls_methods
))
3935 encoding
= encode_method_prototype (cls_methods
);
3936 METHOD_ENCODING (cls_methods
) = encoding
;
3939 cls_methods
= TREE_CHAIN (cls_methods
);
3941 generate_method_descriptors (p
);
3943 if (PROTOCOL_LIST (p
))
3944 refs_decl
= generate_protocol_list (p
);
3948 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3949 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
3952 refs_expr
= convert (build_pointer_type (build_pointer_type
3953 (objc_protocol_template
)),
3954 build_unary_op (ADDR_EXPR
, refs_decl
, 0));
3956 refs_expr
= build_int_cst (NULL_TREE
, 0);
3958 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3959 by generate_method_descriptors, which is called above. */
3960 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
3961 protocol_name_expr
, refs_expr
,
3962 UOBJC_INSTANCE_METHODS_decl
,
3963 UOBJC_CLASS_METHODS_decl
);
3964 finish_var_decl (decl
, initlist
);
3969 build_protocol_initializer (tree type
, tree protocol_name
,
3970 tree protocol_list
, tree instance_methods
,
3973 tree initlist
= NULL_TREE
, expr
;
3974 tree cast_type
= build_pointer_type
3975 (xref_tag (RECORD_TYPE
,
3976 get_identifier (UTAG_CLASS
)));
3978 /* Filling the "isa" in with one allows the runtime system to
3979 detect that the version change...should remove before final release. */
3981 expr
= build_int_cst (cast_type
, PROTOCOL_VERSION
);
3982 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3983 initlist
= tree_cons (NULL_TREE
, protocol_name
, initlist
);
3984 initlist
= tree_cons (NULL_TREE
, protocol_list
, initlist
);
3986 if (!instance_methods
)
3987 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
3990 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
3991 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3995 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
3998 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
3999 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4002 return objc_build_constructor (type
, nreverse (initlist
));
4005 /* struct _objc_category {
4006 char *category_name;
4008 struct _objc_method_list *instance_methods;
4009 struct _objc_method_list *class_methods;
4010 struct _objc_protocol_list *protocols;
4014 build_category_template (void)
4016 tree field_decl
, field_decl_chain
;
4018 objc_category_template
= start_struct (RECORD_TYPE
,
4019 get_identifier (UTAG_CATEGORY
));
4021 /* char *category_name; */
4022 field_decl
= create_field_decl (string_type_node
, "category_name");
4023 field_decl_chain
= field_decl
;
4025 /* char *class_name; */
4026 field_decl
= create_field_decl (string_type_node
, "class_name");
4027 chainon (field_decl_chain
, field_decl
);
4029 /* struct _objc_method_list *instance_methods; */
4030 field_decl
= create_field_decl (build_pointer_type
4031 (xref_tag (RECORD_TYPE
,
4033 (UTAG_METHOD_LIST
))),
4034 "instance_methods");
4035 chainon (field_decl_chain
, field_decl
);
4037 /* struct _objc_method_list *class_methods; */
4038 field_decl
= create_field_decl (build_pointer_type
4039 (xref_tag (RECORD_TYPE
,
4041 (UTAG_METHOD_LIST
))),
4043 chainon (field_decl_chain
, field_decl
);
4045 /* struct _objc_protocol **protocol_list; */
4046 field_decl
= create_field_decl (build_pointer_type
4048 (objc_protocol_template
)),
4050 chainon (field_decl_chain
, field_decl
);
4052 finish_struct (objc_category_template
, field_decl_chain
, NULL_TREE
);
4055 /* struct _objc_selector {
4061 build_selector_template (void)
4064 tree field_decl
, field_decl_chain
;
4066 objc_selector_template
4067 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SELECTOR
));
4070 field_decl
= create_field_decl (objc_selector_type
, "sel_id");
4071 field_decl_chain
= field_decl
;
4073 /* char *sel_type; */
4074 field_decl
= create_field_decl (string_type_node
, "sel_type");
4075 chainon (field_decl_chain
, field_decl
);
4077 finish_struct (objc_selector_template
, field_decl_chain
, NULL_TREE
);
4080 /* struct _objc_class {
4081 struct _objc_class *isa;
4082 struct _objc_class *super_class;
4087 struct _objc_ivar_list *ivars;
4088 struct _objc_method_list *methods;
4089 #ifdef __NEXT_RUNTIME__
4090 struct objc_cache *cache;
4092 struct sarray *dtable;
4093 struct _objc_class *subclass_list;
4094 struct _objc_class *sibling_class;
4096 struct _objc_protocol_list *protocols;
4097 #ifdef __NEXT_RUNTIME__
4100 void *gc_object_type;
4103 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4104 the NeXT/Apple runtime; still, the compiler must generate them to
4105 maintain backward binary compatibility (and to allow for future
4109 build_class_template (void)
4111 tree field_decl
, field_decl_chain
;
4114 = start_struct (RECORD_TYPE
, get_identifier (UTAG_CLASS
));
4116 /* struct _objc_class *isa; */
4117 field_decl
= create_field_decl (build_pointer_type (objc_class_template
),
4119 field_decl_chain
= field_decl
;
4121 /* struct _objc_class *super_class; */
4122 field_decl
= create_field_decl (build_pointer_type (objc_class_template
),
4124 chainon (field_decl_chain
, field_decl
);
4127 field_decl
= create_field_decl (string_type_node
, "name");
4128 chainon (field_decl_chain
, field_decl
);
4131 field_decl
= create_field_decl (long_integer_type_node
, "version");
4132 chainon (field_decl_chain
, field_decl
);
4135 field_decl
= create_field_decl (long_integer_type_node
, "info");
4136 chainon (field_decl_chain
, field_decl
);
4138 /* long instance_size; */
4139 field_decl
= create_field_decl (long_integer_type_node
, "instance_size");
4140 chainon (field_decl_chain
, field_decl
);
4142 /* struct _objc_ivar_list *ivars; */
4143 field_decl
= create_field_decl (build_pointer_type
4144 (xref_tag (RECORD_TYPE
,
4148 chainon (field_decl_chain
, field_decl
);
4150 /* struct _objc_method_list *methods; */
4151 field_decl
= create_field_decl (build_pointer_type
4152 (xref_tag (RECORD_TYPE
,
4154 (UTAG_METHOD_LIST
))),
4156 chainon (field_decl_chain
, field_decl
);
4158 if (flag_next_runtime
)
4160 /* struct objc_cache *cache; */
4161 field_decl
= create_field_decl (build_pointer_type
4162 (xref_tag (RECORD_TYPE
,
4166 chainon (field_decl_chain
, field_decl
);
4170 /* struct sarray *dtable; */
4171 field_decl
= create_field_decl (build_pointer_type
4172 (xref_tag (RECORD_TYPE
,
4176 chainon (field_decl_chain
, field_decl
);
4178 /* struct objc_class *subclass_list; */
4179 field_decl
= create_field_decl (build_pointer_type
4180 (objc_class_template
),
4182 chainon (field_decl_chain
, field_decl
);
4184 /* struct objc_class *sibling_class; */
4185 field_decl
= create_field_decl (build_pointer_type
4186 (objc_class_template
),
4188 chainon (field_decl_chain
, field_decl
);
4191 /* struct _objc_protocol **protocol_list; */
4192 field_decl
= create_field_decl (build_pointer_type
4194 (xref_tag (RECORD_TYPE
,
4198 chainon (field_decl_chain
, field_decl
);
4200 if (flag_next_runtime
)
4203 field_decl
= create_field_decl (build_pointer_type (void_type_node
),
4205 chainon (field_decl_chain
, field_decl
);
4208 /* void *gc_object_type; */
4209 field_decl
= create_field_decl (build_pointer_type (void_type_node
),
4211 chainon (field_decl_chain
, field_decl
);
4213 finish_struct (objc_class_template
, field_decl_chain
, NULL_TREE
);
4216 /* Generate appropriate forward declarations for an implementation. */
4219 synth_forward_declarations (void)
4223 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4224 UOBJC_CLASS_decl
= build_metadata_decl ("_OBJC_CLASS",
4225 objc_class_template
);
4227 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4228 UOBJC_METACLASS_decl
= build_metadata_decl ("_OBJC_METACLASS",
4229 objc_class_template
);
4231 /* Pre-build the following entities - for speed/convenience. */
4233 an_id
= get_identifier ("super_class");
4234 ucls_super_ref
= build_component_ref (UOBJC_CLASS_decl
, an_id
);
4235 uucls_super_ref
= build_component_ref (UOBJC_METACLASS_decl
, an_id
);
4239 error_with_ivar (const char *message
, tree decl
)
4241 error ("%J%s %qs", decl
,
4242 message
, gen_declaration (decl
));
4247 check_ivars (tree inter
, tree imp
)
4249 tree intdecls
= CLASS_RAW_IVARS (inter
);
4250 tree impdecls
= CLASS_RAW_IVARS (imp
);
4257 if (intdecls
&& TREE_CODE (intdecls
) == TYPE_DECL
)
4258 intdecls
= TREE_CHAIN (intdecls
);
4260 if (intdecls
== 0 && impdecls
== 0)
4262 if (intdecls
== 0 || impdecls
== 0)
4264 error ("inconsistent instance variable specification");
4268 t1
= TREE_TYPE (intdecls
); t2
= TREE_TYPE (impdecls
);
4270 if (!comptypes (t1
, t2
)
4271 || !tree_int_cst_equal (DECL_INITIAL (intdecls
),
4272 DECL_INITIAL (impdecls
)))
4274 if (DECL_NAME (intdecls
) == DECL_NAME (impdecls
))
4276 error_with_ivar ("conflicting instance variable type",
4278 error_with_ivar ("previous declaration of",
4281 else /* both the type and the name don't match */
4283 error ("inconsistent instance variable specification");
4288 else if (DECL_NAME (intdecls
) != DECL_NAME (impdecls
))
4290 error_with_ivar ("conflicting instance variable name",
4292 error_with_ivar ("previous declaration of",
4296 intdecls
= TREE_CHAIN (intdecls
);
4297 impdecls
= TREE_CHAIN (impdecls
);
4301 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
4302 This needs to be done just once per compilation. */
4304 /* struct _objc_super {
4305 struct _objc_object *self;
4306 struct _objc_class *super_class;
4310 build_super_template (void)
4312 tree field_decl
, field_decl_chain
;
4314 objc_super_template
= start_struct (RECORD_TYPE
, get_identifier (UTAG_SUPER
));
4316 /* struct _objc_object *self; */
4317 field_decl
= create_field_decl (objc_object_type
, "self");
4318 field_decl_chain
= field_decl
;
4320 /* struct _objc_class *super_class; */
4321 field_decl
= create_field_decl (build_pointer_type (objc_class_template
),
4323 chainon (field_decl_chain
, field_decl
);
4325 finish_struct (objc_super_template
, field_decl_chain
, NULL_TREE
);
4328 /* struct _objc_ivar {
4335 build_ivar_template (void)
4337 tree objc_ivar_id
, objc_ivar_record
;
4338 tree field_decl
, field_decl_chain
;
4340 objc_ivar_id
= get_identifier (UTAG_IVAR
);
4341 objc_ivar_record
= start_struct (RECORD_TYPE
, objc_ivar_id
);
4343 /* char *ivar_name; */
4344 field_decl
= create_field_decl (string_type_node
, "ivar_name");
4345 field_decl_chain
= field_decl
;
4347 /* char *ivar_type; */
4348 field_decl
= create_field_decl (string_type_node
, "ivar_type");
4349 chainon (field_decl_chain
, field_decl
);
4351 /* int ivar_offset; */
4352 field_decl
= create_field_decl (integer_type_node
, "ivar_offset");
4353 chainon (field_decl_chain
, field_decl
);
4355 finish_struct (objc_ivar_record
, field_decl_chain
, NULL_TREE
);
4357 return objc_ivar_record
;
4362 struct objc_ivar ivar_list[ivar_count];
4366 build_ivar_list_template (tree list_type
, int size
)
4368 tree objc_ivar_list_record
;
4369 tree field_decl
, field_decl_chain
;
4371 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
4373 /* int ivar_count; */
4374 field_decl
= create_field_decl (integer_type_node
, "ivar_count");
4375 field_decl_chain
= field_decl
;
4377 /* struct objc_ivar ivar_list[]; */
4378 field_decl
= create_field_decl (build_array_type
4381 (build_int_cst (NULL_TREE
, size
- 1))),
4383 chainon (field_decl_chain
, field_decl
);
4385 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
4387 return objc_ivar_list_record
;
4391 struct _objc__method_prototype_list *method_next;
4393 struct objc_method method_list[method_count];
4397 build_method_list_template (tree list_type
, int size
)
4399 tree objc_ivar_list_record
;
4400 tree field_decl
, field_decl_chain
;
4402 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
4404 /* struct _objc__method_prototype_list *method_next; */
4405 field_decl
= create_field_decl (build_pointer_type
4406 (xref_tag (RECORD_TYPE
,
4408 (UTAG_METHOD_PROTOTYPE_LIST
))),
4410 field_decl_chain
= field_decl
;
4412 /* int method_count; */
4413 field_decl
= create_field_decl (integer_type_node
, "method_count");
4414 chainon (field_decl_chain
, field_decl
);
4416 /* struct objc_method method_list[]; */
4417 field_decl
= create_field_decl (build_array_type
4420 (build_int_cst (NULL_TREE
, size
- 1))),
4422 chainon (field_decl_chain
, field_decl
);
4424 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
4426 return objc_ivar_list_record
;
4430 build_ivar_list_initializer (tree type
, tree field_decl
)
4432 tree initlist
= NULL_TREE
;
4436 tree ivar
= NULL_TREE
;
4439 if (DECL_NAME (field_decl
))
4440 ivar
= tree_cons (NULL_TREE
,
4441 add_objc_string (DECL_NAME (field_decl
),
4445 /* Unnamed bit-field ivar (yuck). */
4446 ivar
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), ivar
);
4449 encode_field_decl (field_decl
,
4450 obstack_object_size (&util_obstack
),
4451 OBJC_ENCODE_DONT_INLINE_DEFS
);
4453 /* Null terminate string. */
4454 obstack_1grow (&util_obstack
, 0);
4458 add_objc_string (get_identifier (obstack_finish (&util_obstack
)),
4461 obstack_free (&util_obstack
, util_firstobj
);
4464 ivar
= tree_cons (NULL_TREE
, byte_position (field_decl
), ivar
);
4465 initlist
= tree_cons (NULL_TREE
,
4466 objc_build_constructor (type
, nreverse (ivar
)),
4469 field_decl
= TREE_CHAIN (field_decl
);
4470 while (field_decl
&& TREE_CODE (field_decl
) != FIELD_DECL
);
4474 return objc_build_constructor (build_array_type (type
, 0),
4475 nreverse (initlist
));
4479 generate_ivars_list (tree type
, const char *name
, int size
, tree list
)
4481 tree decl
, initlist
;
4483 decl
= start_var_decl (type
, synth_id_with_class_suffix
4484 (name
, objc_implementation_context
));
4486 initlist
= build_tree_list (NULL_TREE
, build_int_cst (NULL_TREE
, size
));
4487 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
4489 finish_var_decl (decl
,
4490 objc_build_constructor (TREE_TYPE (decl
),
4491 nreverse (initlist
)));
4496 /* Count only the fields occurring in T. */
4498 ivar_list_length (tree t
)
4502 for (; t
; t
= TREE_CHAIN (t
))
4503 if (TREE_CODE (t
) == FIELD_DECL
)
4510 generate_ivar_lists (void)
4512 tree initlist
, ivar_list_template
, chain
;
4515 generating_instance_variables
= 1;
4517 if (!objc_ivar_template
)
4518 objc_ivar_template
= build_ivar_template ();
4520 /* Only generate class variables for the root of the inheritance
4521 hierarchy since these will be the same for every class. */
4523 if (CLASS_SUPER_NAME (implementation_template
) == NULL_TREE
4524 && (chain
= TYPE_FIELDS (objc_class_template
)))
4526 size
= ivar_list_length (chain
);
4528 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
4529 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
4531 UOBJC_CLASS_VARIABLES_decl
4532 = generate_ivars_list (ivar_list_template
, "_OBJC_CLASS_VARIABLES",
4536 UOBJC_CLASS_VARIABLES_decl
= 0;
4538 chain
= CLASS_IVARS (implementation_template
);
4541 size
= ivar_list_length (chain
);
4542 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
4543 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
4545 UOBJC_INSTANCE_VARIABLES_decl
4546 = generate_ivars_list (ivar_list_template
, "_OBJC_INSTANCE_VARIABLES",
4550 UOBJC_INSTANCE_VARIABLES_decl
= 0;
4552 generating_instance_variables
= 0;
4556 build_dispatch_table_initializer (tree type
, tree entries
)
4558 tree initlist
= NULL_TREE
;
4562 tree elemlist
= NULL_TREE
;
4564 elemlist
= tree_cons (NULL_TREE
,
4565 build_selector (METHOD_SEL_NAME (entries
)),
4568 /* Generate the method encoding if we don't have one already. */
4569 if (! METHOD_ENCODING (entries
))
4570 METHOD_ENCODING (entries
) =
4571 encode_method_prototype (entries
);
4573 elemlist
= tree_cons (NULL_TREE
,
4574 add_objc_string (METHOD_ENCODING (entries
),
4579 = tree_cons (NULL_TREE
,
4580 convert (ptr_type_node
,
4581 build_unary_op (ADDR_EXPR
,
4582 METHOD_DEFINITION (entries
), 1)),
4585 initlist
= tree_cons (NULL_TREE
,
4586 objc_build_constructor (type
, nreverse (elemlist
)),
4589 entries
= TREE_CHAIN (entries
);
4593 return objc_build_constructor (build_array_type (type
, 0),
4594 nreverse (initlist
));
4597 /* To accomplish method prototyping without generating all kinds of
4598 inane warnings, the definition of the dispatch table entries were
4601 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
4603 struct objc_method { SEL _cmd; ...; void *_imp; }; */
4606 build_method_template (void)
4609 tree field_decl
, field_decl_chain
;
4611 _SLT_record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD
));
4614 field_decl
= create_field_decl (objc_selector_type
, "_cmd");
4615 field_decl_chain
= field_decl
;
4617 /* char *method_types; */
4618 field_decl
= create_field_decl (string_type_node
, "method_types");
4619 chainon (field_decl_chain
, field_decl
);
4622 field_decl
= create_field_decl (build_pointer_type (void_type_node
),
4624 chainon (field_decl_chain
, field_decl
);
4626 finish_struct (_SLT_record
, field_decl_chain
, NULL_TREE
);
4633 generate_dispatch_table (tree type
, const char *name
, int size
, tree list
)
4635 tree decl
, initlist
;
4637 decl
= start_var_decl (type
, synth_id_with_class_suffix
4638 (name
, objc_implementation_context
));
4640 initlist
= build_tree_list (NULL_TREE
, build_int_cst (NULL_TREE
, 0));
4641 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, size
), initlist
);
4642 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
4644 finish_var_decl (decl
,
4645 objc_build_constructor (TREE_TYPE (decl
),
4646 nreverse (initlist
)));
4652 mark_referenced_methods (void)
4654 struct imp_entry
*impent
;
4657 for (impent
= imp_list
; impent
; impent
= impent
->next
)
4659 chain
= CLASS_CLS_METHODS (impent
->imp_context
);
4662 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain
)));
4663 chain
= TREE_CHAIN (chain
);
4666 chain
= CLASS_NST_METHODS (impent
->imp_context
);
4669 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain
)));
4670 chain
= TREE_CHAIN (chain
);
4676 generate_dispatch_tables (void)
4678 tree initlist
, chain
, method_list_template
;
4681 if (!objc_method_template
)
4682 objc_method_template
= build_method_template ();
4684 chain
= CLASS_CLS_METHODS (objc_implementation_context
);
4687 size
= list_length (chain
);
4689 method_list_template
4690 = build_method_list_template (objc_method_template
, size
);
4692 = build_dispatch_table_initializer (objc_method_template
, chain
);
4694 UOBJC_CLASS_METHODS_decl
4695 = generate_dispatch_table (method_list_template
,
4696 ((TREE_CODE (objc_implementation_context
)
4697 == CLASS_IMPLEMENTATION_TYPE
)
4698 ? "_OBJC_CLASS_METHODS"
4699 : "_OBJC_CATEGORY_CLASS_METHODS"),
4703 UOBJC_CLASS_METHODS_decl
= 0;
4705 chain
= CLASS_NST_METHODS (objc_implementation_context
);
4708 size
= list_length (chain
);
4710 method_list_template
4711 = build_method_list_template (objc_method_template
, size
);
4713 = build_dispatch_table_initializer (objc_method_template
, chain
);
4715 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
4716 UOBJC_INSTANCE_METHODS_decl
4717 = generate_dispatch_table (method_list_template
,
4718 "_OBJC_INSTANCE_METHODS",
4721 /* We have a category. */
4722 UOBJC_INSTANCE_METHODS_decl
4723 = generate_dispatch_table (method_list_template
,
4724 "_OBJC_CATEGORY_INSTANCE_METHODS",
4728 UOBJC_INSTANCE_METHODS_decl
= 0;
4732 generate_protocol_list (tree i_or_p
)
4735 tree refs_decl
, lproto
, e
, plist
;
4737 const char *ref_name
;
4739 if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
4740 || TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4741 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
4742 else if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4743 plist
= PROTOCOL_LIST (i_or_p
);
4748 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4749 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
4750 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
4753 /* Build initializer. */
4754 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), NULL_TREE
);
4755 e
= build_int_cst (build_pointer_type (objc_protocol_template
), size
);
4756 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4758 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4760 tree pval
= TREE_VALUE (lproto
);
4762 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
4763 && PROTOCOL_FORWARD_DECL (pval
))
4765 e
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (pval
), 0);
4766 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4770 /* static struct objc_protocol *refs[n]; */
4772 if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4773 ref_name
= synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p
);
4774 else if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
)
4775 ref_name
= synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p
);
4776 else if (TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4777 ref_name
= synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p
);
4781 refs_decl
= start_var_decl
4783 (build_pointer_type (objc_protocol_template
),
4784 build_index_type (build_int_cst (NULL_TREE
, size
+ 2))),
4787 finish_var_decl (refs_decl
, objc_build_constructor (TREE_TYPE (refs_decl
),
4788 nreverse (initlist
)));
4794 build_category_initializer (tree type
, tree cat_name
, tree class_name
,
4795 tree instance_methods
, tree class_methods
,
4798 tree initlist
= NULL_TREE
, expr
;
4800 initlist
= tree_cons (NULL_TREE
, cat_name
, initlist
);
4801 initlist
= tree_cons (NULL_TREE
, class_name
, initlist
);
4803 if (!instance_methods
)
4804 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4807 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
4808 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4811 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4814 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
4815 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4818 /* protocol_list = */
4820 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4823 expr
= convert (build_pointer_type
4825 (objc_protocol_template
)),
4826 build_unary_op (ADDR_EXPR
, protocol_list
, 0));
4827 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4830 return objc_build_constructor (type
, nreverse (initlist
));
4833 /* struct _objc_class {
4834 struct objc_class *isa;
4835 struct objc_class *super_class;
4840 struct objc_ivar_list *ivars;
4841 struct objc_method_list *methods;
4842 if (flag_next_runtime)
4843 struct objc_cache *cache;
4845 struct sarray *dtable;
4846 struct objc_class *subclass_list;
4847 struct objc_class *sibling_class;
4849 struct objc_protocol_list *protocols;
4850 if (flag_next_runtime)
4852 void *gc_object_type;
4856 build_shared_structure_initializer (tree type
, tree isa
, tree super
,
4857 tree name
, tree size
, int status
,
4858 tree dispatch_table
, tree ivar_list
,
4861 tree initlist
= NULL_TREE
, expr
;
4864 initlist
= tree_cons (NULL_TREE
, isa
, initlist
);
4867 initlist
= tree_cons (NULL_TREE
, super
, initlist
);
4870 initlist
= tree_cons (NULL_TREE
, default_conversion (name
), initlist
);
4873 initlist
= tree_cons (NULL_TREE
, build_int_cst (long_integer_type_node
, 0),
4877 initlist
= tree_cons (NULL_TREE
,
4878 build_int_cst (long_integer_type_node
, status
),
4881 /* instance_size = */
4882 initlist
= tree_cons (NULL_TREE
, convert (long_integer_type_node
, size
),
4885 /* objc_ivar_list = */
4887 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4890 expr
= build_unary_op (ADDR_EXPR
, ivar_list
, 0);
4891 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4894 /* objc_method_list = */
4895 if (!dispatch_table
)
4896 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4899 expr
= build_unary_op (ADDR_EXPR
, dispatch_table
, 0);
4900 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4903 if (flag_next_runtime
)
4904 /* method_cache = */
4905 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4909 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4911 /* subclass_list = */
4912 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4914 /* sibling_class = */
4915 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4918 /* protocol_list = */
4919 if (! protocol_list
)
4920 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4923 expr
= convert (build_pointer_type
4925 (objc_protocol_template
)),
4926 build_unary_op (ADDR_EXPR
, protocol_list
, 0));
4927 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4930 if (flag_next_runtime
)
4932 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4934 /* gc_object_type = NULL */
4935 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4937 return objc_build_constructor (type
, nreverse (initlist
));
4940 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
4943 lookup_category (tree
class, tree cat_name
)
4945 tree category
= CLASS_CATEGORY_LIST (class);
4947 while (category
&& CLASS_SUPER_NAME (category
) != cat_name
)
4948 category
= CLASS_CATEGORY_LIST (category
);
4952 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4955 generate_category (tree cat
)
4958 tree initlist
, cat_name_expr
, class_name_expr
;
4959 tree protocol_decl
, category
;
4961 add_class_reference (CLASS_NAME (cat
));
4962 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
4964 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
4966 category
= lookup_category (implementation_template
,
4967 CLASS_SUPER_NAME (cat
));
4969 if (category
&& CLASS_PROTOCOL_LIST (category
))
4971 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
4972 protocol_decl
= generate_protocol_list (category
);
4977 decl
= start_var_decl (objc_category_template
,
4978 synth_id_with_class_suffix
4979 ("_OBJC_CATEGORY", objc_implementation_context
));
4981 initlist
= build_category_initializer (TREE_TYPE (decl
),
4982 cat_name_expr
, class_name_expr
,
4983 UOBJC_INSTANCE_METHODS_decl
,
4984 UOBJC_CLASS_METHODS_decl
,
4987 finish_var_decl (decl
, initlist
);
4990 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4991 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4994 generate_shared_structures (void)
4996 tree sc_spec
, decl_specs
, decl
;
4997 tree name_expr
, super_expr
, root_expr
;
4998 tree my_root_id
= NULL_TREE
, my_super_id
= NULL_TREE
;
4999 tree cast_type
, initlist
, protocol_decl
;
5001 my_super_id
= CLASS_SUPER_NAME (implementation_template
);
5004 add_class_reference (my_super_id
);
5006 /* Compute "my_root_id" - this is required for code generation.
5007 the "isa" for all meta class structures points to the root of
5008 the inheritance hierarchy (e.g. "__Object")... */
5009 my_root_id
= my_super_id
;
5012 tree my_root_int
= lookup_interface (my_root_id
);
5014 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
5015 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
5022 /* No super class. */
5023 my_root_id
= CLASS_NAME (implementation_template
);
5025 cast_type
= build_pointer_type (objc_class_template
);
5026 name_expr
= add_objc_string (CLASS_NAME (implementation_template
),
5029 /* Install class `isa' and `super' pointers at runtime. */
5032 super_expr
= add_objc_string (my_super_id
, class_names
);
5033 super_expr
= build_c_cast (cast_type
, super_expr
); /* cast! */
5036 super_expr
= build_int_cst (NULL_TREE
, 0);
5038 root_expr
= add_objc_string (my_root_id
, class_names
);
5039 root_expr
= build_c_cast (cast_type
, root_expr
); /* cast! */
5041 if (CLASS_PROTOCOL_LIST (implementation_template
))
5043 generate_protocol_references
5044 (CLASS_PROTOCOL_LIST (implementation_template
));
5045 protocol_decl
= generate_protocol_list (implementation_template
);
5050 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5052 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
5053 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
5055 decl
= start_var_decl (objc_class_template
,
5057 (DECL_NAME (UOBJC_METACLASS_decl
)));
5060 = build_shared_structure_initializer
5062 root_expr
, super_expr
, name_expr
,
5063 convert (integer_type_node
, TYPE_SIZE_UNIT (objc_class_template
)),
5065 UOBJC_CLASS_METHODS_decl
,
5066 UOBJC_CLASS_VARIABLES_decl
,
5069 finish_var_decl (decl
, initlist
);
5071 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5073 decl
= start_var_decl (objc_class_template
,
5075 (DECL_NAME (UOBJC_CLASS_decl
)));
5078 = build_shared_structure_initializer
5080 build_unary_op (ADDR_EXPR
, UOBJC_METACLASS_decl
, 0),
5081 super_expr
, name_expr
,
5082 convert (integer_type_node
,
5083 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5084 (implementation_template
))),
5086 UOBJC_INSTANCE_METHODS_decl
,
5087 UOBJC_INSTANCE_VARIABLES_decl
,
5090 finish_var_decl (decl
, initlist
);
5095 synth_id_with_class_suffix (const char *preamble
, tree ctxt
)
5097 static char string
[BUFSIZE
];
5099 if (TREE_CODE (ctxt
) == CLASS_IMPLEMENTATION_TYPE
5100 || TREE_CODE (ctxt
) == CLASS_INTERFACE_TYPE
)
5102 sprintf (string
, "%s_%s", preamble
,
5103 IDENTIFIER_POINTER (CLASS_NAME (ctxt
)));
5105 else if (TREE_CODE (ctxt
) == CATEGORY_IMPLEMENTATION_TYPE
5106 || TREE_CODE (ctxt
) == CATEGORY_INTERFACE_TYPE
)
5108 /* We have a category. */
5109 const char *const class_name
5110 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
5111 const char *const class_super_name
5112 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
));
5113 sprintf (string
, "%s_%s_%s", preamble
, class_name
, class_super_name
);
5115 else if (TREE_CODE (ctxt
) == PROTOCOL_INTERFACE_TYPE
)
5117 const char *protocol_name
= IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt
));
5118 sprintf (string
, "%s_%s", preamble
, protocol_name
);
5126 /* If type is empty or only type qualifiers are present, add default
5127 type of id (otherwise grokdeclarator will default to int). */
5130 adjust_type_for_id_default (tree type
)
5133 type
= make_node (TREE_LIST
);
5135 if (!TREE_VALUE (type
))
5136 TREE_VALUE (type
) = objc_object_type
;
5137 else if (TREE_CODE (TREE_VALUE (type
)) == RECORD_TYPE
5138 && TYPED_OBJECT (TREE_VALUE (type
)))
5139 error ("can not use an object as parameter to a method");
5146 selector ':' '(' typename ')' identifier
5149 Transform an Objective-C keyword argument into
5150 the C equivalent parameter declarator.
5152 In: key_name, an "identifier_node" (optional).
5153 arg_type, a "tree_list" (optional).
5154 arg_name, an "identifier_node".
5156 Note: It would be really nice to strongly type the preceding
5157 arguments in the function prototype; however, then I
5158 could not use the "accessor" macros defined in "tree.h".
5160 Out: an instance of "keyword_decl". */
5163 objc_build_keyword_decl (tree key_name
, tree arg_type
, tree arg_name
)
5167 /* If no type is specified, default to "id". */
5168 arg_type
= adjust_type_for_id_default (arg_type
);
5170 keyword_decl
= make_node (KEYWORD_DECL
);
5172 TREE_TYPE (keyword_decl
) = arg_type
;
5173 KEYWORD_ARG_NAME (keyword_decl
) = arg_name
;
5174 KEYWORD_KEY_NAME (keyword_decl
) = key_name
;
5176 return keyword_decl
;
5179 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5182 build_keyword_selector (tree selector
)
5185 tree key_chain
, key_name
;
5188 /* Scan the selector to see how much space we'll need. */
5189 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
5191 if (TREE_CODE (selector
) == KEYWORD_DECL
)
5192 key_name
= KEYWORD_KEY_NAME (key_chain
);
5193 else if (TREE_CODE (selector
) == TREE_LIST
)
5194 key_name
= TREE_PURPOSE (key_chain
);
5199 len
+= IDENTIFIER_LENGTH (key_name
) + 1;
5201 /* Just a ':' arg. */
5205 buf
= (char *) alloca (len
+ 1);
5206 /* Start the buffer out as an empty string. */
5209 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
5211 if (TREE_CODE (selector
) == KEYWORD_DECL
)
5212 key_name
= KEYWORD_KEY_NAME (key_chain
);
5213 else if (TREE_CODE (selector
) == TREE_LIST
)
5215 key_name
= TREE_PURPOSE (key_chain
);
5216 /* The keyword decl chain will later be used as a function argument
5217 chain. Unhook the selector itself so as to not confuse other
5218 parts of the compiler. */
5219 TREE_PURPOSE (key_chain
) = NULL_TREE
;
5225 strcat (buf
, IDENTIFIER_POINTER (key_name
));
5229 return get_identifier (buf
);
5232 /* Used for declarations and definitions. */
5235 build_method_decl (enum tree_code code
, tree ret_type
, tree selector
,
5240 /* If no type is specified, default to "id". */
5241 ret_type
= adjust_type_for_id_default (ret_type
);
5243 method_decl
= make_node (code
);
5244 TREE_TYPE (method_decl
) = ret_type
;
5246 /* If we have a keyword selector, create an identifier_node that
5247 represents the full selector name (`:' included)... */
5248 if (TREE_CODE (selector
) == KEYWORD_DECL
)
5250 METHOD_SEL_NAME (method_decl
) = build_keyword_selector (selector
);
5251 METHOD_SEL_ARGS (method_decl
) = selector
;
5252 METHOD_ADD_ARGS (method_decl
) = add_args
;
5256 METHOD_SEL_NAME (method_decl
) = selector
;
5257 METHOD_SEL_ARGS (method_decl
) = NULL_TREE
;
5258 METHOD_ADD_ARGS (method_decl
) = NULL_TREE
;
5264 #define METHOD_DEF 0
5265 #define METHOD_REF 1
5267 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5268 an argument list for method METH. CONTEXT is either METHOD_DEF or
5269 METHOD_REF, saying whether we are trying to define a method or call
5270 one. SUPERFLAG says this is for a send to super; this makes a
5271 difference for the NeXT calling sequence in which the lookup and
5272 the method call are done together. If METH is null, user-defined
5273 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5276 get_arg_type_list (tree meth
, int context
, int superflag
)
5280 /* Receiver type. */
5281 if (flag_next_runtime
&& superflag
)
5282 arglist
= build_tree_list (NULL_TREE
, objc_super_type
);
5283 else if (context
== METHOD_DEF
&& TREE_CODE (meth
) == INSTANCE_METHOD_DECL
)
5284 arglist
= build_tree_list (NULL_TREE
, objc_instance_type
);
5286 arglist
= build_tree_list (NULL_TREE
, objc_object_type
);
5288 /* Selector type - will eventually change to `int'. */
5289 chainon (arglist
, build_tree_list (NULL_TREE
, objc_selector_type
));
5291 /* No actual method prototype given -- assume that remaining arguments
5296 /* Build a list of argument types. */
5297 for (akey
= METHOD_SEL_ARGS (meth
); akey
; akey
= TREE_CHAIN (akey
))
5299 tree arg_type
= TREE_VALUE (TREE_TYPE (akey
));
5301 /* Decay arrays and functions into pointers. */
5302 if (TREE_CODE (arg_type
) == ARRAY_TYPE
)
5303 arg_type
= build_pointer_type (TREE_TYPE (arg_type
));
5304 else if (TREE_CODE (arg_type
) == FUNCTION_TYPE
)
5305 arg_type
= build_pointer_type (arg_type
);
5307 chainon (arglist
, build_tree_list (NULL_TREE
, arg_type
));
5310 if (METHOD_ADD_ARGS (meth
))
5312 for (akey
= TREE_CHAIN (METHOD_ADD_ARGS (meth
));
5313 akey
; akey
= TREE_CHAIN (akey
))
5315 tree arg_type
= TREE_TYPE (TREE_VALUE (akey
));
5317 chainon (arglist
, build_tree_list (NULL_TREE
, arg_type
));
5320 if (!TREE_OVERFLOW (METHOD_ADD_ARGS (meth
)))
5321 goto lack_of_ellipsis
;
5326 chainon (arglist
, OBJC_VOID_AT_END
);
5333 check_duplicates (hash hsh
, int methods
, int is_class
)
5335 tree meth
= NULL_TREE
;
5343 /* We have two or more methods with the same name but
5347 warning ("multiple %s named %<%c%s%> found",
5348 methods
? "methods" : "selectors",
5349 (is_class
? '+' : '-'),
5350 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
5352 warn_with_method (methods
? "using" : "found",
5353 ((TREE_CODE (meth
) == INSTANCE_METHOD_DECL
)
5357 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
5358 warn_with_method ("also found",
5359 ((TREE_CODE (loop
->value
) == INSTANCE_METHOD_DECL
)
5368 /* If RECEIVER is a class reference, return the identifier node for
5369 the referenced class. RECEIVER is created by objc_get_class_reference,
5370 so we check the exact form created depending on which runtimes are
5374 receiver_is_class_object (tree receiver
, int self
, int super
)
5376 tree chain
, exp
, arg
;
5378 /* The receiver is 'self' or 'super' in the context of a class method. */
5379 if (objc_method_context
5380 && TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
5383 ? CLASS_SUPER_NAME (implementation_template
)
5384 : CLASS_NAME (implementation_template
));
5386 if (flag_next_runtime
)
5388 /* The receiver is a variable created by
5389 build_class_reference_decl. */
5390 if (TREE_CODE (receiver
) == VAR_DECL
&& IS_CLASS (TREE_TYPE (receiver
)))
5391 /* Look up the identifier. */
5392 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
5393 if (TREE_PURPOSE (chain
) == receiver
)
5394 return TREE_VALUE (chain
);
5397 /* The receiver is a function call that returns an id. Check if
5398 it is a call to objc_getClass, if so, pick up the class name. */
5399 if (TREE_CODE (receiver
) == CALL_EXPR
5400 && (exp
= TREE_OPERAND (receiver
, 0))
5401 && TREE_CODE (exp
) == ADDR_EXPR
5402 && (exp
= TREE_OPERAND (exp
, 0))
5403 && TREE_CODE (exp
) == FUNCTION_DECL
5404 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
5405 prototypes for objc_get_class(). Thankfully, they seem to share the
5406 same function type. */
5407 && TREE_TYPE (exp
) == TREE_TYPE (objc_get_class_decl
)
5408 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp
)), TAG_GETCLASS
)
5409 /* We have a call to objc_get_class/objc_getClass! */
5410 && (arg
= TREE_OPERAND (receiver
, 1))
5411 && TREE_CODE (arg
) == TREE_LIST
5412 && (arg
= TREE_VALUE (arg
)))
5415 if (TREE_CODE (arg
) == ADDR_EXPR
5416 && (arg
= TREE_OPERAND (arg
, 0))
5417 && TREE_CODE (arg
) == STRING_CST
)
5418 /* Finally, we have the class name. */
5419 return get_identifier (TREE_STRING_POINTER (arg
));
5424 /* If we are currently building a message expr, this holds
5425 the identifier of the selector of the message. This is
5426 used when printing warnings about argument mismatches. */
5428 static tree current_objc_message_selector
= 0;
5431 objc_message_selector (void)
5433 return current_objc_message_selector
;
5436 /* Construct an expression for sending a message.
5437 MESS has the object to send to in TREE_PURPOSE
5438 and the argument list (including selector) in TREE_VALUE.
5440 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
5441 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
5444 objc_build_message_expr (tree mess
)
5446 tree receiver
= TREE_PURPOSE (mess
);
5449 tree args
= TREE_PURPOSE (TREE_VALUE (mess
));
5451 tree args
= TREE_VALUE (mess
);
5453 tree method_params
= NULL_TREE
;
5455 if (TREE_CODE (receiver
) == ERROR_MARK
)
5456 return error_mark_node
;
5458 /* Obtain the full selector name. */
5459 if (TREE_CODE (args
) == IDENTIFIER_NODE
)
5460 /* A unary selector. */
5462 else if (TREE_CODE (args
) == TREE_LIST
)
5463 sel_name
= build_keyword_selector (args
);
5467 /* Build the parameter list to give to the method. */
5468 if (TREE_CODE (args
) == TREE_LIST
)
5470 method_params
= chainon (args
, TREE_VALUE (TREE_VALUE (mess
)));
5473 tree chain
= args
, prev
= NULL_TREE
;
5475 /* We have a keyword selector--check for comma expressions. */
5478 tree element
= TREE_VALUE (chain
);
5480 /* We have a comma expression, must collapse... */
5481 if (TREE_CODE (element
) == TREE_LIST
)
5484 TREE_CHAIN (prev
) = element
;
5489 chain
= TREE_CHAIN (chain
);
5491 method_params
= args
;
5496 if (processing_template_decl
)
5497 /* Must wait until template instantiation time. */
5498 return build_min_nt (MESSAGE_SEND_EXPR
, receiver
, sel_name
,
5502 return objc_finish_message_expr (receiver
, sel_name
, method_params
);
5505 /* Look up method SEL_NAME that would be suitable for receiver
5506 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
5507 nonzero), and report on any duplicates. */
5510 lookup_method_in_hash_lists (tree sel_name
, int is_class
)
5512 hash method_prototype
= NULL
;
5515 method_prototype
= hash_lookup (nst_method_hash_list
,
5518 if (!method_prototype
)
5520 method_prototype
= hash_lookup (cls_method_hash_list
,
5525 return check_duplicates (method_prototype
, 1, is_class
);
5528 /* The 'objc_finish_message_expr' routine is called from within
5529 'objc_build_message_expr' for non-template functions. In the case of
5530 C++ template functions, it is called from 'build_expr_from_tree'
5531 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
5534 objc_finish_message_expr (tree receiver
, tree sel_name
, tree method_params
)
5536 tree method_prototype
= NULL_TREE
, rprotos
= NULL_TREE
, rtype
;
5537 tree selector
, retval
, class_tree
;
5538 int self
, super
, have_cast
;
5540 /* Extract the receiver of the message, as well as its type
5541 (where the latter may take the form of a cast or be inferred
5542 from the implementation context). */
5544 while (TREE_CODE (rtype
) == COMPOUND_EXPR
5545 || TREE_CODE (rtype
) == MODIFY_EXPR
5546 || TREE_CODE (rtype
) == NOP_EXPR
5547 || TREE_CODE (rtype
) == CONVERT_EXPR
5548 || TREE_CODE (rtype
) == COMPONENT_REF
)
5549 rtype
= TREE_OPERAND (rtype
, 0);
5550 self
= (rtype
== self_decl
);
5551 super
= (rtype
== UOBJC_SUPER_decl
);
5552 rtype
= TREE_TYPE (receiver
);
5553 have_cast
= (TREE_CODE (receiver
) == NOP_EXPR
5554 || (TREE_CODE (receiver
) == COMPOUND_EXPR
5555 && !IS_SUPER (rtype
)));
5557 /* If the receiver is a class object, retrieve the corresponding
5558 @interface, if one exists. */
5559 class_tree
= receiver_is_class_object (receiver
, self
, super
);
5561 /* Now determine the receiver type (if an explicit cast has not been
5566 rtype
= lookup_interface (class_tree
);
5567 /* Handle `self' and `super'. */
5570 if (!CLASS_SUPER_NAME (implementation_template
))
5572 error ("no super class declared in @interface for %qs",
5573 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
5574 return error_mark_node
;
5576 rtype
= lookup_interface (CLASS_SUPER_NAME (implementation_template
));
5579 rtype
= lookup_interface (CLASS_NAME (implementation_template
));
5582 /* If receiver is of type `id' or `Class' (or if the @interface for a
5583 class is not visible), we shall be satisfied with the existence of
5584 any instance or class method. */
5585 if (!rtype
|| objc_is_id (rtype
))
5588 rtype
= xref_tag (RECORD_TYPE
, class_tree
);
5591 class_tree
= (IS_CLASS (rtype
) ? objc_class_name
: NULL_TREE
);
5592 rprotos
= (TYPE_HAS_OBJC_INFO (TREE_TYPE (rtype
))
5593 ? TYPE_OBJC_PROTOCOL_LIST (TREE_TYPE (rtype
))
5600 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
5601 in protocols themselves for the method prototype. */
5603 = lookup_method_in_protocol_list (rprotos
, sel_name
,
5604 class_tree
!= NULL_TREE
);
5606 /* If messaging 'Class <Proto>' but did not find a class method
5607 prototype, search for an instance method instead, and warn
5608 about having done so. */
5609 if (!method_prototype
&& !rtype
&& class_tree
!= NULL_TREE
)
5612 = lookup_method_in_protocol_list (rprotos
, sel_name
, 0);
5614 if (method_prototype
)
5615 warning ("found %<-%s%> instead of %<+%s%> in protocol(s)",
5616 IDENTIFIER_POINTER (sel_name
),
5617 IDENTIFIER_POINTER (sel_name
));
5623 tree orig_rtype
= rtype
, saved_rtype
;
5625 if (TREE_CODE (rtype
) == POINTER_TYPE
)
5626 rtype
= TREE_TYPE (rtype
);
5627 /* Traverse typedef aliases */
5628 while (TREE_CODE (rtype
) == RECORD_TYPE
&& OBJC_TYPE_NAME (rtype
)
5629 && TREE_CODE (OBJC_TYPE_NAME (rtype
)) == TYPE_DECL
5630 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype
)))
5631 rtype
= DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype
));
5632 saved_rtype
= rtype
;
5633 if (TYPED_OBJECT (rtype
))
5635 rprotos
= TYPE_OBJC_PROTOCOL_LIST (rtype
);
5636 rtype
= TYPE_OBJC_INTERFACE (rtype
);
5638 /* If we could not find an @interface declaration, we must have
5639 only seen a @class declaration; so, we cannot say anything
5640 more intelligent about which methods the receiver will
5642 if (!rtype
|| TREE_CODE (rtype
) == IDENTIFIER_NODE
)
5643 rtype
= saved_rtype
;
5644 else if (TREE_CODE (rtype
) == CLASS_INTERFACE_TYPE
5645 || TREE_CODE (rtype
) == CLASS_IMPLEMENTATION_TYPE
)
5647 /* We have a valid ObjC class name. Look up the method name
5648 in the published @interface for the class (and its
5651 = lookup_method_static (rtype
, sel_name
, class_tree
!= NULL_TREE
);
5653 /* If the method was not found in the @interface, it may still
5654 exist locally as part of the @implementation. */
5655 if (!method_prototype
&& objc_implementation_context
5656 && CLASS_NAME (objc_implementation_context
)
5657 == OBJC_TYPE_NAME (rtype
))
5661 ? CLASS_CLS_METHODS (objc_implementation_context
)
5662 : CLASS_NST_METHODS (objc_implementation_context
)),
5665 /* If we haven't found a candidate method by now, try looking for
5666 it in the protocol list. */
5667 if (!method_prototype
&& rprotos
)
5669 = lookup_method_in_protocol_list (rprotos
, sel_name
,
5670 class_tree
!= NULL_TREE
);
5674 warning ("invalid receiver type %qs",
5675 gen_type_name (orig_rtype
));
5676 /* After issuing the "invalid receiver" warning, perform method
5677 lookup as if we were messaging 'id'. */
5678 rtype
= rprotos
= NULL_TREE
;
5683 /* For 'id' or 'Class' receivers, search in the global hash table
5684 as a last resort. For all receivers, warn if protocol searches
5686 if (!method_prototype
)
5689 warning ("%<%c%s%> not found in protocol(s)",
5690 (class_tree
? '+' : '-'),
5691 IDENTIFIER_POINTER (sel_name
));
5695 = lookup_method_in_hash_lists (sel_name
, class_tree
!= NULL_TREE
);
5698 if (!method_prototype
)
5700 static bool warn_missing_methods
= false;
5703 warning ("%qs may not respond to %<%c%s%>",
5704 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype
)),
5705 (class_tree
? '+' : '-'),
5706 IDENTIFIER_POINTER (sel_name
));
5707 /* If we are messaging an 'id' or 'Class' object and made it here,
5708 then we have failed to find _any_ instance or class method,
5711 warning ("no %<%c%s%> method found",
5712 (class_tree
? '+' : '-'),
5713 IDENTIFIER_POINTER (sel_name
));
5715 if (!warn_missing_methods
)
5717 warning ("(Messages without a matching method signature");
5718 warning ("will be assumed to return %<id%> and accept");
5719 warning ("%<...%> as arguments.)");
5720 warn_missing_methods
= true;
5724 /* Save the selector name for printing error messages. */
5725 current_objc_message_selector
= sel_name
;
5727 /* Build the parameters list for looking up the method.
5728 These are the object itself and the selector. */
5730 if (flag_typed_selectors
)
5731 selector
= build_typed_selector_reference (sel_name
, method_prototype
);
5733 selector
= build_selector_reference (sel_name
);
5735 retval
= build_objc_method_call (super
, method_prototype
,
5737 selector
, method_params
);
5739 current_objc_message_selector
= 0;
5744 /* Build a tree expression to send OBJECT the operation SELECTOR,
5745 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5746 assuming the method has prototype METHOD_PROTOTYPE.
5747 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5748 Use METHOD_PARAMS as list of args to pass to the method.
5749 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5752 build_objc_method_call (int super_flag
, tree method_prototype
,
5753 tree lookup_object
, tree selector
,
5756 tree sender
= (super_flag
? umsg_super_decl
:
5757 (!flag_next_runtime
|| flag_nil_receivers
5759 : umsg_nonnil_decl
));
5760 tree rcv_p
= (super_flag
? objc_super_type
: objc_object_type
);
5762 /* If a prototype for the method to be called exists, then cast
5763 the sender's return type and arguments to match that of the method.
5764 Otherwise, leave sender as is. */
5767 ? TREE_VALUE (TREE_TYPE (method_prototype
))
5768 : objc_object_type
);
5770 = build_pointer_type
5771 (build_function_type
5774 (method_prototype
, METHOD_REF
, super_flag
)));
5777 lookup_object
= build_c_cast (rcv_p
, lookup_object
);
5779 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
5780 lookup_object
= save_expr (lookup_object
);
5782 if (flag_next_runtime
)
5784 /* If we are returning a struct in memory, and the address
5785 of that memory location is passed as a hidden first
5786 argument, then change which messenger entry point this
5787 expr will call. NB: Note that sender_cast remains
5788 unchanged (it already has a struct return type). */
5789 if (!targetm
.calls
.struct_value_rtx (0, 0)
5790 && (TREE_CODE (ret_type
) == RECORD_TYPE
5791 || TREE_CODE (ret_type
) == UNION_TYPE
)
5792 && targetm
.calls
.return_in_memory (ret_type
, 0))
5793 sender
= (super_flag
? umsg_super_stret_decl
:
5794 flag_nil_receivers
? umsg_stret_decl
: umsg_nonnil_stret_decl
);
5796 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5797 tree_cons (NULL_TREE
, selector
,
5799 method
= build_fold_addr_expr (sender
);
5803 /* This is the portable (GNU) way. */
5806 /* First, call the lookup function to get a pointer to the method,
5807 then cast the pointer, then call it with the method arguments. */
5809 object
= (super_flag
? self_decl
: lookup_object
);
5811 t
= tree_cons (NULL_TREE
, selector
, NULL_TREE
);
5812 t
= tree_cons (NULL_TREE
, lookup_object
, t
);
5813 method
= build_function_call (sender
, t
);
5815 /* Pass the object to the method. */
5816 method_params
= tree_cons (NULL_TREE
, object
,
5817 tree_cons (NULL_TREE
, selector
,
5821 /* ??? Selector is not at this point something we can use inside
5822 the compiler itself. Set it to garbage for the nonce. */
5823 t
= build (OBJ_TYPE_REF
, sender_cast
, method
, lookup_object
, size_zero_node
);
5824 return build_function_call (t
, method_params
);
5828 build_protocol_reference (tree p
)
5831 const char *proto_name
;
5833 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
5835 proto_name
= synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
);
5836 decl
= start_var_decl (objc_protocol_template
, proto_name
);
5838 PROTOCOL_FORWARD_DECL (p
) = decl
;
5841 /* This function is called by the parser when (and only when) a
5842 @protocol() expression is found, in order to compile it. */
5844 objc_build_protocol_expr (tree protoname
)
5847 tree p
= lookup_protocol (protoname
);
5851 error ("cannot find protocol declaration for %qs",
5852 IDENTIFIER_POINTER (protoname
));
5853 return error_mark_node
;
5856 if (!PROTOCOL_FORWARD_DECL (p
))
5857 build_protocol_reference (p
);
5859 expr
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
5861 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
5862 if we have it, rather than converting it here. */
5863 expr
= convert (objc_protocol_type
, expr
);
5865 /* The @protocol() expression is being compiled into a pointer to a
5866 statically allocated instance of the Protocol class. To become
5867 usable at runtime, the 'isa' pointer of the instance need to be
5868 fixed up at runtime by the runtime library, to point to the
5869 actual 'Protocol' class. */
5871 /* For the GNU runtime, put the static Protocol instance in the list
5872 of statically allocated instances, so that we make sure that its
5873 'isa' pointer is fixed up at runtime by the GNU runtime library
5874 to point to the Protocol class (at runtime, when loading the
5875 module, the GNU runtime library loops on the statically allocated
5876 instances (as found in the defs field in objc_symtab) and fixups
5877 all the 'isa' pointers of those objects). */
5878 if (! flag_next_runtime
)
5880 /* This type is a struct containing the fields of a Protocol
5881 object. (Cfr. objc_protocol_type instead is the type of a pointer
5882 to such a struct). */
5883 tree protocol_struct_type
= xref_tag
5884 (RECORD_TYPE
, get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
5887 /* Look for the list of Protocol statically allocated instances
5888 to fixup at runtime. Create a new list to hold Protocol
5889 statically allocated instances, if the list is not found. At
5890 present there is only another list, holding NSConstantString
5891 static instances to be fixed up at runtime. */
5892 for (chain
= &objc_static_instances
;
5893 *chain
&& TREE_VALUE (*chain
) != protocol_struct_type
;
5894 chain
= &TREE_CHAIN (*chain
));
5897 *chain
= tree_cons (NULL_TREE
, protocol_struct_type
, NULL_TREE
);
5898 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type
),
5902 /* Add this statically allocated instance to the Protocol list. */
5903 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
,
5904 PROTOCOL_FORWARD_DECL (p
),
5905 TREE_PURPOSE (*chain
));
5912 /* This function is called by the parser when a @selector() expression
5913 is found, in order to compile it. It is only called by the parser
5914 and only to compile a @selector(). */
5916 objc_build_selector_expr (tree selnamelist
)
5920 /* Obtain the full selector name. */
5921 if (TREE_CODE (selnamelist
) == IDENTIFIER_NODE
)
5922 /* A unary selector. */
5923 selname
= selnamelist
;
5924 else if (TREE_CODE (selnamelist
) == TREE_LIST
)
5925 selname
= build_keyword_selector (selnamelist
);
5929 /* If we are required to check @selector() expressions as they
5930 are found, check that the selector has been declared. */
5931 if (warn_undeclared_selector
)
5933 /* Look the selector up in the list of all known class and
5934 instance methods (up to this line) to check that the selector
5938 /* First try with instance methods. */
5939 hsh
= hash_lookup (nst_method_hash_list
, selname
);
5941 /* If not found, try with class methods. */
5944 hsh
= hash_lookup (cls_method_hash_list
, selname
);
5947 /* If still not found, print out a warning. */
5950 warning ("undeclared selector %qs", IDENTIFIER_POINTER (selname
));
5955 if (flag_typed_selectors
)
5956 return build_typed_selector_reference (selname
, 0);
5958 return build_selector_reference (selname
);
5962 objc_build_encode_expr (tree type
)
5967 encode_type (type
, obstack_object_size (&util_obstack
),
5968 OBJC_ENCODE_INLINE_DEFS
);
5969 obstack_1grow (&util_obstack
, 0); /* null terminate string */
5970 string
= obstack_finish (&util_obstack
);
5972 /* Synthesize a string that represents the encoded struct/union. */
5973 result
= my_build_string (strlen (string
) + 1, string
);
5974 obstack_free (&util_obstack
, util_firstobj
);
5979 build_ivar_reference (tree id
)
5981 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
5983 /* Historically, a class method that produced objects (factory
5984 method) would assign `self' to the instance that it
5985 allocated. This would effectively turn the class method into
5986 an instance method. Following this assignment, the instance
5987 variables could be accessed. That practice, while safe,
5988 violates the simple rule that a class method should not refer
5989 to an instance variable. It's better to catch the cases
5990 where this is done unknowingly than to support the above
5992 warning ("instance variable %qs accessed in class method",
5993 IDENTIFIER_POINTER (id
));
5994 self_decl
= convert (objc_instance_type
, self_decl
); /* cast */
5997 return build_component_ref (build_indirect_ref (self_decl
, "->"), id
);
6000 /* Compute a hash value for a given method SEL_NAME. */
6003 hash_func (tree sel_name
)
6005 const unsigned char *s
6006 = (const unsigned char *)IDENTIFIER_POINTER (sel_name
);
6010 h
= h
* 67 + *s
++ - 113;
6017 nst_method_hash_list
6018 = (hash
*) ggc_alloc_cleared (SIZEHASHTABLE
* sizeof (hash
));
6019 cls_method_hash_list
6020 = (hash
*) ggc_alloc_cleared (SIZEHASHTABLE
* sizeof (hash
));
6022 /* Initialize the hash table used to hold the constant string objects. */
6023 string_htab
= htab_create_ggc (31, string_hash
,
6027 /* WARNING!!!! hash_enter is called with a method, and will peek
6028 inside to find its selector! But hash_lookup is given a selector
6029 directly, and looks for the selector that's inside the found
6030 entry's key (method) for comparison. */
6033 hash_enter (hash
*hashlist
, tree method
)
6036 int slot
= hash_func (METHOD_SEL_NAME (method
)) % SIZEHASHTABLE
;
6038 obj
= (hash
) ggc_alloc (sizeof (struct hashed_entry
));
6040 obj
->next
= hashlist
[slot
];
6043 hashlist
[slot
] = obj
; /* append to front */
6047 hash_lookup (hash
*hashlist
, tree sel_name
)
6051 target
= hashlist
[hash_func (sel_name
) % SIZEHASHTABLE
];
6055 if (sel_name
== METHOD_SEL_NAME (target
->key
))
6058 target
= target
->next
;
6064 hash_add_attr (hash entry
, tree value
)
6068 obj
= (attr
) ggc_alloc (sizeof (struct hashed_attribute
));
6069 obj
->next
= entry
->list
;
6072 entry
->list
= obj
; /* append to front */
6076 lookup_method (tree mchain
, tree method
)
6080 if (TREE_CODE (method
) == IDENTIFIER_NODE
)
6083 key
= METHOD_SEL_NAME (method
);
6087 if (METHOD_SEL_NAME (mchain
) == key
)
6090 mchain
= TREE_CHAIN (mchain
);
6096 lookup_method_static (tree interface
, tree ident
, int is_class
)
6098 tree meth
= NULL_TREE
, root_inter
= NULL_TREE
;
6099 tree inter
= interface
;
6103 tree chain
= is_class
? CLASS_CLS_METHODS (inter
) : CLASS_NST_METHODS (inter
);
6104 tree category
= inter
;
6106 /* First, look up the method in the class itself. */
6107 if ((meth
= lookup_method (chain
, ident
)))
6110 /* Failing that, look for the method in each category of the class. */
6111 while ((category
= CLASS_CATEGORY_LIST (category
)))
6113 chain
= is_class
? CLASS_CLS_METHODS (category
) : CLASS_NST_METHODS (category
);
6115 /* Check directly in each category. */
6116 if ((meth
= lookup_method (chain
, ident
)))
6119 /* Failing that, check in each category's protocols. */
6120 if (CLASS_PROTOCOL_LIST (category
))
6122 if ((meth
= (lookup_method_in_protocol_list
6123 (CLASS_PROTOCOL_LIST (category
), ident
, is_class
))))
6128 /* If not found in categories, check in protocols of the main class. */
6129 if (CLASS_PROTOCOL_LIST (inter
))
6131 if ((meth
= (lookup_method_in_protocol_list
6132 (CLASS_PROTOCOL_LIST (inter
), ident
, is_class
))))
6136 /* Failing that, climb up the inheritance hierarchy. */
6138 inter
= lookup_interface (CLASS_SUPER_NAME (inter
));
6142 /* If no class (factory) method was found, check if an _instance_
6143 method of the same name exists in the root class. This is what
6144 the Objective-C runtime will do. If an instance method was not
6146 return is_class
? lookup_method_static (root_inter
, ident
, 0): NULL_TREE
;
6149 /* Add the method to the hash list if it doesn't contain an identical
6152 add_method_to_hash_list (hash
*hash_list
, tree method
)
6156 if (!(hsh
= hash_lookup (hash_list
, METHOD_SEL_NAME (method
))))
6158 /* Install on a global chain. */
6159 hash_enter (hash_list
, method
);
6163 /* Check types against those; if different, add to a list. */
6165 int already_there
= comp_proto_with_proto (method
, hsh
->key
);
6166 for (loop
= hsh
->list
; !already_there
&& loop
; loop
= loop
->next
)
6167 already_there
|= comp_proto_with_proto (method
, loop
->value
);
6169 hash_add_attr (hsh
, method
);
6174 objc_add_method (tree
class, tree method
, int is_class
)
6178 if (!(mth
= lookup_method (is_class
6179 ? CLASS_CLS_METHODS (class)
6180 : CLASS_NST_METHODS (class), method
)))
6182 /* put method on list in reverse order */
6185 TREE_CHAIN (method
) = CLASS_CLS_METHODS (class);
6186 CLASS_CLS_METHODS (class) = method
;
6190 TREE_CHAIN (method
) = CLASS_NST_METHODS (class);
6191 CLASS_NST_METHODS (class) = method
;
6196 /* When processing an @interface for a class or category, give hard
6197 errors on methods with identical selectors but differing argument
6198 and/or return types. We do not do this for @implementations, because
6199 C/C++ will do it for us (i.e., there will be duplicate function
6200 definition errors). */
6201 if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
6202 || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
)
6203 && !comp_proto_with_proto (method
, mth
))
6204 error ("duplicate declaration of method %<%c%s%>",
6205 is_class
? '+' : '-',
6206 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
6210 add_method_to_hash_list (cls_method_hash_list
, method
);
6213 add_method_to_hash_list (nst_method_hash_list
, method
);
6215 /* Instance methods in root classes (and categories thereof)
6216 may act as class methods as a last resort. We also add
6217 instance methods listed in @protocol declarations to
6218 the class hash table, on the assumption that @protocols
6219 may be adopted by root classes or categories. */
6220 if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
6221 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6222 class = lookup_interface (CLASS_NAME (class));
6224 if (TREE_CODE (class) == PROTOCOL_INTERFACE_TYPE
6225 || !CLASS_SUPER_NAME (class))
6226 add_method_to_hash_list (cls_method_hash_list
, method
);
6233 add_class (tree
class)
6235 /* Put interfaces on list in reverse order. */
6236 TREE_CHAIN (class) = interface_chain
;
6237 interface_chain
= class;
6238 return interface_chain
;
6242 add_category (tree
class, tree category
)
6244 /* Put categories on list in reverse order. */
6245 tree cat
= lookup_category (class, CLASS_SUPER_NAME (category
));
6249 warning ("duplicate interface declaration for category %<%s(%s)%>",
6250 IDENTIFIER_POINTER (CLASS_NAME (class)),
6251 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category
)));
6255 CLASS_CATEGORY_LIST (category
) = CLASS_CATEGORY_LIST (class);
6256 CLASS_CATEGORY_LIST (class) = category
;
6260 /* Called after parsing each instance variable declaration. Necessary to
6261 preserve typedefs and implement public/private...
6263 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
6266 add_instance_variable (tree
class, int public, tree field_decl
)
6268 tree field_type
= TREE_TYPE (field_decl
);
6269 const char *ivar_name
= DECL_NAME (field_decl
)
6270 ? IDENTIFIER_POINTER (DECL_NAME (field_decl
))
6274 if (TREE_CODE (field_type
) == REFERENCE_TYPE
)
6276 error ("illegal reference type specified for instance variable %qs",
6278 /* Return class as is without adding this ivar. */
6283 if (field_type
== error_mark_node
|| !TYPE_SIZE (field_type
)
6284 || TYPE_SIZE (field_type
) == error_mark_node
)
6285 /* 'type[0]' is allowed, but 'type[]' is not! */
6287 error ("instance variable %qs has unknown size", ivar_name
);
6288 /* Return class as is without adding this ivar. */
6293 /* zlaski 2001-Apr-24: C++ classes with non-trivial constructors and/or destructors
6294 cannot be ivars; ditto for classes with vtables. */
6295 if(IS_AGGR_TYPE (field_type
) && (TYPE_NEEDS_CONSTRUCTING (field_type
)
6296 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type
) || TYPE_POLYMORPHIC_P (field_type
)))
6298 const char *type_name
= IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type
));
6299 if(TYPE_POLYMORPHIC_P (field_type
)) {
6300 /* vtable pointers are Real Bad(tm), since Obj-C cannot initialize them */
6301 error ("type %qs has virtual member functions", type_name
);
6302 error ("illegal aggregate type %qs specified for instance variable %qs",
6303 type_name
, ivar_name
);
6304 /* Return class as is without adding this ivar. */
6307 /* user-defined constructors and destructors are not known to Obj-C and
6308 hence will not be called. This may or may not be a problem. */
6309 if (TYPE_NEEDS_CONSTRUCTING (field_type
))
6310 warning ("type %qs has a user-defined constructor", type_name
);
6311 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type
))
6312 warning ("type %qs has a user-defined destructor", type_name
);
6313 warning ("C++ constructors and destructors will not be invoked for Objective-C fields");
6317 /* Overload the public attribute, it is not used for FIELD_DECLs. */
6321 TREE_PUBLIC (field_decl
) = 0;
6322 TREE_PRIVATE (field_decl
) = 0;
6323 TREE_PROTECTED (field_decl
) = 1;
6327 TREE_PUBLIC (field_decl
) = 1;
6328 TREE_PRIVATE (field_decl
) = 0;
6329 TREE_PROTECTED (field_decl
) = 0;
6333 TREE_PUBLIC (field_decl
) = 0;
6334 TREE_PRIVATE (field_decl
) = 1;
6335 TREE_PROTECTED (field_decl
) = 0;
6340 CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), field_decl
);
6346 is_ivar (tree decl_chain
, tree ident
)
6348 for ( ; decl_chain
; decl_chain
= TREE_CHAIN (decl_chain
))
6349 if (DECL_NAME (decl_chain
) == ident
)
6354 /* True if the ivar is private and we are not in its implementation. */
6357 is_private (tree decl
)
6359 return (TREE_PRIVATE (decl
)
6360 && ! is_ivar (CLASS_IVARS (implementation_template
),
6364 /* We have an instance variable reference;, check to see if it is public. */
6367 objc_is_public (tree expr
, tree identifier
)
6369 tree basetype
= TREE_TYPE (expr
);
6370 enum tree_code code
= TREE_CODE (basetype
);
6373 if (code
== RECORD_TYPE
)
6375 if (TYPE_HAS_OBJC_INFO (basetype
) && TYPE_OBJC_INTERFACE (basetype
))
6377 if (TREE_CODE (TYPE_OBJC_INTERFACE (basetype
)) == IDENTIFIER_NODE
)
6379 error ("cannot find interface declaration for %qs",
6380 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype
)));
6384 if ((decl
= is_ivar (TYPE_FIELDS (basetype
), identifier
)))
6386 if (TREE_PUBLIC (decl
))
6389 /* Important difference between the Stepstone translator:
6390 all instance variables should be public within the context
6391 of the implementation. */
6392 if (objc_implementation_context
6393 && (((TREE_CODE (objc_implementation_context
)
6394 == CLASS_IMPLEMENTATION_TYPE
)
6395 || (TREE_CODE (objc_implementation_context
)
6396 == CATEGORY_IMPLEMENTATION_TYPE
))
6397 && (CLASS_NAME (objc_implementation_context
)
6398 == OBJC_TYPE_NAME (basetype
))))
6400 int private = is_private (decl
);
6403 error ("instance variable %qs is declared private",
6404 IDENTIFIER_POINTER (DECL_NAME (decl
)));
6408 /* The 2.95.2 compiler sometimes allowed C functions to access
6409 non-@public ivars. We will let this slide for now... */
6410 if (!objc_method_context
)
6412 warning ("instance variable %qs is %s; "
6413 "this will be a hard error in the future",
6414 IDENTIFIER_POINTER (identifier
),
6415 TREE_PRIVATE (decl
) ? "@private" : "@protected");
6419 error ("instance variable %qs is declared %s",
6420 IDENTIFIER_POINTER (identifier
),
6421 TREE_PRIVATE (decl
) ? "private" : "protected");
6426 else if (objc_implementation_context
&& (basetype
== objc_object_reference
))
6428 expr
= convert (uprivate_record
, expr
);
6429 warning ("static access to object of type %<id%>");
6436 /* Make sure all entries in CHAIN are also in LIST. */
6439 check_methods (tree chain
, tree list
, int mtype
)
6445 if (!lookup_method (list
, chain
))
6449 if (TREE_CODE (objc_implementation_context
)
6450 == CLASS_IMPLEMENTATION_TYPE
)
6451 warning ("incomplete implementation of class %qs",
6452 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
)));
6453 else if (TREE_CODE (objc_implementation_context
)
6454 == CATEGORY_IMPLEMENTATION_TYPE
)
6455 warning ("incomplete implementation of category %qs",
6456 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
6460 warning ("method definition for %<%c%s%> not found",
6461 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
6464 chain
= TREE_CHAIN (chain
);
6470 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
6473 conforms_to_protocol (tree
class, tree protocol
)
6475 if (TREE_CODE (protocol
) == PROTOCOL_INTERFACE_TYPE
)
6477 tree p
= CLASS_PROTOCOL_LIST (class);
6478 while (p
&& TREE_VALUE (p
) != protocol
)
6483 tree super
= (CLASS_SUPER_NAME (class)
6484 ? lookup_interface (CLASS_SUPER_NAME (class))
6486 int tmp
= super
? conforms_to_protocol (super
, protocol
) : 0;
6495 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
6496 CONTEXT. This is one of two mechanisms to check protocol integrity. */
6499 check_methods_accessible (tree chain
, tree context
, int mtype
)
6503 tree base_context
= context
;
6507 context
= base_context
;
6511 list
= CLASS_CLS_METHODS (context
);
6513 list
= CLASS_NST_METHODS (context
);
6515 if (lookup_method (list
, chain
))
6518 else if (TREE_CODE (context
) == CLASS_IMPLEMENTATION_TYPE
6519 || TREE_CODE (context
) == CLASS_INTERFACE_TYPE
)
6520 context
= (CLASS_SUPER_NAME (context
)
6521 ? lookup_interface (CLASS_SUPER_NAME (context
))
6524 else if (TREE_CODE (context
) == CATEGORY_IMPLEMENTATION_TYPE
6525 || TREE_CODE (context
) == CATEGORY_INTERFACE_TYPE
)
6526 context
= (CLASS_NAME (context
)
6527 ? lookup_interface (CLASS_NAME (context
))
6533 if (context
== NULL_TREE
)
6537 if (TREE_CODE (objc_implementation_context
)
6538 == CLASS_IMPLEMENTATION_TYPE
)
6539 warning ("incomplete implementation of class %qs",
6541 (CLASS_NAME (objc_implementation_context
)));
6542 else if (TREE_CODE (objc_implementation_context
)
6543 == CATEGORY_IMPLEMENTATION_TYPE
)
6544 warning ("incomplete implementation of category %qs",
6546 (CLASS_SUPER_NAME (objc_implementation_context
)));
6549 warning ("method definition for %<%c%s%> not found",
6550 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
6553 chain
= TREE_CHAIN (chain
); /* next method... */
6558 /* Check whether the current interface (accessible via
6559 'objc_implementation_context') actually implements protocol P, along
6560 with any protocols that P inherits. */
6563 check_protocol (tree p
, const char *type
, const char *name
)
6565 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
6569 /* Ensure that all protocols have bodies! */
6572 f1
= check_methods (PROTOCOL_CLS_METHODS (p
),
6573 CLASS_CLS_METHODS (objc_implementation_context
),
6575 f2
= check_methods (PROTOCOL_NST_METHODS (p
),
6576 CLASS_NST_METHODS (objc_implementation_context
),
6581 f1
= check_methods_accessible (PROTOCOL_CLS_METHODS (p
),
6582 objc_implementation_context
,
6584 f2
= check_methods_accessible (PROTOCOL_NST_METHODS (p
),
6585 objc_implementation_context
,
6590 warning ("%s %qs does not fully implement the %qs protocol",
6591 type
, name
, IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
6594 /* Check protocols recursively. */
6595 if (PROTOCOL_LIST (p
))
6597 tree subs
= PROTOCOL_LIST (p
);
6599 lookup_interface (CLASS_SUPER_NAME (implementation_template
));
6603 tree sub
= TREE_VALUE (subs
);
6605 /* If the superclass does not conform to the protocols
6606 inherited by P, then we must! */
6607 if (!super_class
|| !conforms_to_protocol (super_class
, sub
))
6608 check_protocol (sub
, type
, name
);
6609 subs
= TREE_CHAIN (subs
);
6614 /* Check whether the current interface (accessible via
6615 'objc_implementation_context') actually implements the protocols listed
6619 check_protocols (tree proto_list
, const char *type
, const char *name
)
6621 for ( ; proto_list
; proto_list
= TREE_CHAIN (proto_list
))
6623 tree p
= TREE_VALUE (proto_list
);
6625 check_protocol (p
, type
, name
);
6629 /* Make sure that the class CLASS_NAME is defined
6630 CODE says which kind of thing CLASS_NAME ought to be.
6631 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6632 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6635 start_class (enum tree_code code
, tree class_name
, tree super_name
,
6641 if (current_namespace
!= global_namespace
) {
6642 error ("Objective-C declarations may only appear in global scope");
6644 #endif /* OBJCPLUS */
6646 if (objc_implementation_context
)
6648 warning ("%<@end%> missing in implementation context");
6649 finish_class (objc_implementation_context
);
6650 objc_ivar_chain
= NULL_TREE
;
6651 objc_implementation_context
= NULL_TREE
;
6654 class = make_node (code
);
6655 TYPE_LANG_SLOT_1 (class) = make_tree_vec (CLASS_LANG_SLOT_ELTS
);
6657 /* Check for existence of the super class, if one was specified. */
6658 if ((code
== CLASS_INTERFACE_TYPE
|| code
== CLASS_IMPLEMENTATION_TYPE
)
6659 && super_name
&& !objc_is_class_name (super_name
))
6661 error ("cannot find interface declaration for %qs, superclass of %qs",
6662 IDENTIFIER_POINTER (super_name
),
6663 IDENTIFIER_POINTER (class_name
));
6664 super_name
= NULL_TREE
;
6667 CLASS_NAME (class) = class_name
;
6668 CLASS_SUPER_NAME (class) = super_name
;
6669 CLASS_CLS_METHODS (class) = NULL_TREE
;
6671 if (! objc_is_class_name (class_name
)
6672 && (decl
= lookup_name (class_name
)))
6674 error ("%qs redeclared as different kind of symbol",
6675 IDENTIFIER_POINTER (class_name
));
6676 error ("%Jprevious declaration of '%D'",
6680 if (code
== CLASS_IMPLEMENTATION_TYPE
)
6685 for (chain
= implemented_classes
; chain
; chain
= TREE_CHAIN (chain
))
6686 if (TREE_VALUE (chain
) == class_name
)
6688 error ("reimplementation of class %qs",
6689 IDENTIFIER_POINTER (class_name
));
6690 return error_mark_node
;
6692 implemented_classes
= tree_cons (NULL_TREE
, class_name
,
6693 implemented_classes
);
6696 /* Reset for multiple classes per file. */
6699 objc_implementation_context
= class;
6701 /* Lookup the interface for this implementation. */
6703 if (!(implementation_template
= lookup_interface (class_name
)))
6705 warning ("cannot find interface declaration for %qs",
6706 IDENTIFIER_POINTER (class_name
));
6707 add_class (implementation_template
= objc_implementation_context
);
6710 /* If a super class has been specified in the implementation,
6711 insure it conforms to the one specified in the interface. */
6714 && (super_name
!= CLASS_SUPER_NAME (implementation_template
)))
6716 tree previous_name
= CLASS_SUPER_NAME (implementation_template
);
6717 const char *const name
=
6718 previous_name
? IDENTIFIER_POINTER (previous_name
) : "";
6719 error ("conflicting super class name %qs",
6720 IDENTIFIER_POINTER (super_name
));
6721 error ("previous declaration of %qs", name
);
6724 else if (! super_name
)
6726 CLASS_SUPER_NAME (objc_implementation_context
)
6727 = CLASS_SUPER_NAME (implementation_template
);
6731 else if (code
== CLASS_INTERFACE_TYPE
)
6733 if (lookup_interface (class_name
))
6735 error ("duplicate interface declaration for class %qs",
6737 warning ("duplicate interface declaration for class %qs",
6739 IDENTIFIER_POINTER (class_name
));
6744 CLASS_PROTOCOL_LIST (class)
6745 = lookup_and_install_protocols (protocol_list
);
6748 else if (code
== CATEGORY_INTERFACE_TYPE
)
6750 tree class_category_is_assoc_with
;
6752 /* For a category, class_name is really the name of the class that
6753 the following set of methods will be associated with. We must
6754 find the interface so that can derive the objects template. */
6756 if (!(class_category_is_assoc_with
= lookup_interface (class_name
)))
6758 error ("cannot find interface declaration for %qs",
6759 IDENTIFIER_POINTER (class_name
));
6760 exit (FATAL_EXIT_CODE
);
6763 add_category (class_category_is_assoc_with
, class);
6766 CLASS_PROTOCOL_LIST (class)
6767 = lookup_and_install_protocols (protocol_list
);
6770 else if (code
== CATEGORY_IMPLEMENTATION_TYPE
)
6772 /* Reset for multiple classes per file. */
6775 objc_implementation_context
= class;
6777 /* For a category, class_name is really the name of the class that
6778 the following set of methods will be associated with. We must
6779 find the interface so that can derive the objects template. */
6781 if (!(implementation_template
= lookup_interface (class_name
)))
6783 error ("cannot find interface declaration for %qs",
6784 IDENTIFIER_POINTER (class_name
));
6785 exit (FATAL_EXIT_CODE
);
6792 continue_class (tree
class)
6794 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6795 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6797 struct imp_entry
*imp_entry
;
6800 /* Check consistency of the instance variables. */
6802 if (CLASS_RAW_IVARS (class))
6803 check_ivars (implementation_template
, class);
6805 /* code generation */
6808 push_lang_context (lang_name_c
);
6811 build_private_template (implementation_template
);
6812 uprivate_record
= CLASS_STATIC_TEMPLATE (implementation_template
);
6813 ivar_context
= TYPE_FIELDS (uprivate_record
);
6814 objc_instance_type
= build_pointer_type (uprivate_record
);
6816 imp_entry
= (struct imp_entry
*) ggc_alloc (sizeof (struct imp_entry
));
6818 imp_entry
->next
= imp_list
;
6819 imp_entry
->imp_context
= class;
6820 imp_entry
->imp_template
= implementation_template
;
6822 synth_forward_declarations ();
6823 imp_entry
->class_decl
= UOBJC_CLASS_decl
;
6824 imp_entry
->meta_decl
= UOBJC_METACLASS_decl
;
6826 /* Append to front and increment count. */
6827 imp_list
= imp_entry
;
6828 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6834 pop_lang_context ();
6835 #endif /* OBJCPLUS */
6837 return ivar_context
;
6840 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6843 push_lang_context (lang_name_c
);
6844 #endif /* OBJCPLUS */
6846 build_private_template (class);
6849 pop_lang_context ();
6850 #endif /* OBJCPLUS */
6856 return error_mark_node
;
6859 /* This is called once we see the "@end" in an interface/implementation. */
6862 finish_class (tree
class)
6864 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6866 /* All code generation is done in finish_objc. */
6868 if (implementation_template
!= objc_implementation_context
)
6870 /* Ensure that all method listed in the interface contain bodies. */
6871 check_methods (CLASS_CLS_METHODS (implementation_template
),
6872 CLASS_CLS_METHODS (objc_implementation_context
), '+');
6873 check_methods (CLASS_NST_METHODS (implementation_template
),
6874 CLASS_NST_METHODS (objc_implementation_context
), '-');
6876 if (CLASS_PROTOCOL_LIST (implementation_template
))
6877 check_protocols (CLASS_PROTOCOL_LIST (implementation_template
),
6879 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
)));
6883 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6885 tree category
= lookup_category (implementation_template
, CLASS_SUPER_NAME (class));
6889 /* Ensure all method listed in the interface contain bodies. */
6890 check_methods (CLASS_CLS_METHODS (category
),
6891 CLASS_CLS_METHODS (objc_implementation_context
), '+');
6892 check_methods (CLASS_NST_METHODS (category
),
6893 CLASS_NST_METHODS (objc_implementation_context
), '-');
6895 if (CLASS_PROTOCOL_LIST (category
))
6896 check_protocols (CLASS_PROTOCOL_LIST (category
),
6898 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
6904 add_protocol (tree protocol
)
6906 /* Put protocol on list in reverse order. */
6907 TREE_CHAIN (protocol
) = protocol_chain
;
6908 protocol_chain
= protocol
;
6909 return protocol_chain
;
6913 lookup_protocol (tree ident
)
6917 for (chain
= protocol_chain
; chain
; chain
= TREE_CHAIN (chain
))
6918 if (ident
== PROTOCOL_NAME (chain
))
6924 /* This function forward declares the protocols named by NAMES. If
6925 they are already declared or defined, the function has no effect. */
6928 objc_declare_protocols (tree names
)
6933 if (current_namespace
!= global_namespace
) {
6934 error ("Objective-C declarations may only appear in global scope");
6936 #endif /* OBJCPLUS */
6938 for (list
= names
; list
; list
= TREE_CHAIN (list
))
6940 tree name
= TREE_VALUE (list
);
6942 if (lookup_protocol (name
) == NULL_TREE
)
6944 tree protocol
= make_node (PROTOCOL_INTERFACE_TYPE
);
6946 TYPE_LANG_SLOT_1 (protocol
)
6947 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS
);
6948 PROTOCOL_NAME (protocol
) = name
;
6949 PROTOCOL_LIST (protocol
) = NULL_TREE
;
6950 add_protocol (protocol
);
6951 PROTOCOL_DEFINED (protocol
) = 0;
6952 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6958 start_protocol (enum tree_code code
, tree name
, tree list
)
6963 if (current_namespace
!= global_namespace
) {
6964 error ("Objective-C declarations may only appear in global scope");
6966 #endif /* OBJCPLUS */
6968 protocol
= lookup_protocol (name
);
6972 protocol
= make_node (code
);
6973 TYPE_LANG_SLOT_1 (protocol
) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS
);
6975 PROTOCOL_NAME (protocol
) = name
;
6976 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
6977 add_protocol (protocol
);
6978 PROTOCOL_DEFINED (protocol
) = 1;
6979 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6981 check_protocol_recursively (protocol
, list
);
6983 else if (! PROTOCOL_DEFINED (protocol
))
6985 PROTOCOL_DEFINED (protocol
) = 1;
6986 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
6988 check_protocol_recursively (protocol
, list
);
6992 warning ("duplicate declaration for protocol %qs",
6993 IDENTIFIER_POINTER (name
));
6999 /* "Encode" a data type into a string, which grows in util_obstack.
7000 ??? What is the FORMAT? Someone please document this! */
7003 encode_type_qualifiers (tree declspecs
)
7007 for (spec
= declspecs
; spec
; spec
= TREE_CHAIN (spec
))
7009 if (ridpointers
[(int) RID_IN
] == TREE_VALUE (spec
))
7010 obstack_1grow (&util_obstack
, 'n');
7011 else if (ridpointers
[(int) RID_INOUT
] == TREE_VALUE (spec
))
7012 obstack_1grow (&util_obstack
, 'N');
7013 else if (ridpointers
[(int) RID_OUT
] == TREE_VALUE (spec
))
7014 obstack_1grow (&util_obstack
, 'o');
7015 else if (ridpointers
[(int) RID_BYCOPY
] == TREE_VALUE (spec
))
7016 obstack_1grow (&util_obstack
, 'O');
7017 else if (ridpointers
[(int) RID_BYREF
] == TREE_VALUE (spec
))
7018 obstack_1grow (&util_obstack
, 'R');
7019 else if (ridpointers
[(int) RID_ONEWAY
] == TREE_VALUE (spec
))
7020 obstack_1grow (&util_obstack
, 'V');
7024 /* Encode a pointer type. */
7027 encode_pointer (tree type
, int curtype
, int format
)
7029 tree pointer_to
= TREE_TYPE (type
);
7031 if (TREE_CODE (pointer_to
) == RECORD_TYPE
)
7033 if (OBJC_TYPE_NAME (pointer_to
)
7034 && TREE_CODE (OBJC_TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
)
7036 const char *name
= IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to
));
7038 if (strcmp (name
, TAG_OBJECT
) == 0) /* '@' */
7040 obstack_1grow (&util_obstack
, '@');
7043 else if (TYPE_HAS_OBJC_INFO (pointer_to
)
7044 && TYPE_OBJC_INTERFACE (pointer_to
))
7046 if (generating_instance_variables
)
7048 obstack_1grow (&util_obstack
, '@');
7049 obstack_1grow (&util_obstack
, '"');
7050 obstack_grow (&util_obstack
, name
, strlen (name
));
7051 obstack_1grow (&util_obstack
, '"');
7056 obstack_1grow (&util_obstack
, '@');
7060 else if (strcmp (name
, TAG_CLASS
) == 0) /* '#' */
7062 obstack_1grow (&util_obstack
, '#');
7065 else if (strcmp (name
, TAG_SELECTOR
) == 0) /* ':' */
7067 obstack_1grow (&util_obstack
, ':');
7072 else if (TREE_CODE (pointer_to
) == INTEGER_TYPE
7073 && TYPE_MODE (pointer_to
) == QImode
)
7075 tree pname
= TREE_CODE (OBJC_TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
7076 ? OBJC_TYPE_NAME (pointer_to
)
7077 : DECL_NAME (OBJC_TYPE_NAME (pointer_to
));
7079 if (!flag_next_runtime
|| strcmp (IDENTIFIER_POINTER (pname
), "BOOL"))
7081 /* It appears that "r*" means "const char *" rather than
7083 if (TYPE_READONLY (pointer_to
))
7084 obstack_1grow (&util_obstack
, 'r');
7086 obstack_1grow (&util_obstack
, '*');
7091 /* We have a type that does not get special treatment. */
7093 /* NeXT extension */
7094 obstack_1grow (&util_obstack
, '^');
7095 encode_type (pointer_to
, curtype
, format
);
7099 encode_array (tree type
, int curtype
, int format
)
7101 tree an_int_cst
= TYPE_SIZE (type
);
7102 tree array_of
= TREE_TYPE (type
);
7105 /* An incomplete array is treated like a pointer. */
7106 if (an_int_cst
== NULL
)
7108 encode_pointer (type
, curtype
, format
);
7112 sprintf (buffer
, "[" HOST_WIDE_INT_PRINT_DEC
,
7113 (TREE_INT_CST_LOW (an_int_cst
)
7114 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
7116 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7117 encode_type (array_of
, curtype
, format
);
7118 obstack_1grow (&util_obstack
, ']');
7123 encode_aggregate_within (tree type
, int curtype
, int format
, int left
,
7127 /* NB: aggregates that are pointed to have slightly different encoding
7128 rules in that you never encode the names of instance variables. */
7130 = (obstack_object_size (&util_obstack
) > 0
7131 && *(obstack_next_free (&util_obstack
) - 1) == '^');
7133 = ((format
== OBJC_ENCODE_INLINE_DEFS
|| generating_instance_variables
)
7134 && (!pointed_to
|| obstack_object_size (&util_obstack
) - curtype
== 1));
7136 /* Traverse struct aliases; it is important to get the
7137 original struct and its tag name (if any). */
7138 type
= TYPE_MAIN_VARIANT (type
);
7139 name
= OBJC_TYPE_NAME (type
);
7140 /* Open parenth/bracket. */
7141 obstack_1grow (&util_obstack
, left
);
7143 /* Encode the struct/union tag name, or '?' if a tag was
7144 not provided. Typedef aliases do not qualify. */
7145 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
7147 /* Did this struct have a tag? */
7148 && !TYPE_WAS_ANONYMOUS (type
)
7151 obstack_grow (&util_obstack
,
7152 IDENTIFIER_POINTER (name
),
7153 strlen (IDENTIFIER_POINTER (name
)));
7155 obstack_1grow (&util_obstack
, '?');
7157 /* Encode the types (and possibly names) of the inner fields,
7159 if (inline_contents
)
7161 tree fields
= TYPE_FIELDS (type
);
7163 obstack_1grow (&util_obstack
, '=');
7164 for (; fields
; fields
= TREE_CHAIN (fields
))
7167 /* C++ static members, and things that are not fields at all,
7168 should not appear in the encoding. */
7169 if (TREE_CODE (fields
) != FIELD_DECL
|| TREE_STATIC (fields
))
7172 if (generating_instance_variables
&& !pointed_to
)
7174 tree fname
= DECL_NAME (fields
);
7176 obstack_1grow (&util_obstack
, '"');
7177 if (fname
&& TREE_CODE (fname
) == IDENTIFIER_NODE
)
7178 obstack_grow (&util_obstack
,
7179 IDENTIFIER_POINTER (fname
),
7180 strlen (IDENTIFIER_POINTER (fname
)));
7181 obstack_1grow (&util_obstack
, '"');
7183 encode_field_decl (fields
, curtype
, format
);
7186 /* Close parenth/bracket. */
7187 obstack_1grow (&util_obstack
, right
);
7191 encode_aggregate (tree type
, int curtype
, int format
)
7193 enum tree_code code
= TREE_CODE (type
);
7199 encode_aggregate_within (type
, curtype
, format
, '{', '}');
7204 encode_aggregate_within (type
, curtype
, format
, '(', ')');
7209 obstack_1grow (&util_obstack
, 'i');
7217 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
7221 encode_next_bitfield (int width
)
7224 sprintf (buffer
, "b%d", width
);
7225 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7228 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
7230 encode_type (tree type
, int curtype
, int format
)
7232 enum tree_code code
= TREE_CODE (type
);
7235 if (TYPE_READONLY (type
))
7236 obstack_1grow (&util_obstack
, 'r');
7238 if (code
== INTEGER_TYPE
)
7240 switch (GET_MODE_BITSIZE (TYPE_MODE (type
)))
7242 case 8: c
= TYPE_UNSIGNED (type
) ? 'C' : 'c'; break;
7243 case 16: c
= TYPE_UNSIGNED (type
) ? 'S' : 's'; break;
7245 if (type
== long_unsigned_type_node
7246 || type
== long_integer_type_node
)
7247 c
= TYPE_UNSIGNED (type
) ? 'L' : 'l';
7249 c
= TYPE_UNSIGNED (type
) ? 'I' : 'i';
7251 case 64: c
= TYPE_UNSIGNED (type
) ? 'Q' : 'q'; break;
7254 obstack_1grow (&util_obstack
, c
);
7257 else if (code
== REAL_TYPE
)
7259 /* Floating point types. */
7260 switch (GET_MODE_BITSIZE (TYPE_MODE (type
)))
7262 case 32: c
= 'f'; break;
7265 case 128: c
= 'd'; break;
7268 obstack_1grow (&util_obstack
, c
);
7271 else if (code
== VOID_TYPE
)
7272 obstack_1grow (&util_obstack
, 'v');
7274 else if (code
== BOOLEAN_TYPE
)
7275 obstack_1grow (&util_obstack
, 'B');
7277 else if (code
== ARRAY_TYPE
)
7278 encode_array (type
, curtype
, format
);
7280 else if (code
== POINTER_TYPE
)
7281 encode_pointer (type
, curtype
, format
);
7283 else if (code
== RECORD_TYPE
|| code
== UNION_TYPE
|| code
== ENUMERAL_TYPE
)
7284 encode_aggregate (type
, curtype
, format
);
7286 else if (code
== FUNCTION_TYPE
) /* '?' */
7287 obstack_1grow (&util_obstack
, '?');
7291 encode_gnu_bitfield (int position
, tree type
, int size
)
7293 enum tree_code code
= TREE_CODE (type
);
7295 char charType
= '?';
7297 if (code
== INTEGER_TYPE
)
7299 if (integer_zerop (TYPE_MIN_VALUE (type
)))
7301 /* Unsigned integer types. */
7303 if (TYPE_MODE (type
) == QImode
)
7305 else if (TYPE_MODE (type
) == HImode
)
7307 else if (TYPE_MODE (type
) == SImode
)
7309 if (type
== long_unsigned_type_node
)
7314 else if (TYPE_MODE (type
) == DImode
)
7319 /* Signed integer types. */
7321 if (TYPE_MODE (type
) == QImode
)
7323 else if (TYPE_MODE (type
) == HImode
)
7325 else if (TYPE_MODE (type
) == SImode
)
7327 if (type
== long_integer_type_node
)
7333 else if (TYPE_MODE (type
) == DImode
)
7337 else if (code
== ENUMERAL_TYPE
)
7342 sprintf (buffer
, "b%d%c%d", position
, charType
, size
);
7343 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7347 encode_field_decl (tree field_decl
, int curtype
, int format
)
7352 /* C++ static members, and things that are not fields at all,
7353 should not appear in the encoding. */
7354 if (TREE_CODE (field_decl
) != FIELD_DECL
|| TREE_STATIC (field_decl
))
7358 type
= TREE_TYPE (field_decl
);
7360 /* Generate the bitfield typing information, if needed. Note the difference
7361 between GNU and NeXT runtimes. */
7362 if (DECL_BIT_FIELD_TYPE (field_decl
))
7364 int size
= tree_low_cst (DECL_SIZE (field_decl
), 1);
7366 if (flag_next_runtime
)
7367 encode_next_bitfield (size
);
7369 encode_gnu_bitfield (int_bit_position (field_decl
),
7370 DECL_BIT_FIELD_TYPE (field_decl
), size
);
7373 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
7376 static GTY(()) tree objc_parmlist
= NULL_TREE
;
7378 /* Append PARM to a list of formal parameters of a method, making a necessary
7379 array-to-pointer adjustment along the way. */
7382 objc_push_parm (tree parm
)
7384 /* Decay arrays and functions into pointers. */
7385 if (TREE_CODE (TREE_TYPE (parm
)) == ARRAY_TYPE
)
7386 TREE_TYPE (parm
) = build_pointer_type (TREE_TYPE (TREE_TYPE (parm
)));
7387 else if (TREE_CODE (TREE_TYPE (parm
)) == FUNCTION_TYPE
)
7388 TREE_TYPE (parm
) = build_pointer_type (TREE_TYPE (parm
));
7390 DECL_ARG_TYPE_AS_WRITTEN (parm
) = TREE_TYPE (parm
);
7391 DECL_ARG_TYPE (parm
)
7392 = lang_hooks
.types
.type_promotes_to (TREE_TYPE (parm
));
7394 /* Record constancy and volatility. */
7395 c_apply_type_quals_to_decl
7396 ((TYPE_READONLY (TREE_TYPE (parm
)) ? TYPE_QUAL_CONST
: 0)
7397 | (TYPE_RESTRICT (TREE_TYPE (parm
)) ? TYPE_QUAL_RESTRICT
: 0)
7398 | (TYPE_VOLATILE (TREE_TYPE (parm
)) ? TYPE_QUAL_VOLATILE
: 0), parm
);
7400 objc_parmlist
= chainon (objc_parmlist
, parm
);
7403 /* Retrieve the formal parameter list constructed via preceding calls to
7404 objc_push_parm(). */
7408 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED
)
7410 static struct c_arg_info
*
7411 objc_get_parm_info (int have_ellipsis
)
7415 tree parm_info
= objc_parmlist
;
7416 objc_parmlist
= NULL_TREE
;
7420 tree parm_info
= objc_parmlist
;
7421 struct c_arg_info
*arg_info
;
7422 /* The C front-end requires an elaborate song and dance at
7425 declare_parm_level ();
7428 tree next
= TREE_CHAIN (parm_info
);
7430 TREE_CHAIN (parm_info
) = NULL_TREE
;
7431 parm_info
= pushdecl (parm_info
);
7432 finish_decl (parm_info
, NULL_TREE
, NULL_TREE
);
7435 arg_info
= get_parm_info (have_ellipsis
);
7437 objc_parmlist
= NULL_TREE
;
7442 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
7443 method definitions. In the case of instance methods, we can be more
7444 specific as to the type of 'self'. */
7447 synth_self_and_ucmd_args (void)
7451 if (objc_method_context
7452 && TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
)
7453 self_type
= objc_instance_type
;
7455 /* Really a `struct objc_class *'. However, we allow people to
7456 assign to self, which changes its type midstream. */
7457 self_type
= objc_object_type
;
7460 objc_push_parm (build_decl (PARM_DECL
, self_id
, self_type
));
7463 objc_push_parm (build_decl (PARM_DECL
, ucmd_id
, objc_selector_type
));
7466 /* Transform an Objective-C method definition into a static C function
7467 definition, synthesizing the first two arguments, "self" and "_cmd",
7471 start_method_def (tree method
)
7477 struct c_arg_info
*parm_info
;
7479 int have_ellipsis
= 0;
7481 /* Required to implement _msgSuper. */
7482 objc_method_context
= method
;
7483 UOBJC_SUPER_decl
= NULL_TREE
;
7485 /* Generate prototype declarations for arguments..."new-style". */
7486 synth_self_and_ucmd_args ();
7488 /* Generate argument declarations if a keyword_decl. */
7489 parmlist
= METHOD_SEL_ARGS (method
);
7492 tree type
= TREE_VALUE (TREE_TYPE (parmlist
)), parm
;
7494 parm
= build_decl (PARM_DECL
, KEYWORD_ARG_NAME (parmlist
), type
);
7495 objc_push_parm (parm
);
7496 parmlist
= TREE_CHAIN (parmlist
);
7499 if (METHOD_ADD_ARGS (method
))
7503 for (akey
= TREE_CHAIN (METHOD_ADD_ARGS (method
));
7504 akey
; akey
= TREE_CHAIN (akey
))
7506 objc_push_parm (TREE_VALUE (akey
));
7509 if (TREE_OVERFLOW (METHOD_ADD_ARGS (method
)))
7513 parm_info
= objc_get_parm_info (have_ellipsis
);
7515 really_start_method (objc_method_context
, parm_info
);
7519 warn_with_method (const char *message
, int mtype
, tree method
)
7521 /* Add a readable method name to the warning. */
7522 warning ("%J%s %<%c%s%>", method
,
7523 message
, mtype
, gen_method_decl (method
));
7526 /* Return 1 if TYPE1 is equivalent to TYPE2
7527 for purposes of method overloading. */
7530 objc_types_are_equivalent (tree type1
, tree type2
)
7535 /* Strip away indirections. */
7536 while ((TREE_CODE (type1
) == ARRAY_TYPE
|| TREE_CODE (type1
) == POINTER_TYPE
)
7537 && (TREE_CODE (type1
) == TREE_CODE (type2
)))
7538 type1
= TREE_TYPE (type1
), type2
= TREE_TYPE (type2
);
7539 if (TYPE_MAIN_VARIANT (type1
) != TYPE_MAIN_VARIANT (type2
))
7542 type1
= (TYPE_HAS_OBJC_INFO (type1
)
7543 ? TYPE_OBJC_PROTOCOL_LIST (type1
)
7545 type2
= (TYPE_HAS_OBJC_INFO (type2
)
7546 ? TYPE_OBJC_PROTOCOL_LIST (type2
)
7549 if (list_length (type1
) == list_length (type2
))
7551 for (; type2
; type2
= TREE_CHAIN (type2
))
7552 if (!lookup_protocol_in_reflist (type1
, TREE_VALUE (type2
)))
7559 /* Return 1 if PROTO1 is equivalent to PROTO2
7560 for purposes of method overloading. */
7563 comp_proto_with_proto (tree proto1
, tree proto2
)
7567 /* The following test is needed in case there are hashing
7569 if (METHOD_SEL_NAME (proto1
) != METHOD_SEL_NAME (proto2
))
7572 /* Compare return types. */
7573 type1
= TREE_VALUE (TREE_TYPE (proto1
));
7574 type2
= TREE_VALUE (TREE_TYPE (proto2
));
7576 if (!objc_types_are_equivalent (type1
, type2
))
7579 /* Compare argument types. */
7580 for (type1
= get_arg_type_list (proto1
, METHOD_REF
, 0),
7581 type2
= get_arg_type_list (proto2
, METHOD_REF
, 0);
7583 type1
= TREE_CHAIN (type1
), type2
= TREE_CHAIN (type2
))
7585 if (!objc_types_are_equivalent (TREE_VALUE (type1
), TREE_VALUE (type2
)))
7589 return (!type1
&& !type2
);
7592 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
7593 this occurs. ObjC method dispatches are _not_ like C++ virtual
7594 member function dispatches, and we account for the difference here. */
7597 objc_fold_obj_type_ref (tree ref
, tree known_type
)
7599 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED
,
7600 tree known_type ATTRIBUTE_UNUSED
)
7604 tree v
= BINFO_VIRTUALS (TYPE_BINFO (known_type
));
7606 /* If the receiver does not have virtual member functions, there
7607 is nothing we can (or need to) do here. */
7611 /* Let C++ handle C++ virtual functions. */
7612 return cp_fold_obj_type_ref (ref
, known_type
);
7614 /* For plain ObjC, we currently do not need to do anything. */
7620 objc_start_function (tree name
, tree type
, tree attrs
,
7624 struct c_arg_info
*params
7628 tree fndecl
= build_decl (FUNCTION_DECL
, name
, type
);
7631 DECL_ARGUMENTS (fndecl
) = params
;
7632 DECL_INITIAL (fndecl
) = error_mark_node
;
7633 DECL_EXTERNAL (fndecl
) = 0;
7634 TREE_STATIC (fndecl
) = 1;
7635 retrofit_lang_decl (fndecl
);
7636 cplus_decl_attributes (&fndecl
, attrs
, 0);
7637 start_preparsed_function (fndecl
, attrs
, /*flags=*/SF_DEFAULT
);
7639 decl_attributes (&fndecl
, attrs
, 0);
7640 announce_function (fndecl
);
7641 DECL_INITIAL (fndecl
) = error_mark_node
;
7642 DECL_EXTERNAL (fndecl
) = 0;
7643 TREE_STATIC (fndecl
) = 1;
7644 current_function_decl
= pushdecl (fndecl
);
7646 declare_parm_level ();
7647 DECL_RESULT (current_function_decl
)
7648 = build_decl (RESULT_DECL
, NULL_TREE
,
7649 TREE_TYPE (TREE_TYPE (current_function_decl
)));
7650 DECL_ARTIFICIAL (DECL_RESULT (current_function_decl
)) = 1;
7651 DECL_IGNORED_P (DECL_RESULT (current_function_decl
)) = 1;
7652 start_fname_decls ();
7653 store_parm_decls_from (params
);
7656 TREE_USED (current_function_decl
) = 1;
7659 /* - Generate an identifier for the function. the format is "_n_cls",
7660 where 1 <= n <= nMethods, and cls is the name the implementation we
7662 - Install the return type from the method declaration.
7663 - If we have a prototype, check for type consistency. */
7666 really_start_method (tree method
,
7670 struct c_arg_info
*parmlist
7674 tree ret_type
, meth_type
;
7676 const char *sel_name
, *class_name
, *cat_name
;
7679 /* Synth the storage class & assemble the return type. */
7680 ret_type
= TREE_VALUE (TREE_TYPE (method
));
7682 sel_name
= IDENTIFIER_POINTER (METHOD_SEL_NAME (method
));
7683 class_name
= IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
7684 cat_name
= ((TREE_CODE (objc_implementation_context
)
7685 == CLASS_IMPLEMENTATION_TYPE
)
7687 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
7690 /* Make sure this is big enough for any plausible method label. */
7691 buf
= (char *) alloca (50 + strlen (sel_name
) + strlen (class_name
)
7692 + (cat_name
? strlen (cat_name
) : 0));
7694 OBJC_GEN_METHOD_LABEL (buf
, TREE_CODE (method
) == INSTANCE_METHOD_DECL
,
7695 class_name
, cat_name
, sel_name
, method_slot
);
7697 method_id
= get_identifier (buf
);
7700 /* Objective-C methods cannot be overloaded, so we don't need
7701 the type encoding appended. It looks bad anyway... */
7702 push_lang_context (lang_name_c
);
7706 = build_function_type (ret_type
,
7707 get_arg_type_list (method
, METHOD_DEF
, 0));
7708 objc_start_function (method_id
, meth_type
, NULL_TREE
, parmlist
);
7710 /* Set self_decl from the first argument. */
7711 self_decl
= DECL_ARGUMENTS (current_function_decl
);
7713 /* Suppress unused warnings. */
7714 TREE_USED (self_decl
) = 1;
7715 TREE_USED (TREE_CHAIN (self_decl
)) = 1;
7717 pop_lang_context ();
7720 METHOD_DEFINITION (method
) = current_function_decl
;
7722 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7724 if (implementation_template
!= objc_implementation_context
)
7727 = lookup_method_static (implementation_template
,
7728 METHOD_SEL_NAME (method
),
7729 TREE_CODE (method
) == CLASS_METHOD_DECL
);
7733 if (!comp_proto_with_proto (method
, proto
))
7735 char type
= (TREE_CODE (method
) == INSTANCE_METHOD_DECL
? '-' : '+');
7737 warn_with_method ("conflicting types for", type
, method
);
7738 warn_with_method ("previous declaration of", type
, proto
);
7743 /* We have a method @implementation even though we did not
7744 see a corresponding @interface declaration (which is allowed
7745 by Objective-C rules). Go ahead and place the method in
7746 the @interface anyway, so that message dispatch lookups
7748 tree interface
= implementation_template
;
7750 if (TREE_CODE (objc_implementation_context
)
7751 == CATEGORY_IMPLEMENTATION_TYPE
)
7752 interface
= lookup_category
7754 CLASS_SUPER_NAME (objc_implementation_context
));
7757 objc_add_method (interface
, copy_node (method
),
7758 TREE_CODE (method
) == CLASS_METHOD_DECL
);
7763 static void *UOBJC_SUPER_scope
= 0;
7765 /* _n_Method (id self, SEL sel, ...)
7767 struct objc_super _S;
7768 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7772 get_super_receiver (void)
7774 if (objc_method_context
)
7776 tree super_expr
, super_expr_list
;
7778 if (!UOBJC_SUPER_decl
)
7780 UOBJC_SUPER_decl
= build_decl (VAR_DECL
, get_identifier (TAG_SUPER
),
7781 objc_super_template
);
7782 /* This prevents `unused variable' warnings when compiling with -Wall. */
7783 TREE_USED (UOBJC_SUPER_decl
) = 1;
7784 lang_hooks
.decls
.pushdecl (UOBJC_SUPER_decl
);
7785 finish_decl (UOBJC_SUPER_decl
, NULL_TREE
, NULL_TREE
);
7786 UOBJC_SUPER_scope
= objc_get_current_scope ();
7789 /* Set receiver to self. */
7790 super_expr
= build_component_ref (UOBJC_SUPER_decl
, self_id
);
7791 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, self_decl
);
7792 super_expr_list
= super_expr
;
7794 /* Set class to begin searching. */
7795 super_expr
= build_component_ref (UOBJC_SUPER_decl
,
7796 get_identifier ("super_class"));
7798 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
7800 /* [_cls, __cls]Super are "pre-built" in
7801 synth_forward_declarations. */
7803 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
,
7804 ((TREE_CODE (objc_method_context
)
7805 == INSTANCE_METHOD_DECL
)
7807 : uucls_super_ref
));
7811 /* We have a category. */
7813 tree super_name
= CLASS_SUPER_NAME (implementation_template
);
7816 /* Barf if super used in a category of Object. */
7819 error ("no super class declared in interface for %qs",
7820 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
7821 return error_mark_node
;
7824 if (flag_next_runtime
&& !flag_zero_link
)
7826 super_class
= objc_get_class_reference (super_name
);
7827 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
7828 /* If we are in a class method, we must retrieve the
7829 _metaclass_ for the current class, pointed at by
7830 the class's "isa" pointer. The following assumes that
7831 "isa" is the first ivar in a class (which it must be). */
7833 = build_indirect_ref
7834 (build_c_cast (build_pointer_type (objc_class_type
),
7835 super_class
), "unary *");
7839 add_class_reference (super_name
);
7840 super_class
= (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
7841 ? objc_get_class_decl
: objc_get_meta_class_decl
);
7842 assemble_external (super_class
);
7844 = build_function_call
7848 my_build_string (IDENTIFIER_LENGTH (super_name
) + 1,
7849 IDENTIFIER_POINTER (super_name
))));
7853 = build_modify_expr (super_expr
, NOP_EXPR
,
7854 build_c_cast (TREE_TYPE (super_expr
),
7858 super_expr_list
= build_compound_expr (super_expr_list
, super_expr
);
7860 super_expr
= build_unary_op (ADDR_EXPR
, UOBJC_SUPER_decl
, 0);
7861 super_expr_list
= build_compound_expr (super_expr_list
, super_expr
);
7863 return super_expr_list
;
7867 error ("[super ...] must appear in a method context");
7868 return error_mark_node
;
7872 /* When exiting a scope, sever links to a 'super' declaration (if any)
7873 therein contained. */
7876 objc_clear_super_receiver (void)
7878 if (objc_method_context
7879 && UOBJC_SUPER_scope
== objc_get_current_scope ()) {
7880 UOBJC_SUPER_decl
= 0;
7881 UOBJC_SUPER_scope
= 0;
7886 objc_finish_method_definition (tree fndecl
)
7888 /* We cannot validly inline ObjC methods, at least not without a language
7889 extension to declare that a method need not be dynamically
7890 dispatched, so suppress all thoughts of doing so. */
7891 DECL_INLINE (fndecl
) = 0;
7892 DECL_UNINLINABLE (fndecl
) = 1;
7895 /* The C++ front-end will have called finish_function() for us. */
7899 METHOD_ENCODING (objc_method_context
)
7900 = encode_method_prototype (objc_method_context
);
7902 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7903 since the optimizer may find "may be used before set" errors. */
7904 objc_method_context
= NULL_TREE
;
7909 lang_report_error_function (tree decl
)
7911 if (objc_method_context
)
7913 fprintf (stderr
, "In method %qs\n",
7914 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context
)));
7923 /* Given a tree DECL node, produce a printable description of it in the given
7924 buffer, overwriting the buffer. */
7927 gen_declaration (tree decl
)
7933 gen_type_name_0 (TREE_TYPE (decl
));
7935 if (DECL_NAME (decl
))
7937 if (!POINTER_TYPE_P (TREE_TYPE (decl
)))
7938 strcat (errbuf
, " ");
7940 strcat (errbuf
, IDENTIFIER_POINTER (DECL_NAME (decl
)));
7943 if (DECL_INITIAL (decl
)
7944 && TREE_CODE (DECL_INITIAL (decl
)) == INTEGER_CST
)
7945 sprintf (errbuf
+ strlen (errbuf
), ": " HOST_WIDE_INT_PRINT_DEC
,
7946 TREE_INT_CST_LOW (DECL_INITIAL (decl
)));
7952 /* Given a tree TYPE node, produce a printable description of it in the given
7953 buffer, overwriting the buffer. */
7956 gen_type_name_0 (tree type
)
7958 tree orig
= type
, proto
;
7960 if (TYPE_P (type
) && TYPE_NAME (type
))
7961 type
= TYPE_NAME (type
);
7962 else if (POINTER_TYPE_P (type
) || TREE_CODE (type
) == ARRAY_TYPE
)
7964 tree inner
= TREE_TYPE (type
);
7966 while (TREE_CODE (inner
) == ARRAY_TYPE
)
7967 inner
= TREE_TYPE (inner
);
7969 gen_type_name_0 (inner
);
7971 if (!POINTER_TYPE_P (inner
))
7972 strcat (errbuf
, " ");
7974 if (POINTER_TYPE_P (type
))
7975 strcat (errbuf
, "*");
7977 while (type
!= inner
)
7979 strcat (errbuf
, "[");
7981 if (TYPE_DOMAIN (type
))
7985 sprintf (sz
, HOST_WIDE_INT_PRINT_DEC
,
7987 (TYPE_MAX_VALUE (TYPE_DOMAIN (type
))) + 1));
7988 strcat (errbuf
, sz
);
7991 strcat (errbuf
, "]");
7992 type
= TREE_TYPE (type
);
7998 if (TREE_CODE (type
) == TYPE_DECL
&& DECL_NAME (type
))
7999 type
= DECL_NAME (type
);
8001 strcat (errbuf
, IDENTIFIER_POINTER (type
));
8003 /* For 'id' and 'Class', adopted protocols are stored in the pointee. */
8004 if (objc_is_id (orig
))
8005 orig
= TREE_TYPE (orig
);
8007 proto
= TYPE_HAS_OBJC_INFO (orig
) ? TYPE_OBJC_PROTOCOL_LIST (orig
) : NULL_TREE
;
8011 strcat (errbuf
, " <");
8015 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto
))));
8016 proto
= TREE_CHAIN (proto
);
8017 strcat (errbuf
, proto
? ", " : ">");
8026 gen_type_name (tree type
)
8030 return gen_type_name_0 (type
);
8033 /* Given a method tree, put a printable description into the given
8034 buffer (overwriting) and return a pointer to the buffer. */
8037 gen_method_decl (tree method
)
8041 strcpy (errbuf
, "("); /* NB: Do _not_ call strcat() here. */
8042 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method
)));
8043 strcat (errbuf
, ")");
8044 chain
= METHOD_SEL_ARGS (method
);
8048 /* We have a chain of keyword_decls. */
8051 if (KEYWORD_KEY_NAME (chain
))
8052 strcat (errbuf
, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain
)));
8054 strcat (errbuf
, ":(");
8055 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain
)));
8056 strcat (errbuf
, ")");
8058 strcat (errbuf
, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain
)));
8059 if ((chain
= TREE_CHAIN (chain
)))
8060 strcat (errbuf
, " ");
8064 if (METHOD_ADD_ARGS (method
))
8066 chain
= TREE_CHAIN (METHOD_ADD_ARGS (method
));
8068 /* Know we have a chain of parm_decls. */
8071 strcat (errbuf
, ", ");
8072 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain
)));
8073 chain
= TREE_CHAIN (chain
);
8076 if (TREE_OVERFLOW (METHOD_ADD_ARGS (method
)))
8077 strcat (errbuf
, ", ...");
8082 /* We have a unary selector. */
8083 strcat (errbuf
, IDENTIFIER_POINTER (METHOD_SEL_NAME (method
)));
8091 /* Dump an @interface declaration of the supplied class CHAIN to the
8092 supplied file FP. Used to implement the -gen-decls option (which
8093 prints out an @interface declaration of all classes compiled in
8094 this run); potentially useful for debugging the compiler too. */
8096 dump_interface (FILE *fp
, tree chain
)
8098 /* FIXME: A heap overflow here whenever a method (or ivar)
8099 declaration is so long that it doesn't fit in the buffer. The
8100 code and all the related functions should be rewritten to avoid
8101 using fixed size buffers. */
8102 const char *my_name
= IDENTIFIER_POINTER (CLASS_NAME (chain
));
8103 tree ivar_decls
= CLASS_RAW_IVARS (chain
);
8104 tree nst_methods
= CLASS_NST_METHODS (chain
);
8105 tree cls_methods
= CLASS_CLS_METHODS (chain
);
8107 fprintf (fp
, "\n@interface %s", my_name
);
8109 /* CLASS_SUPER_NAME is used to store the superclass name for
8110 classes, and the category name for categories. */
8111 if (CLASS_SUPER_NAME (chain
))
8113 const char *name
= IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain
));
8115 if (TREE_CODE (chain
) == CATEGORY_IMPLEMENTATION_TYPE
8116 || TREE_CODE (chain
) == CATEGORY_INTERFACE_TYPE
)
8118 fprintf (fp
, " (%s)\n", name
);
8122 fprintf (fp
, " : %s\n", name
);
8128 /* FIXME - the following doesn't seem to work at the moment. */
8131 fprintf (fp
, "{\n");
8134 fprintf (fp
, "\t%s;\n", gen_declaration (ivar_decls
));
8135 ivar_decls
= TREE_CHAIN (ivar_decls
);
8138 fprintf (fp
, "}\n");
8143 fprintf (fp
, "- %s;\n", gen_method_decl (nst_methods
));
8144 nst_methods
= TREE_CHAIN (nst_methods
);
8149 fprintf (fp
, "+ %s;\n", gen_method_decl (cls_methods
));
8150 cls_methods
= TREE_CHAIN (cls_methods
);
8153 fprintf (fp
, "@end\n");
8156 /* Demangle function for Objective-C */
8158 objc_demangle (const char *mangled
)
8160 char *demangled
, *cp
;
8162 if (mangled
[0] == '_' &&
8163 (mangled
[1] == 'i' || mangled
[1] == 'c') &&
8166 cp
= demangled
= xmalloc(strlen(mangled
) + 2);
8167 if (mangled
[1] == 'i')
8168 *cp
++ = '-'; /* for instance method */
8170 *cp
++ = '+'; /* for class method */
8171 *cp
++ = '['; /* opening left brace */
8172 strcpy(cp
, mangled
+3); /* tack on the rest of the mangled name */
8173 while (*cp
&& *cp
== '_')
8174 cp
++; /* skip any initial underbars in class name */
8175 cp
= strchr(cp
, '_'); /* find first non-initial underbar */
8178 free(demangled
); /* not mangled name */
8181 if (cp
[1] == '_') /* easy case: no category name */
8183 *cp
++ = ' '; /* replace two '_' with one ' ' */
8184 strcpy(cp
, mangled
+ (cp
- demangled
) + 2);
8188 *cp
++ = '('; /* less easy case: category name */
8189 cp
= strchr(cp
, '_');
8192 free(demangled
); /* not mangled name */
8196 *cp
++ = ' '; /* overwriting 1st char of method name... */
8197 strcpy(cp
, mangled
+ (cp
- demangled
)); /* get it back */
8199 while (*cp
&& *cp
== '_')
8200 cp
++; /* skip any initial underbars in method name */
8203 *cp
= ':'; /* replace remaining '_' with ':' */
8204 *cp
++ = ']'; /* closing right brace */
8205 *cp
++ = 0; /* string terminator */
8209 return mangled
; /* not an objc mangled name */
8213 objc_printable_name (tree decl
, int kind ATTRIBUTE_UNUSED
)
8215 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl
)));
8221 gcc_obstack_init (&util_obstack
);
8222 util_firstobj
= (char *) obstack_finish (&util_obstack
);
8224 errbuf
= (char *) xmalloc (1024 * 10);
8226 synth_module_prologue ();
8232 struct imp_entry
*impent
;
8234 /* The internally generated initializers appear to have missing braces.
8235 Don't warn about this. */
8236 int save_warn_missing_braces
= warn_missing_braces
;
8237 warn_missing_braces
= 0;
8239 /* A missing @end may not be detected by the parser. */
8240 if (objc_implementation_context
)
8242 warning ("%<@end%> missing in implementation context");
8243 finish_class (objc_implementation_context
);
8244 objc_ivar_chain
= NULL_TREE
;
8245 objc_implementation_context
= NULL_TREE
;
8248 /* Process the static instances here because initialization of objc_symtab
8250 if (objc_static_instances
)
8251 generate_static_references ();
8253 if (imp_list
|| class_names_chain
8254 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8255 generate_objc_symtab_decl ();
8257 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8259 objc_implementation_context
= impent
->imp_context
;
8260 implementation_template
= impent
->imp_template
;
8262 UOBJC_CLASS_decl
= impent
->class_decl
;
8263 UOBJC_METACLASS_decl
= impent
->meta_decl
;
8265 /* Dump the @interface of each class as we compile it, if the
8266 -gen-decls option is in use. TODO: Dump the classes in the
8267 order they were found, rather than in reverse order as we
8269 if (flag_gen_declaration
)
8271 dump_interface (gen_declaration_file
, objc_implementation_context
);
8274 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
8276 /* all of the following reference the string pool... */
8277 generate_ivar_lists ();
8278 generate_dispatch_tables ();
8279 generate_shared_structures ();
8283 generate_dispatch_tables ();
8284 generate_category (objc_implementation_context
);
8288 /* If we are using an array of selectors, we must always
8289 finish up the array decl even if no selectors were used. */
8290 if (! flag_next_runtime
|| sel_ref_chain
)
8291 build_selector_translation_table ();
8294 generate_protocols ();
8296 if (flag_replace_objc_classes
&& imp_list
)
8297 generate_objc_image_info ();
8299 /* Arrange for ObjC data structures to be initialized at run time. */
8300 if (objc_implementation_context
|| class_names_chain
|| objc_static_instances
8301 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8303 build_module_descriptor ();
8305 if (!flag_next_runtime
)
8306 build_module_initializer_routine ();
8309 /* Dump the class references. This forces the appropriate classes
8310 to be linked into the executable image, preserving unix archive
8311 semantics. This can be removed when we move to a more dynamically
8312 linked environment. */
8314 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
8316 handle_class_ref (chain
);
8317 if (TREE_PURPOSE (chain
))
8318 generate_classref_translation_entry (chain
);
8321 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8322 handle_impent (impent
);
8324 /* Dump the string table last. */
8326 generate_strings ();
8333 /* Run through the selector hash tables and print a warning for any
8334 selector which has multiple methods. */
8336 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8338 for (hsh
= cls_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8339 check_duplicates (hsh
, 0, 1);
8340 for (hsh
= nst_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8341 check_duplicates (hsh
, 0, 1);
8345 warn_missing_braces
= save_warn_missing_braces
;
8348 /* Subroutines of finish_objc. */
8351 generate_classref_translation_entry (tree chain
)
8353 tree expr
, decl
, type
;
8355 decl
= TREE_PURPOSE (chain
);
8356 type
= TREE_TYPE (decl
);
8358 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
8359 expr
= convert (type
, expr
); /* cast! */
8361 /* The decl that is the one that we
8362 forward declared in build_class_reference. */
8363 finish_var_decl (decl
, expr
);
8368 handle_class_ref (tree chain
)
8370 const char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
8371 char *string
= (char *) alloca (strlen (name
) + 30);
8375 sprintf (string
, "%sobjc_class_name_%s",
8376 (flag_next_runtime
? "." : "__"), name
);
8378 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8379 if (flag_next_runtime
)
8381 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file
, string
);
8386 /* Make a decl for this name, so we can use its address in a tree. */
8387 decl
= build_decl (VAR_DECL
, get_identifier (string
), char_type_node
);
8388 DECL_EXTERNAL (decl
) = 1;
8389 TREE_PUBLIC (decl
) = 1;
8392 rest_of_decl_compilation (decl
, 0, 0);
8394 /* Make a decl for the address. */
8395 sprintf (string
, "%sobjc_class_ref_%s",
8396 (flag_next_runtime
? "." : "__"), name
);
8397 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
8398 decl
= build_decl (VAR_DECL
, get_identifier (string
), string_type_node
);
8399 DECL_INITIAL (decl
) = exp
;
8400 TREE_STATIC (decl
) = 1;
8401 TREE_USED (decl
) = 1;
8404 rest_of_decl_compilation (decl
, 0, 0);
8408 handle_impent (struct imp_entry
*impent
)
8412 objc_implementation_context
= impent
->imp_context
;
8413 implementation_template
= impent
->imp_template
;
8415 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
8417 const char *const class_name
=
8418 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8420 string
= (char *) alloca (strlen (class_name
) + 30);
8422 sprintf (string
, "%sobjc_class_name_%s",
8423 (flag_next_runtime
? "." : "__"), class_name
);
8425 else if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
8427 const char *const class_name
=
8428 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8429 const char *const class_super_name
=
8430 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
8432 string
= (char *) alloca (strlen (class_name
)
8433 + strlen (class_super_name
) + 30);
8435 /* Do the same for categories. Even though no references to
8436 these symbols are generated automatically by the compiler, it
8437 gives you a handle to pull them into an archive by hand. */
8438 sprintf (string
, "*%sobjc_category_name_%s_%s",
8439 (flag_next_runtime
? "." : "__"), class_name
, class_super_name
);
8444 #ifdef ASM_DECLARE_CLASS_REFERENCE
8445 if (flag_next_runtime
)
8447 ASM_DECLARE_CLASS_REFERENCE (asm_out_file
, string
);
8455 init
= build_int_cst (c_common_type_for_size (BITS_PER_WORD
, 1), 0);
8456 decl
= build_decl (VAR_DECL
, get_identifier (string
), TREE_TYPE (init
));
8457 TREE_PUBLIC (decl
) = 1;
8458 TREE_READONLY (decl
) = 1;
8459 TREE_USED (decl
) = 1;
8460 TREE_CONSTANT (decl
) = 1;
8461 DECL_CONTEXT (decl
) = 0;
8462 DECL_ARTIFICIAL (decl
) = 1;
8463 DECL_INITIAL (decl
) = init
;
8464 assemble_variable (decl
, 1, 0, 0);
8468 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
8469 later requires that ObjC translation units participating in F&C be
8470 specially marked. The following routine accomplishes this. */
8472 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
8475 generate_objc_image_info (void)
8477 tree decl
, initlist
;
8479 decl
= start_var_decl (build_array_type
8481 build_index_type (build_int_cst (NULL_TREE
, 2 - 1))),
8482 "_OBJC_IMAGE_INFO");
8484 initlist
= build_tree_list (NULL_TREE
, build_int_cst (NULL_TREE
, 0));
8485 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 1), initlist
);
8486 initlist
= objc_build_constructor (TREE_TYPE (decl
), nreverse (initlist
));
8488 finish_var_decl (decl
, initlist
);
8491 /* Look up ID as an instance variable. OTHER contains the result of
8492 the C or C++ lookup, which we may want to use instead. */
8495 objc_lookup_ivar (tree other
, tree id
)
8499 /* If we are not inside of an ObjC method, ivar lookup makes no sense. */
8500 if (!objc_method_context
)
8503 if (!strcmp (IDENTIFIER_POINTER (id
), "super"))
8504 /* We have a message to super. */
8505 return get_super_receiver ();
8507 /* In a class method, look up an instance variable only as a last
8509 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
8510 && other
&& other
!= error_mark_node
)
8513 /* Look up the ivar, but do not use it if it is not accessible. */
8514 ivar
= is_ivar (objc_ivar_chain
, id
);
8516 if (!ivar
|| is_private (ivar
))
8519 /* In an instance method, a local variable (or parameter) may hide the
8520 instance variable. */
8521 if (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
8522 && other
&& other
!= error_mark_node
&& !DECL_FILE_SCOPE_P (other
))
8524 warning ("local declaration of %qs hides instance variable",
8525 IDENTIFIER_POINTER (id
));
8530 /* At this point, we are either in an instance method with no obscuring
8531 local definitions, or in a class method with no alternate definitions
8533 return build_ivar_reference (id
);
8536 #include "gt-objc-objc-act.h"