1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000,
3 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* Purpose: This module implements the Objective-C 4.0 language.
25 compatibility issues (with the Stepstone translator):
27 - does not recognize the following 3.3 constructs.
28 @requires, @classes, @messages, = (...)
29 - methods with variable arguments must conform to ANSI standard.
30 - tagged structure definitions that appear in BOTH the interface
31 and implementation are not allowed.
32 - public/private: all instance variables are public within the
33 context of the implementation...I consider this to be a bug in
35 - statically allocated objects are not supported. the user will
36 receive an error if this service is requested.
38 code generation `options':
44 #include "coretypes.h"
59 #include "langhooks.h"
70 #include "diagnostic.h"
72 #include "tree-iterator.h"
76 #define OBJC_VOID_AT_END void_list_node
78 /* When building Objective-C++, we are not linking against the C front-end
79 and so need to replicate the C tree-construction functions in some way. */
81 #define OBJCP_REMAP_FUNCTIONS
82 #include "objcp-decl.h"
85 /* This is the default way of generating a method name. */
86 /* I am not sure it is really correct.
87 Perhaps there's a danger that it will make name conflicts
88 if method names contain underscores. -- rms. */
89 #ifndef OBJC_GEN_METHOD_LABEL
90 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
93 sprintf ((BUF), "_%s_%s_%s_%s", \
94 ((IS_INST) ? "i" : "c"), \
96 ((CAT_NAME)? (CAT_NAME) : ""), \
98 for (temp = (BUF); *temp; temp++) \
99 if (*temp == ':') *temp = '_'; \
103 /* These need specifying. */
104 #ifndef OBJC_FORWARDING_STACK_OFFSET
105 #define OBJC_FORWARDING_STACK_OFFSET 0
108 #ifndef OBJC_FORWARDING_MIN_OFFSET
109 #define OBJC_FORWARDING_MIN_OFFSET 0
112 /* Set up for use of obstacks. */
116 /* This obstack is used to accumulate the encoding of a data type. */
117 static struct obstack util_obstack
;
119 /* This points to the beginning of obstack contents, so we can free
120 the whole contents. */
123 /* The version identifies which language generation and runtime
124 the module (file) was compiled for, and is recorded in the
125 module descriptor. */
127 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
128 #define PROTOCOL_VERSION 2
130 /* (Decide if these can ever be validly changed.) */
131 #define OBJC_ENCODE_INLINE_DEFS 0
132 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
134 /*** Private Interface (procedures) ***/
136 /* Used by compile_file. */
138 static void init_objc (void);
139 static void finish_objc (void);
141 /* Code generation. */
143 static void synth_module_prologue (void);
144 static tree
objc_build_constructor (tree
, tree
);
145 static void build_module_descriptor (void);
146 static void build_module_initializer_routine (void);
147 static tree
init_module_descriptor (tree
);
148 static tree
build_objc_method_call (int, tree
, tree
, tree
, tree
);
149 static void generate_strings (void);
150 static tree
get_proto_encoding (tree
);
151 static void build_selector_translation_table (void);
152 static tree
lookup_interface (tree
);
153 static tree
objc_add_static_instance (tree
, tree
);
155 static tree
start_class (enum tree_code
, tree
, tree
, tree
);
156 static tree
continue_class (tree
);
157 static void finish_class (tree
);
158 static void start_method_def (tree
);
160 static void objc_start_function (tree
, tree
, tree
, tree
);
162 static void objc_start_function (tree
, tree
, tree
, struct c_arg_info
*);
164 static tree
start_protocol (enum tree_code
, tree
, tree
);
165 static tree
build_method_decl (enum tree_code
, tree
, tree
, tree
);
166 static tree
objc_add_method (tree
, tree
, int);
167 static tree
add_instance_variable (tree
, int, tree
);
168 static tree
build_ivar_reference (tree
);
169 static tree
is_ivar (tree
, tree
);
170 static int is_private (tree
);
171 static tree
get_super_receiver (void);
173 static void build_objc_exception_stuff (void);
174 static void build_next_objc_exception_stuff (void);
176 static tree
build_ivar_template (void);
177 static tree
build_method_template (void);
178 static tree
build_private_template (tree
);
179 static void build_class_template (void);
180 static void build_selector_template (void);
181 static void build_category_template (void);
182 static tree
lookup_method_in_hash_lists (tree
, int);
183 static void build_super_template (void);
184 static tree
build_category_initializer (tree
, tree
, tree
, tree
, tree
, tree
);
185 static tree
build_protocol_initializer (tree
, tree
, tree
, tree
, tree
);
186 static void synth_forward_declarations (void);
187 static int ivar_list_length (tree
);
188 static tree
get_class_ivars (tree
);
189 static void generate_ivar_lists (void);
190 static void generate_dispatch_tables (void);
191 static void generate_shared_structures (void);
192 static tree
generate_protocol_list (tree
);
193 static void build_protocol_reference (tree
);
195 static tree
build_keyword_selector (tree
);
196 static const char *synth_id_with_class_suffix (const char *, tree
);
198 static void generate_static_references (void);
199 static int check_methods_accessible (tree
, tree
, int);
200 static void encode_aggregate_within (tree
, int, int, int, int);
201 static const char *objc_demangle (const char *);
203 /* Hash tables to manage the global pool of method prototypes. */
205 hash
*nst_method_hash_list
= 0;
206 hash
*cls_method_hash_list
= 0;
208 static size_t hash_func (tree
);
209 static void hash_init (void);
210 static void hash_enter (hash
*, tree
);
211 static hash
hash_lookup (hash
*, tree
);
212 static void hash_add_attr (hash
, tree
);
213 static tree
lookup_method (tree
, tree
);
214 static tree
lookup_method_static (tree
, tree
, int);
215 static void add_method_to_hash_list (hash
*, tree
);
216 static tree
add_class (tree
);
217 static void add_category (tree
, tree
);
218 static inline tree
lookup_category (tree
, tree
);
222 class_names
, /* class, category, protocol, module names */
223 meth_var_names
, /* method and variable names */
224 meth_var_types
/* method and variable type descriptors */
227 static tree
add_objc_string (tree
, enum string_section
);
228 static tree
get_objc_string_decl (tree
, enum string_section
);
229 static tree
build_objc_string_decl (enum string_section
);
230 static tree
build_selector_reference_decl (void);
231 static void build_selector_table_decl (void);
233 /* Protocol additions. */
235 static tree
add_protocol (tree
);
236 static tree
lookup_protocol (tree
);
237 static void check_protocol_recursively (tree
, tree
);
238 static tree
lookup_and_install_protocols (tree
);
242 static void encode_type_qualifiers (tree
);
243 static void encode_pointer (tree
, int, int);
244 static void encode_array (tree
, int, int);
245 static void encode_aggregate (tree
, int, int);
246 static void encode_next_bitfield (int);
247 static void encode_gnu_bitfield (int, tree
, int);
248 static void encode_type (tree
, int, int);
249 static void encode_field_decl (tree
, int, int);
252 static void really_start_method (tree
, tree
);
254 static void really_start_method (tree
, struct c_arg_info
*);
256 static int objc_types_are_equivalent (tree
, tree
);
257 static int comp_proto_with_proto (tree
, tree
);
258 static tree
get_arg_type_list (tree
, int, int);
259 static void objc_push_parm (tree
);
261 static tree
objc_get_parm_info (int);
263 static struct c_arg_info
*objc_get_parm_info (int);
265 static void synth_self_and_ucmd_args (void);
267 /* Utilities for debugging and error diagnostics. */
269 static void warn_with_method (const char *, int, tree
);
270 static void error_with_ivar (const char *, tree
);
271 static char *gen_type_name (tree
);
272 static char *gen_type_name_0 (tree
);
273 static char *gen_method_decl (tree
);
274 static char *gen_declaration (tree
);
275 static void dump_interface (FILE *, tree
);
277 /* Everything else. */
279 static tree
lookup_method_in_protocol_list (tree
, tree
, int);
280 static tree
lookup_protocol_in_reflist (tree
, tree
);
281 static tree
start_var_decl (tree
, const char *);
282 static void finish_var_decl (tree
, tree
);
283 static tree
create_field_decl (tree
, const char *);
284 static tree
setup_string_decl (void);
285 static int check_string_class_template (void);
286 static tree
my_build_string (int, const char *);
287 static void build_objc_symtab_template (void);
288 static tree
init_def_list (tree
);
289 static tree
init_objc_symtab (tree
);
290 static tree
build_metadata_decl (const char *, tree
);
291 static void forward_declare_categories (void);
292 static void generate_objc_symtab_decl (void);
293 static tree
build_selector (tree
);
294 static tree
build_typed_selector_reference (tree
, tree
);
295 static tree
build_selector_reference (tree
);
296 static tree
build_class_reference_decl (void);
297 static void add_class_reference (tree
);
298 static void build_protocol_template (void);
299 static tree
build_descriptor_table_initializer (tree
, tree
);
300 static tree
build_method_prototype_list_template (tree
, int);
301 static tree
build_method_prototype_template (void);
302 static tree
objc_method_parm_type (tree
);
303 static int objc_encoded_type_size (tree
);
304 static tree
encode_method_prototype (tree
);
305 static tree
generate_descriptor_table (tree
, const char *, int, tree
, tree
);
306 static void generate_method_descriptors (tree
);
307 static void generate_protocol_references (tree
);
308 static void generate_protocols (void);
309 static void check_ivars (tree
, tree
);
310 static tree
build_ivar_list_template (tree
, int);
311 static tree
build_method_list_template (tree
, int);
312 static tree
build_ivar_list_initializer (tree
, tree
);
313 static tree
generate_ivars_list (tree
, const char *, int, tree
);
314 static tree
build_dispatch_table_initializer (tree
, tree
);
315 static tree
generate_dispatch_table (tree
, const char *, int, tree
);
316 static tree
build_shared_structure_initializer (tree
, tree
, tree
, tree
,
317 tree
, int, tree
, tree
, tree
);
318 static void generate_category (tree
);
319 static tree
adjust_type_for_id_default (tree
);
320 static tree
check_duplicates (hash
, int, int);
321 static tree
receiver_is_class_object (tree
, int, int);
322 static int check_methods (tree
, tree
, int);
323 static int conforms_to_protocol (tree
, tree
);
324 static void check_protocol (tree
, const char *, const char *);
325 static void check_protocols (tree
, const char *, const char *);
326 static void generate_classref_translation_entry (tree
);
327 static void handle_class_ref (tree
);
328 static void generate_struct_by_value_array (void)
330 static void mark_referenced_methods (void);
331 static void generate_objc_image_info (void);
333 /*** Private Interface (data) ***/
335 /* Reserved tag definitions. */
337 #define OBJECT_TYPEDEF_NAME "id"
338 #define CLASS_TYPEDEF_NAME "Class"
340 #define TAG_OBJECT "objc_object"
341 #define TAG_CLASS "objc_class"
342 #define TAG_SUPER "objc_super"
343 #define TAG_SELECTOR "objc_selector"
345 #define UTAG_CLASS "_objc_class"
346 #define UTAG_IVAR "_objc_ivar"
347 #define UTAG_IVAR_LIST "_objc_ivar_list"
348 #define UTAG_METHOD "_objc_method"
349 #define UTAG_METHOD_LIST "_objc_method_list"
350 #define UTAG_CATEGORY "_objc_category"
351 #define UTAG_MODULE "_objc_module"
352 #define UTAG_SYMTAB "_objc_symtab"
353 #define UTAG_SUPER "_objc_super"
354 #define UTAG_SELECTOR "_objc_selector"
356 #define UTAG_PROTOCOL "_objc_protocol"
357 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
358 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
360 /* Note that the string object global name is only needed for the
362 #define STRING_OBJECT_GLOBAL_FORMAT "_%sClassReference"
364 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
366 static const char *TAG_GETCLASS
;
367 static const char *TAG_GETMETACLASS
;
368 static const char *TAG_MSGSEND
;
369 static const char *TAG_MSGSENDSUPER
;
370 /* The NeXT Objective-C messenger may have two extra entry points, for use
371 when returning a structure. */
372 static const char *TAG_MSGSEND_STRET
;
373 static const char *TAG_MSGSENDSUPER_STRET
;
374 static const char *default_constant_string_class_name
;
376 /* Runtime metadata flags. */
377 #define CLS_FACTORY 0x0001L
378 #define CLS_META 0x0002L
380 #define OBJC_MODIFIER_STATIC 0x00000001
381 #define OBJC_MODIFIER_FINAL 0x00000002
382 #define OBJC_MODIFIER_PUBLIC 0x00000004
383 #define OBJC_MODIFIER_PRIVATE 0x00000008
384 #define OBJC_MODIFIER_PROTECTED 0x00000010
385 #define OBJC_MODIFIER_NATIVE 0x00000020
386 #define OBJC_MODIFIER_SYNCHRONIZED 0x00000040
387 #define OBJC_MODIFIER_ABSTRACT 0x00000080
388 #define OBJC_MODIFIER_VOLATILE 0x00000100
389 #define OBJC_MODIFIER_TRANSIENT 0x00000200
390 #define OBJC_MODIFIER_NONE_SPECIFIED 0x80000000
392 /* NeXT-specific tags. */
394 #define TAG_MSGSEND_NONNIL "objc_msgSendNonNil"
395 #define TAG_MSGSEND_NONNIL_STRET "objc_msgSendNonNil_stret"
396 #define TAG_EXCEPTIONEXTRACT "objc_exception_extract"
397 #define TAG_EXCEPTIONTRYENTER "objc_exception_try_enter"
398 #define TAG_EXCEPTIONTRYEXIT "objc_exception_try_exit"
399 #define TAG_EXCEPTIONMATCH "objc_exception_match"
400 #define TAG_EXCEPTIONTHROW "objc_exception_throw"
401 #define TAG_SYNCENTER "objc_sync_enter"
402 #define TAG_SYNCEXIT "objc_sync_exit"
403 #define TAG_SETJMP "_setjmp"
404 #define UTAG_EXCDATA "_objc_exception_data"
406 /* GNU-specific tags. */
408 #define TAG_EXECCLASS "__objc_exec_class"
409 #define TAG_GNUINIT "__objc_gnu_init"
411 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
412 tree objc_global_trees
[OCTI_MAX
];
414 static void handle_impent (struct imp_entry
*);
416 struct imp_entry
*imp_list
= 0;
417 int imp_count
= 0; /* `@implementation' */
418 int cat_count
= 0; /* `@category' */
420 enum tree_code objc_inherit_code
;
421 int objc_public_flag
;
423 /* Use to generate method labels. */
424 static int method_slot
= 0;
428 static char *errbuf
; /* Buffer for error diagnostics */
430 /* Data imported from tree.c. */
432 extern enum debug_info_type write_symbols
;
434 /* Data imported from toplev.c. */
436 extern const char *dump_base_name
;
438 static int flag_typed_selectors
;
440 /* Store all constructed constant strings in a hash table so that
441 they get uniqued properly. */
443 struct string_descriptor
GTY(())
445 /* The literal argument . */
448 /* The resulting constant string. */
452 static GTY((param_is (struct string_descriptor
))) htab_t string_htab
;
454 static hashval_t
string_hash (const void *);
455 static int string_eq (const void *, const void *);
457 FILE *gen_declaration_file
;
459 /* Tells "encode_pointer/encode_aggregate" whether we are generating
460 type descriptors for instance variables (as opposed to methods).
461 Type descriptors for instance variables contain more information
462 than methods (for static typing and embedded structures). */
464 static int generating_instance_variables
= 0;
466 /* Some platforms pass small structures through registers versus
467 through an invisible pointer. Determine at what size structure is
468 the transition point between the two possibilities. */
471 generate_struct_by_value_array (void)
474 tree field_decl
, field_decl_chain
;
476 int aggregate_in_mem
[32];
479 /* Presumably no platform passes 32 byte structures in a register. */
480 for (i
= 1; i
< 32; i
++)
484 /* Create an unnamed struct that has `i' character components */
485 type
= start_struct (RECORD_TYPE
, NULL_TREE
);
487 strcpy (buffer
, "c1");
488 field_decl
= create_field_decl (char_type_node
,
490 field_decl_chain
= field_decl
;
492 for (j
= 1; j
< i
; j
++)
494 sprintf (buffer
, "c%d", j
+ 1);
495 field_decl
= create_field_decl (char_type_node
,
497 chainon (field_decl_chain
, field_decl
);
499 finish_struct (type
, field_decl_chain
, NULL_TREE
);
501 aggregate_in_mem
[i
] = aggregate_value_p (type
, 0);
502 if (!aggregate_in_mem
[i
])
506 /* We found some structures that are returned in registers instead of memory
507 so output the necessary data. */
510 for (i
= 31; i
>= 0; i
--)
511 if (!aggregate_in_mem
[i
])
513 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i
);
515 /* The first member of the structure is always 0 because we don't handle
516 structures with 0 members */
517 printf ("static int struct_forward_array[] = {\n 0");
519 for (j
= 1; j
<= i
; j
++)
520 printf (", %d", aggregate_in_mem
[j
]);
531 if (cxx_init () == false)
533 if (c_objc_common_init () == false)
537 #ifndef USE_MAPPED_LOCATION
538 /* Force the line number back to 0; check_newline will have
539 raised it to 1, which will make the builtin functions appear
540 not to be built in. */
544 /* If gen_declaration desired, open the output file. */
545 if (flag_gen_declaration
)
547 register char * const dumpname
= concat (dump_base_name
, ".decl", NULL
);
548 gen_declaration_file
= fopen (dumpname
, "w");
549 if (gen_declaration_file
== 0)
550 fatal_error ("can't open %s: %m", dumpname
);
554 if (flag_next_runtime
)
556 TAG_GETCLASS
= "objc_getClass";
557 TAG_GETMETACLASS
= "objc_getMetaClass";
558 TAG_MSGSEND
= "objc_msgSend";
559 TAG_MSGSENDSUPER
= "objc_msgSendSuper";
560 TAG_MSGSEND_STRET
= "objc_msgSend_stret";
561 TAG_MSGSENDSUPER_STRET
= "objc_msgSendSuper_stret";
562 default_constant_string_class_name
= "NSConstantString";
566 TAG_GETCLASS
= "objc_get_class";
567 TAG_GETMETACLASS
= "objc_get_meta_class";
568 TAG_MSGSEND
= "objc_msg_lookup";
569 TAG_MSGSENDSUPER
= "objc_msg_lookup_super";
570 /* GNU runtime does not provide special functions to support
571 structure-returning methods. */
572 default_constant_string_class_name
= "NXConstantString";
573 flag_typed_selectors
= 1;
578 if (print_struct_values
)
579 generate_struct_by_value_array ();
585 objc_finish_file (void)
587 mark_referenced_methods ();
590 /* We need to instantiate templates _before_ we emit ObjC metadata;
591 if we do not, some metadata (such as selectors) may go missing. */
592 instantiate_pending_templates (0);
595 /* Finalize Objective-C runtime data. No need to generate tables
596 and code if only checking syntax. */
597 if (!flag_syntax_only
)
600 if (gen_declaration_file
)
601 fclose (gen_declaration_file
);
608 /* Return the first occurrence of a method declaration corresponding
609 to sel_name in rproto_list. Search rproto_list recursively.
610 If is_class is 0, search for instance methods, otherwise for class
613 lookup_method_in_protocol_list (tree rproto_list
, tree sel_name
,
619 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
621 p
= TREE_VALUE (rproto
);
623 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
625 if ((fnd
= lookup_method (is_class
626 ? PROTOCOL_CLS_METHODS (p
)
627 : PROTOCOL_NST_METHODS (p
), sel_name
)))
629 else if (PROTOCOL_LIST (p
))
630 fnd
= lookup_method_in_protocol_list (PROTOCOL_LIST (p
),
635 ; /* An identifier...if we could not find a protocol. */
646 lookup_protocol_in_reflist (tree rproto_list
, tree lproto
)
650 /* Make sure the protocol is supported by the object on the rhs. */
651 if (TREE_CODE (lproto
) == PROTOCOL_INTERFACE_TYPE
)
654 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
656 p
= TREE_VALUE (rproto
);
658 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
663 else if (PROTOCOL_LIST (p
))
664 fnd
= lookup_protocol_in_reflist (PROTOCOL_LIST (p
), lproto
);
673 ; /* An identifier...if we could not find a protocol. */
680 objc_start_class_interface (tree
class, tree super_class
, tree protos
)
682 objc_interface_context
684 = start_class (CLASS_INTERFACE_TYPE
, class, super_class
, protos
);
685 objc_public_flag
= 0;
689 objc_start_category_interface (tree
class, tree categ
, tree protos
)
691 objc_interface_context
692 = start_class (CATEGORY_INTERFACE_TYPE
, class, categ
, protos
);
694 = continue_class (objc_interface_context
);
698 objc_start_protocol (tree name
, tree protos
)
700 objc_interface_context
701 = start_protocol (PROTOCOL_INTERFACE_TYPE
, name
, protos
);
705 objc_continue_interface (void)
708 = continue_class (objc_interface_context
);
712 objc_finish_interface (void)
714 finish_class (objc_interface_context
);
715 objc_interface_context
= NULL_TREE
;
719 objc_start_class_implementation (tree
class, tree super_class
)
721 objc_implementation_context
723 = start_class (CLASS_IMPLEMENTATION_TYPE
, class, super_class
, NULL_TREE
);
724 objc_public_flag
= 0;
728 objc_start_category_implementation (tree
class, tree categ
)
730 objc_implementation_context
731 = start_class (CATEGORY_IMPLEMENTATION_TYPE
, class, categ
, NULL_TREE
);
733 = continue_class (objc_implementation_context
);
737 objc_continue_implementation (void)
740 = continue_class (objc_implementation_context
);
744 objc_finish_implementation (void)
746 if (objc_implementation_context
)
748 finish_class (objc_implementation_context
);
749 objc_ivar_chain
= NULL_TREE
;
750 objc_implementation_context
= NULL_TREE
;
753 warning ("`@end' must appear in an @implementation context");
757 objc_set_visibility (int visibility
)
759 objc_public_flag
= visibility
;
763 objc_set_method_type (enum tree_code type
)
765 objc_inherit_code
= (type
== PLUS_EXPR
767 : INSTANCE_METHOD_DECL
);
771 objc_build_method_signature (tree rettype
, tree selector
, tree optparms
)
773 return build_method_decl (objc_inherit_code
, rettype
, selector
, optparms
);
777 objc_add_method_declaration (tree decl
)
779 if (!objc_interface_context
)
780 fatal_error ("method declaration not in @interface context");
782 objc_add_method (objc_interface_context
,
784 objc_inherit_code
== CLASS_METHOD_DECL
);
788 objc_start_method_definition (tree decl
)
790 if (!objc_implementation_context
)
791 fatal_error ("method definition not in @implementation context");
793 objc_add_method (objc_implementation_context
,
795 objc_inherit_code
== CLASS_METHOD_DECL
);
796 start_method_def (decl
);
800 objc_add_instance_variable (tree decl
)
802 (void) add_instance_variable (objc_ivar_context
,
807 /* Return 1 if IDENT is an ObjC/ObjC++ reserved keyword in the context of
811 objc_is_reserved_word (tree ident
)
813 unsigned char code
= C_RID_CODE (ident
);
815 return (OBJC_IS_AT_KEYWORD (code
)
817 || code
== RID_CLASS
|| code
== RID_PUBLIC
818 || code
== RID_PROTECTED
|| code
== RID_PRIVATE
819 || code
== RID_TRY
|| code
== RID_THROW
|| code
== RID_CATCH
824 /* Return true if TYPE is 'id'. */
827 objc_is_object_id (tree type
)
829 return OBJC_TYPE_NAME (type
) == objc_object_id
;
833 objc_is_class_id (tree type
)
835 return OBJC_TYPE_NAME (type
) == objc_class_id
;
838 /* Return 1 if LHS and RHS are compatible types for assignment or
839 various other operations. Return 0 if they are incompatible, and
840 return -1 if we choose to not decide (because the types are really
841 just C types, not ObjC specific ones). When the operation is
842 REFLEXIVE (typically comparisons), check for compatibility in
843 either direction; when it's not (typically assignments), don't.
845 This function is called in two cases: when both lhs and rhs are
846 pointers to records (in which case we check protocols too), and
847 when both lhs and rhs are records (in which case we check class
850 Warnings about classes/protocols not implementing a protocol are
851 emitted here (multiple of those warnings might be emitted for a
852 single line!); generic warnings about incompatible assignments and
853 lacks of casts in comparisons are/must be emitted by the caller if
858 objc_comptypes (tree lhs
, tree rhs
, int reflexive
)
860 /* New clause for protocols. */
862 /* Here we manage the case of a POINTER_TYPE = POINTER_TYPE. We only
863 manage the ObjC ones, and leave the rest to the C code. */
864 if (TREE_CODE (lhs
) == POINTER_TYPE
865 && TREE_CODE (TREE_TYPE (lhs
)) == RECORD_TYPE
866 && TREE_CODE (rhs
) == POINTER_TYPE
867 && TREE_CODE (TREE_TYPE (rhs
)) == RECORD_TYPE
)
869 int lhs_is_proto
= IS_PROTOCOL_QUALIFIED_UNTYPED (lhs
);
870 int rhs_is_proto
= IS_PROTOCOL_QUALIFIED_UNTYPED (rhs
);
874 tree lproto
, lproto_list
= TYPE_PROTOCOL_LIST (lhs
);
875 tree rproto
, rproto_list
;
878 /* <Protocol> = <Protocol> */
881 /* Class <Protocol> != id <Protocol>;
882 id <Protocol> != Class <Protocol> */
883 if (IS_ID (lhs
) != IS_ID (rhs
))
886 rproto_list
= TYPE_PROTOCOL_LIST (rhs
);
890 /* An assignment between objects of type 'id
891 <Protocol>'; make sure the protocol on the lhs is
892 supported by the object on the rhs. */
893 for (lproto
= lproto_list
; lproto
;
894 lproto
= TREE_CHAIN (lproto
))
896 p
= TREE_VALUE (lproto
);
897 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
901 ("object does not conform to the `%s' protocol",
902 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
908 /* Obscure case - a comparison between two objects
909 of type 'id <Protocol>'. Check that either the
910 protocol on the lhs is supported by the object on
911 the rhs, or viceversa. */
913 /* Check if the protocol on the lhs is supported by the
914 object on the rhs. */
915 for (lproto
= lproto_list
; lproto
;
916 lproto
= TREE_CHAIN (lproto
))
918 p
= TREE_VALUE (lproto
);
919 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
923 /* Check failed - check if the protocol on the rhs
924 is supported by the object on the lhs. */
925 for (rproto
= rproto_list
; rproto
;
926 rproto
= TREE_CHAIN (rproto
))
928 p
= TREE_VALUE (rproto
);
929 lproto
= lookup_protocol_in_reflist (lproto_list
,
934 /* This check failed too: incompatible */
944 /* <Protocol> = <class> * */
945 else if (TYPED_OBJECT (TREE_TYPE (rhs
)))
947 tree rname
= OBJC_TYPE_NAME (TREE_TYPE (rhs
));
950 /* Class <Protocol> != <class> * */
954 /* Make sure the protocol is supported by the object on
956 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
958 p
= TREE_VALUE (lproto
);
960 rinter
= lookup_interface (rname
);
962 while (rinter
&& !rproto
)
966 rproto_list
= CLASS_PROTOCOL_LIST (rinter
);
967 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
968 /* If the underlying ObjC class does not have
969 the protocol we're looking for, check for "one-off"
970 protocols (e.g., `NSObject<MyProt> *foo;') attached
974 rproto_list
= TYPE_PROTOCOL_LIST (TREE_TYPE (rhs
));
975 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
978 /* Check for protocols adopted by categories. */
979 cat
= CLASS_CATEGORY_LIST (rinter
);
980 while (cat
&& !rproto
)
982 rproto_list
= CLASS_PROTOCOL_LIST (cat
);
983 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
984 cat
= CLASS_CATEGORY_LIST (cat
);
987 rinter
= lookup_interface (CLASS_SUPER_NAME (rinter
));
991 warning ("class `%s' does not implement the `%s' protocol",
992 IDENTIFIER_POINTER (OBJC_TYPE_NAME (TREE_TYPE (rhs
))),
993 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
997 /* id <Protocol> = id; Class <Protocol> = id */
998 else if (objc_is_object_id (TREE_TYPE (rhs
)))
1002 /* id <Protocol> != Class; Class <Protocol> = Class */
1003 else if (objc_is_class_id (TREE_TYPE (rhs
)))
1005 return IS_CLASS (lhs
);
1007 /* <Protocol> = ?? : let comptypes decide. */
1010 else if (rhs_is_proto
)
1012 /* <class> * = <Protocol> */
1013 if (TYPED_OBJECT (TREE_TYPE (lhs
)))
1015 /* <class> * != Class <Protocol> */
1021 tree rname
= OBJC_TYPE_NAME (TREE_TYPE (lhs
));
1023 tree rproto
, rproto_list
= TYPE_PROTOCOL_LIST (rhs
);
1025 /* Make sure the protocol is supported by the object on
1027 for (rproto
= rproto_list
; rproto
;
1028 rproto
= TREE_CHAIN (rproto
))
1030 tree p
= TREE_VALUE (rproto
);
1032 rinter
= lookup_interface (rname
);
1034 while (rinter
&& !lproto
)
1038 tree lproto_list
= CLASS_PROTOCOL_LIST (rinter
);
1039 lproto
= lookup_protocol_in_reflist (lproto_list
, p
);
1040 /* If the underlying ObjC class does not
1041 have the protocol we're looking for,
1042 check for "one-off" protocols (e.g.,
1043 `NSObject<MyProt> *foo;') attached to the
1047 lproto_list
= TYPE_PROTOCOL_LIST
1049 lproto
= lookup_protocol_in_reflist
1053 /* Check for protocols adopted by categories. */
1054 cat
= CLASS_CATEGORY_LIST (rinter
);
1055 while (cat
&& !lproto
)
1057 lproto_list
= CLASS_PROTOCOL_LIST (cat
);
1058 lproto
= lookup_protocol_in_reflist (lproto_list
,
1060 cat
= CLASS_CATEGORY_LIST (cat
);
1063 rinter
= lookup_interface (CLASS_SUPER_NAME
1068 warning ("class `%s' does not implement the `%s' protocol",
1069 IDENTIFIER_POINTER (OBJC_TYPE_NAME
1071 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
1078 /* id = id <Protocol>; id = Class <Protocol> */
1079 else if (objc_is_object_id (TREE_TYPE (lhs
)))
1083 /* Class != id <Protocol>; Class = Class <Protocol> */
1084 else if (objc_is_class_id (TREE_TYPE (lhs
)))
1086 return IS_CLASS (rhs
);
1088 /* ??? = <Protocol> : let comptypes decide */
1096 /* Attention: we shouldn't defer to comptypes here. One bad
1097 side effect would be that we might loose the REFLEXIVE
1100 lhs
= TREE_TYPE (lhs
);
1101 rhs
= TREE_TYPE (rhs
);
1105 if (TREE_CODE (lhs
) != RECORD_TYPE
|| TREE_CODE (rhs
) != RECORD_TYPE
)
1107 /* Nothing to do with ObjC - let immediately comptypes take
1108 responsibility for checking. */
1112 /* `id' = `<class> *' `<class> *' = `id': always allow it.
1114 'Object *o = [[Object alloc] init]; falls
1115 in the case <class> * = `id'.
1117 if ((objc_is_object_id (lhs
) && TYPED_OBJECT (rhs
))
1118 || (objc_is_object_id (rhs
) && TYPED_OBJECT (lhs
)))
1121 /* `id' = `Class', `Class' = `id' */
1123 else if ((objc_is_object_id (lhs
) && objc_is_class_id (rhs
))
1124 || (objc_is_class_id (lhs
) && objc_is_object_id (rhs
)))
1127 /* `Class' != `<class> *' && `<class> *' != `Class'! */
1128 else if ((OBJC_TYPE_NAME (lhs
) == objc_class_id
&& TYPED_OBJECT (rhs
))
1129 || (OBJC_TYPE_NAME (rhs
) == objc_class_id
&& TYPED_OBJECT (lhs
)))
1132 /* `<class> *' = `<class> *' */
1134 else if (TYPED_OBJECT (lhs
) && TYPED_OBJECT (rhs
))
1136 tree lname
= OBJC_TYPE_NAME (lhs
);
1137 tree rname
= OBJC_TYPE_NAME (rhs
);
1143 /* If the left hand side is a super class of the right hand side,
1145 for (inter
= lookup_interface (rname
); inter
;
1146 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
1147 if (lname
== CLASS_SUPER_NAME (inter
))
1150 /* Allow the reverse when reflexive. */
1152 for (inter
= lookup_interface (lname
); inter
;
1153 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
1154 if (rname
== CLASS_SUPER_NAME (inter
))
1160 /* Not an ObjC type - let comptypes do the check. */
1164 /* Called from finish_decl. */
1167 objc_check_decl (tree decl
)
1169 tree type
= TREE_TYPE (decl
);
1171 if (TREE_CODE (type
) != RECORD_TYPE
)
1173 if (OBJC_TYPE_NAME (type
) && (type
= objc_is_class_name (OBJC_TYPE_NAME (type
))))
1174 error ("statically allocated instance of Objective-C class `%s'",
1175 IDENTIFIER_POINTER (type
));
1178 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1179 either name an Objective-C class, or refer to the special 'id' or 'Class'
1180 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
1183 objc_get_protocol_qualified_type (tree interface
, tree protocols
)
1188 type
= objc_object_type
;
1189 else if (!(type
= objc_is_id (interface
)))
1191 type
= objc_is_class_name (interface
);
1194 type
= xref_tag (RECORD_TYPE
, type
);
1201 type
= build_variant_type_copy (type
);
1202 /* Look up protocols and install in lang specific list. Note
1203 that the protocol list can have a different lifetime than T! */
1204 SET_TYPE_PROTOCOL_LIST (type
, lookup_and_install_protocols (protocols
));
1206 /* Establish the ObjC-ness of this record. */
1207 if (TREE_CODE (type
) == RECORD_TYPE
)
1208 TREE_STATIC_TEMPLATE (type
) = 1;
1214 /* Check for circular dependencies in protocols. The arguments are
1215 PROTO, the protocol to check, and LIST, a list of protocol it
1219 check_protocol_recursively (tree proto
, tree list
)
1223 for (p
= list
; p
; p
= TREE_CHAIN (p
))
1225 tree pp
= TREE_VALUE (p
);
1227 if (TREE_CODE (pp
) == IDENTIFIER_NODE
)
1228 pp
= lookup_protocol (pp
);
1231 fatal_error ("protocol `%s' has circular dependency",
1232 IDENTIFIER_POINTER (PROTOCOL_NAME (pp
)));
1234 check_protocol_recursively (proto
, PROTOCOL_LIST (pp
));
1238 /* Look up PROTOCOLS, and return a list of those that are found.
1239 If none are found, return NULL. */
1242 lookup_and_install_protocols (tree protocols
)
1245 tree return_value
= NULL_TREE
;
1247 for (proto
= protocols
; proto
; proto
= TREE_CHAIN (proto
))
1249 tree ident
= TREE_VALUE (proto
);
1250 tree p
= lookup_protocol (ident
);
1253 error ("cannot find protocol declaration for `%s'",
1254 IDENTIFIER_POINTER (ident
));
1256 return_value
= chainon (return_value
,
1257 build_tree_list (NULL_TREE
, p
));
1260 return return_value
;
1263 /* Create a declaration for field NAME of a given TYPE. */
1266 create_field_decl (tree type
, const char *name
)
1268 return build_decl (FIELD_DECL
, get_identifier (name
), type
);
1271 /* Create a global, static declaration for variable NAME of a given TYPE. The
1272 finish_var_decl() routine will need to be called on it afterwards. */
1275 start_var_decl (tree type
, const char *name
)
1277 tree var
= build_decl (VAR_DECL
, get_identifier (name
), type
);
1279 TREE_STATIC (var
) = 1;
1280 DECL_INITIAL (var
) = error_mark_node
; /* A real initializer is coming... */
1281 DECL_IGNORED_P (var
) = 1;
1282 DECL_ARTIFICIAL (var
) = 1;
1283 DECL_CONTEXT (var
) = NULL_TREE
;
1285 DECL_THIS_STATIC (var
) = 1; /* squash redeclaration errors */
1291 /* Finish off the variable declaration created by start_var_decl(). */
1294 finish_var_decl (tree var
, tree initializer
)
1296 finish_decl (var
, initializer
, NULL_TREE
);
1297 /* Ensure that the variable actually gets output. */
1298 mark_decl_referenced (var
);
1299 /* Mark the decl to avoid "defined but not used" warning. */
1300 TREE_USED (var
) = 1;
1303 /* Find the decl for the constant string class reference. This is only
1304 used for the NeXT runtime. */
1307 setup_string_decl (void)
1312 /* %s in format will provide room for terminating null */
1313 length
= strlen (STRING_OBJECT_GLOBAL_FORMAT
)
1314 + strlen (constant_string_class_name
);
1315 name
= xmalloc (length
);
1316 sprintf (name
, STRING_OBJECT_GLOBAL_FORMAT
,
1317 constant_string_class_name
);
1318 constant_string_global_id
= get_identifier (name
);
1319 string_class_decl
= lookup_name (constant_string_global_id
);
1321 return string_class_decl
;
1324 /* Purpose: "play" parser, creating/installing representations
1325 of the declarations that are required by Objective-C.
1329 type_spec--------->sc_spec
1330 (tree_list) (tree_list)
1333 identifier_node identifier_node */
1336 synth_module_prologue (void)
1339 enum debug_info_type save_write_symbols
= write_symbols
;
1340 const struct gcc_debug_hooks
*const save_hooks
= debug_hooks
;
1342 /* Suppress outputting debug symbols, because
1343 dbxout_init hasn'r been called yet. */
1344 write_symbols
= NO_DEBUG
;
1345 debug_hooks
= &do_nothing_debug_hooks
;
1348 push_lang_context (lang_name_c
); /* extern "C" */
1351 /* The following are also defined in <objc/objc.h> and friends. */
1353 objc_object_id
= get_identifier (TAG_OBJECT
);
1354 objc_class_id
= get_identifier (TAG_CLASS
);
1356 objc_object_reference
= xref_tag (RECORD_TYPE
, objc_object_id
);
1357 objc_class_reference
= xref_tag (RECORD_TYPE
, objc_class_id
);
1359 objc_object_type
= build_pointer_type (objc_object_reference
);
1360 objc_class_type
= build_pointer_type (objc_class_reference
);
1362 objc_object_name
= get_identifier (OBJECT_TYPEDEF_NAME
);
1363 objc_class_name
= get_identifier (CLASS_TYPEDEF_NAME
);
1365 /* Declare the 'id' and 'Class' typedefs. */
1367 type
= lang_hooks
.decls
.pushdecl (build_decl (TYPE_DECL
,
1370 DECL_IN_SYSTEM_HEADER (type
) = 1;
1371 type
= lang_hooks
.decls
.pushdecl (build_decl (TYPE_DECL
,
1374 DECL_IN_SYSTEM_HEADER (type
) = 1;
1376 /* Forward-declare '@interface Protocol'. */
1378 type
= get_identifier (PROTOCOL_OBJECT_CLASS_NAME
);
1379 objc_declare_class (tree_cons (NULL_TREE
, type
, NULL_TREE
));
1380 objc_protocol_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
1383 /* Declare type of selector-objects that represent an operation name. */
1385 if (flag_next_runtime
)
1386 /* `struct objc_selector *' */
1388 = build_pointer_type (xref_tag (RECORD_TYPE
,
1389 get_identifier (TAG_SELECTOR
)));
1391 /* `const struct objc_selector *' */
1393 = build_pointer_type
1394 (build_qualified_type (xref_tag (RECORD_TYPE
,
1395 get_identifier (TAG_SELECTOR
)),
1398 /* Declare receiver type used for dispatching messages to 'super'. */
1400 /* `struct objc_super *' */
1401 objc_super_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
1402 get_identifier (TAG_SUPER
)));
1404 if (flag_next_runtime
)
1406 /* NB: In order to call one of the ..._stret (struct-returning)
1407 functions, the function *MUST* first be cast to a signature that
1408 corresponds to the actual ObjC method being invoked. This is
1409 what is done by the build_objc_method_call() routine below. */
1411 /* id objc_msgSend (id, SEL, ...); */
1412 /* id objc_msgSendNonNil (id, SEL, ...); */
1413 /* id objc_msgSend_stret (id, SEL, ...); */
1414 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1416 = build_function_type (objc_object_type
,
1417 tree_cons (NULL_TREE
, objc_object_type
,
1418 tree_cons (NULL_TREE
, objc_selector_type
,
1420 umsg_decl
= builtin_function (TAG_MSGSEND
,
1421 type
, 0, NOT_BUILT_IN
,
1423 umsg_nonnil_decl
= builtin_function (TAG_MSGSEND_NONNIL
,
1424 type
, 0, NOT_BUILT_IN
,
1426 umsg_stret_decl
= builtin_function (TAG_MSGSEND_STRET
,
1427 type
, 0, NOT_BUILT_IN
,
1429 umsg_nonnil_stret_decl
= builtin_function (TAG_MSGSEND_NONNIL_STRET
,
1430 type
, 0, NOT_BUILT_IN
,
1433 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1434 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1436 = build_function_type (objc_object_type
,
1437 tree_cons (NULL_TREE
, objc_super_type
,
1438 tree_cons (NULL_TREE
, objc_selector_type
,
1440 umsg_super_decl
= builtin_function (TAG_MSGSENDSUPER
,
1441 type
, 0, NOT_BUILT_IN
,
1443 umsg_super_stret_decl
= builtin_function (TAG_MSGSENDSUPER_STRET
,
1444 type
, 0, NOT_BUILT_IN
, 0,
1449 /* GNU runtime messenger entry points. */
1451 /* typedef id (*IMP)(id, SEL, ...); */
1453 = build_pointer_type
1454 (build_function_type (objc_object_type
,
1455 tree_cons (NULL_TREE
, objc_object_type
,
1456 tree_cons (NULL_TREE
, objc_selector_type
,
1459 /* IMP objc_msg_lookup (id, SEL); */
1461 = build_function_type (IMP_type
,
1462 tree_cons (NULL_TREE
, objc_object_type
,
1463 tree_cons (NULL_TREE
, objc_selector_type
,
1464 OBJC_VOID_AT_END
)));
1465 umsg_decl
= builtin_function (TAG_MSGSEND
,
1466 type
, 0, NOT_BUILT_IN
,
1469 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1471 = build_function_type (IMP_type
,
1472 tree_cons (NULL_TREE
, objc_super_type
,
1473 tree_cons (NULL_TREE
, objc_selector_type
,
1474 OBJC_VOID_AT_END
)));
1475 umsg_super_decl
= builtin_function (TAG_MSGSENDSUPER
,
1476 type
, 0, NOT_BUILT_IN
,
1479 /* The following GNU runtime entry point is called to initialize
1482 __objc_exec_class (void *); */
1484 = build_function_type (void_type_node
,
1485 tree_cons (NULL_TREE
, ptr_type_node
,
1487 execclass_decl
= builtin_function (TAG_EXECCLASS
,
1488 type
, 0, NOT_BUILT_IN
,
1492 /* id objc_getClass (const char *); */
1494 type
= build_function_type (objc_object_type
,
1495 tree_cons (NULL_TREE
,
1496 const_string_type_node
,
1500 = builtin_function (TAG_GETCLASS
, type
, 0, NOT_BUILT_IN
,
1503 /* id objc_getMetaClass (const char *); */
1505 objc_get_meta_class_decl
1506 = builtin_function (TAG_GETMETACLASS
, type
, 0, NOT_BUILT_IN
, NULL
, NULL_TREE
);
1508 build_class_template ();
1509 build_super_template ();
1510 build_protocol_template ();
1511 build_category_template ();
1512 build_objc_exception_stuff ();
1514 if (flag_next_runtime
)
1515 build_next_objc_exception_stuff ();
1517 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1519 if (! flag_next_runtime
)
1520 build_selector_table_decl ();
1522 /* Forward declare constant_string_id and constant_string_type. */
1523 if (!constant_string_class_name
)
1524 constant_string_class_name
= default_constant_string_class_name
;
1526 constant_string_id
= get_identifier (constant_string_class_name
);
1527 objc_declare_class (tree_cons (NULL_TREE
, constant_string_id
, NULL_TREE
));
1529 /* Pre-build the following entities - for speed/convenience. */
1530 self_id
= get_identifier ("self");
1531 ucmd_id
= get_identifier ("_cmd");
1533 /* The C++ front-end does not appear to grok __attribute__((__unused__)). */
1534 unused_list
= build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
1538 pop_lang_context ();
1541 write_symbols
= save_write_symbols
;
1542 debug_hooks
= save_hooks
;
1545 /* Ensure that the ivar list for NSConstantString/NXConstantString
1546 (or whatever was specified via `-fconstant-string-class')
1547 contains fields at least as large as the following three, so that
1548 the runtime can stomp on them with confidence:
1550 struct STRING_OBJECT_CLASS_NAME
1554 unsigned int length;
1558 check_string_class_template (void)
1560 tree field_decl
= TYPE_FIELDS (constant_string_type
);
1562 #define AT_LEAST_AS_LARGE_AS(F, T) \
1563 (F && TREE_CODE (F) == FIELD_DECL \
1564 && (TREE_INT_CST_LOW (DECL_SIZE (F)) \
1565 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1567 if (!AT_LEAST_AS_LARGE_AS (field_decl
, ptr_type_node
))
1570 field_decl
= TREE_CHAIN (field_decl
);
1571 if (!AT_LEAST_AS_LARGE_AS (field_decl
, ptr_type_node
))
1574 field_decl
= TREE_CHAIN (field_decl
);
1575 return AT_LEAST_AS_LARGE_AS (field_decl
, unsigned_type_node
);
1577 #undef AT_LEAST_AS_LARGE_AS
1580 /* Avoid calling `check_string_class_template ()' more than once. */
1581 static GTY(()) int string_layout_checked
;
1583 /* Custom build_string which sets TREE_TYPE! */
1586 my_build_string (int len
, const char *str
)
1588 return fix_string_type (build_string (len
, str
));
1593 string_hash (const void *ptr
)
1595 tree str
= ((struct string_descriptor
*)ptr
)->literal
;
1596 const unsigned char *p
= (const unsigned char *) TREE_STRING_POINTER (str
);
1597 int i
, len
= TREE_STRING_LENGTH (str
);
1600 for (i
= 0; i
< len
; i
++)
1601 h
= ((h
* 613) + p
[i
]);
1607 string_eq (const void *ptr1
, const void *ptr2
)
1609 tree str1
= ((struct string_descriptor
*)ptr1
)->literal
;
1610 tree str2
= ((struct string_descriptor
*)ptr2
)->literal
;
1611 int len1
= TREE_STRING_LENGTH (str1
);
1613 return (len1
== TREE_STRING_LENGTH (str2
)
1614 && !memcmp (TREE_STRING_POINTER (str1
), TREE_STRING_POINTER (str2
),
1618 /* Given a chain of STRING_CST's, build a static instance of
1619 NXConstantString which points at the concatenation of those
1620 strings. We place the string object in the __string_objects
1621 section of the __OBJC segment. The Objective-C runtime will
1622 initialize the isa pointers of the string objects to point at the
1623 NXConstantString class object. */
1626 objc_build_string_object (tree string
)
1628 tree initlist
, constructor
, constant_string_class
;
1631 struct string_descriptor
*desc
, key
;
1634 /* Prep the string argument. */
1635 string
= fix_string_type (string
);
1636 TREE_SET_CODE (string
, STRING_CST
);
1637 length
= TREE_STRING_LENGTH (string
) - 1;
1639 /* Check whether the string class being used actually exists and has the
1640 correct ivar layout. */
1641 if (!string_layout_checked
)
1643 string_layout_checked
= -1;
1644 constant_string_class
= lookup_interface (constant_string_id
);
1646 if (!constant_string_class
1647 || !(constant_string_type
1648 = CLASS_STATIC_TEMPLATE (constant_string_class
)))
1649 error ("cannot find interface declaration for `%s'",
1650 IDENTIFIER_POINTER (constant_string_id
));
1651 /* The NSConstantString/NXConstantString ivar layout is now known. */
1652 else if (!check_string_class_template ())
1653 error ("interface `%s' does not have valid constant string layout",
1654 IDENTIFIER_POINTER (constant_string_id
));
1655 /* For the NeXT runtime, we can generate a literal reference
1656 to the string class, don't need to run a constructor. */
1657 else if (flag_next_runtime
&& !setup_string_decl ())
1658 error ("cannot find reference tag for class `%s'",
1659 IDENTIFIER_POINTER (constant_string_id
));
1662 string_layout_checked
= 1; /* Success! */
1663 add_class_reference (constant_string_id
);
1667 if (string_layout_checked
== -1)
1668 return error_mark_node
;
1670 /* Perhaps we already constructed a constant string just like this one? */
1671 key
.literal
= string
;
1672 loc
= htab_find_slot (string_htab
, &key
, INSERT
);
1678 *loc
= desc
= ggc_alloc (sizeof (*desc
));
1679 desc
->literal
= string
;
1681 /* GNU: & ((NXConstantString) { NULL, string, length }) */
1682 /* NeXT: & ((NSConstantString) { isa, string, length }) */
1683 fields
= TYPE_FIELDS (constant_string_type
);
1685 = build_tree_list (fields
,
1687 ? build_unary_op (ADDR_EXPR
, string_class_decl
, 0)
1688 : build_int_cst (NULL_TREE
, 0));
1689 fields
= TREE_CHAIN (fields
);
1690 initlist
= tree_cons (fields
, build_unary_op (ADDR_EXPR
, string
, 1),
1692 fields
= TREE_CHAIN (fields
);
1693 initlist
= tree_cons (fields
, build_int_cst (NULL_TREE
, length
),
1695 constructor
= objc_build_constructor (constant_string_type
,
1696 nreverse (initlist
));
1697 TREE_INVARIANT (constructor
) = true;
1699 if (!flag_next_runtime
)
1701 = objc_add_static_instance (constructor
, constant_string_type
);
1704 var
= build_decl (CONST_DECL
, NULL
, TREE_TYPE (constructor
));
1705 DECL_INITIAL (var
) = constructor
;
1706 TREE_STATIC (var
) = 1;
1707 pushdecl_top_level (var
);
1710 desc
->constructor
= constructor
;
1713 addr
= build_unary_op (ADDR_EXPR
, desc
->constructor
, 1);
1718 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1720 static GTY(()) int num_static_inst
;
1723 objc_add_static_instance (tree constructor
, tree class_decl
)
1728 /* Find the list of static instances for the CLASS_DECL. Create one if
1730 for (chain
= &objc_static_instances
;
1731 *chain
&& TREE_VALUE (*chain
) != class_decl
;
1732 chain
= &TREE_CHAIN (*chain
));
1735 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
1736 add_objc_string (OBJC_TYPE_NAME (class_decl
), class_names
);
1739 sprintf (buf
, "_OBJC_INSTANCE_%d", num_static_inst
++);
1740 decl
= build_decl (VAR_DECL
, get_identifier (buf
), class_decl
);
1741 DECL_COMMON (decl
) = 1;
1742 TREE_STATIC (decl
) = 1;
1743 DECL_ARTIFICIAL (decl
) = 1;
1744 DECL_INITIAL (decl
) = constructor
;
1746 /* We may be writing something else just now.
1747 Postpone till end of input. */
1748 DECL_DEFER_OUTPUT (decl
) = 1;
1749 pushdecl_top_level (decl
);
1750 rest_of_decl_compilation (decl
, 1, 0);
1752 /* Add the DECL to the head of this CLASS' list. */
1753 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
1758 /* Build a static constant CONSTRUCTOR
1759 with type TYPE and elements ELTS. */
1762 objc_build_constructor (tree type
, tree elts
)
1764 tree constructor
= build_constructor (type
, elts
);
1766 TREE_CONSTANT (constructor
) = 1;
1767 TREE_STATIC (constructor
) = 1;
1768 TREE_READONLY (constructor
) = 1;
1771 /* Adjust for impedance mismatch. We should figure out how to build
1772 CONSTRUCTORs that consistently please both the C and C++ gods. */
1773 if (!TREE_PURPOSE (elts
))
1774 TREE_TYPE (constructor
) = NULL_TREE
;
1775 TREE_HAS_CONSTRUCTOR (constructor
) = 1;
1781 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1783 /* Predefine the following data type:
1791 void *defs[cls_def_cnt + cat_def_cnt];
1795 build_objc_symtab_template (void)
1797 tree field_decl
, field_decl_chain
;
1799 objc_symtab_template
1800 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SYMTAB
));
1802 /* long sel_ref_cnt; */
1803 field_decl
= create_field_decl (long_integer_type_node
, "sel_ref_cnt");
1804 field_decl_chain
= field_decl
;
1807 field_decl
= create_field_decl (build_pointer_type (objc_selector_type
),
1809 chainon (field_decl_chain
, field_decl
);
1811 /* short cls_def_cnt; */
1812 field_decl
= create_field_decl (short_integer_type_node
, "cls_def_cnt");
1813 chainon (field_decl_chain
, field_decl
);
1815 /* short cat_def_cnt; */
1816 field_decl
= create_field_decl (short_integer_type_node
,
1818 chainon (field_decl_chain
, field_decl
);
1820 if (imp_count
|| cat_count
|| !flag_next_runtime
)
1822 /* void *defs[imp_count + cat_count (+ 1)]; */
1823 /* NB: The index is one less than the size of the array. */
1824 int index
= imp_count
+ cat_count
1825 + (flag_next_runtime
? -1: 0);
1826 field_decl
= create_field_decl
1829 build_index_type (build_int_cst (NULL_TREE
, index
))),
1831 chainon (field_decl_chain
, field_decl
);
1834 finish_struct (objc_symtab_template
, field_decl_chain
, NULL_TREE
);
1837 /* Create the initial value for the `defs' field of _objc_symtab.
1838 This is a CONSTRUCTOR. */
1841 init_def_list (tree type
)
1843 tree expr
, initlist
= NULL_TREE
;
1844 struct imp_entry
*impent
;
1847 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1849 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
1851 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1852 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1857 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1859 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1861 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1862 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1866 if (!flag_next_runtime
)
1868 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1871 if (static_instances_decl
)
1872 expr
= build_unary_op (ADDR_EXPR
, static_instances_decl
, 0);
1874 expr
= build_int_cst (NULL_TREE
, 0);
1876 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1879 return objc_build_constructor (type
, nreverse (initlist
));
1882 /* Construct the initial value for all of _objc_symtab. */
1885 init_objc_symtab (tree type
)
1889 /* sel_ref_cnt = { ..., 5, ... } */
1891 initlist
= build_tree_list (NULL_TREE
,
1892 build_int_cst (long_integer_type_node
, 0));
1894 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1896 if (flag_next_runtime
|| ! sel_ref_chain
)
1897 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
1900 = tree_cons (NULL_TREE
,
1901 convert (build_pointer_type (objc_selector_type
),
1902 build_unary_op (ADDR_EXPR
,
1903 UOBJC_SELECTOR_TABLE_decl
, 1)),
1906 /* cls_def_cnt = { ..., 5, ... } */
1908 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, imp_count
), initlist
);
1910 /* cat_def_cnt = { ..., 5, ... } */
1912 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, cat_count
), initlist
);
1914 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1916 if (imp_count
|| cat_count
|| !flag_next_runtime
)
1919 tree field
= TYPE_FIELDS (type
);
1920 field
= TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field
))));
1922 initlist
= tree_cons (NULL_TREE
, init_def_list (TREE_TYPE (field
)),
1926 return objc_build_constructor (type
, nreverse (initlist
));
1929 /* Generate forward declarations for metadata such as
1930 'OBJC_CLASS_...'. */
1933 build_metadata_decl (const char *name
, tree type
)
1937 /* struct TYPE NAME_<name>; */
1938 decl
= start_var_decl (type
, synth_id_with_class_suffix
1940 objc_implementation_context
));
1945 /* Push forward-declarations of all the categories so that
1946 init_def_list can use them in a CONSTRUCTOR. */
1949 forward_declare_categories (void)
1951 struct imp_entry
*impent
;
1952 tree sav
= objc_implementation_context
;
1954 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1956 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1958 /* Set an invisible arg to synth_id_with_class_suffix. */
1959 objc_implementation_context
= impent
->imp_context
;
1960 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
1961 impent
->class_decl
= build_metadata_decl ("_OBJC_CATEGORY",
1962 objc_category_template
);
1965 objc_implementation_context
= sav
;
1968 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
1969 and initialized appropriately. */
1972 generate_objc_symtab_decl (void)
1974 /* forward declare categories */
1976 forward_declare_categories ();
1978 build_objc_symtab_template ();
1979 UOBJC_SYMBOLS_decl
= start_var_decl (objc_symtab_template
, "_OBJC_SYMBOLS");
1980 finish_var_decl (UOBJC_SYMBOLS_decl
,
1981 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)));
1985 init_module_descriptor (tree type
)
1987 tree initlist
, expr
;
1989 /* version = { 1, ... } */
1991 expr
= build_int_cst (long_integer_type_node
, OBJC_VERSION
);
1992 initlist
= build_tree_list (NULL_TREE
, expr
);
1994 /* size = { ..., sizeof (struct _objc_module), ... } */
1996 expr
= convert (long_integer_type_node
,
1997 size_in_bytes (objc_module_template
));
1998 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2000 /* name = { ..., "foo.m", ... } */
2002 expr
= add_objc_string (get_identifier (input_filename
), class_names
);
2003 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2005 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
2007 if (UOBJC_SYMBOLS_decl
)
2008 expr
= build_unary_op (ADDR_EXPR
, UOBJC_SYMBOLS_decl
, 0);
2010 expr
= build_int_cst (NULL_TREE
, 0);
2011 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2013 return objc_build_constructor (type
, nreverse (initlist
));
2016 /* Write out the data structures to describe Objective C classes defined.
2018 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2021 build_module_descriptor (void)
2023 tree field_decl
, field_decl_chain
;
2026 push_lang_context (lang_name_c
); /* extern "C" */
2029 objc_module_template
2030 = start_struct (RECORD_TYPE
, get_identifier (UTAG_MODULE
));
2033 field_decl
= create_field_decl (long_integer_type_node
, "version");
2034 field_decl_chain
= field_decl
;
2037 field_decl
= create_field_decl (long_integer_type_node
, "size");
2038 chainon (field_decl_chain
, field_decl
);
2041 field_decl
= create_field_decl (string_type_node
, "name");
2042 chainon (field_decl_chain
, field_decl
);
2044 /* struct _objc_symtab *symtab; */
2046 = create_field_decl (build_pointer_type
2047 (xref_tag (RECORD_TYPE
,
2048 get_identifier (UTAG_SYMTAB
))),
2050 chainon (field_decl_chain
, field_decl
);
2052 finish_struct (objc_module_template
, field_decl_chain
, NULL_TREE
);
2054 /* Create an instance of "_objc_module". */
2055 UOBJC_MODULES_decl
= start_var_decl (objc_module_template
, "_OBJC_MODULES");
2056 finish_var_decl (UOBJC_MODULES_decl
,
2057 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl
)));
2060 pop_lang_context ();
2064 /* The GNU runtime requires us to provide a static initializer function
2067 static void __objc_gnu_init (void) {
2068 __objc_exec_class (&L_OBJC_MODULES);
2072 build_module_initializer_routine (void)
2077 push_lang_context (lang_name_c
); /* extern "C" */
2080 objc_push_parm (build_decl (PARM_DECL
, NULL_TREE
, void_type_node
));
2081 objc_start_function (get_identifier (TAG_GNUINIT
),
2082 build_function_type (void_type_node
,
2084 NULL_TREE
, objc_get_parm_info (0));
2086 body
= c_begin_compound_stmt (true);
2087 add_stmt (build_function_call
2091 build_unary_op (ADDR_EXPR
,
2092 UOBJC_MODULES_decl
, 0))));
2093 add_stmt (c_end_compound_stmt (body
, true));
2095 TREE_PUBLIC (current_function_decl
) = 0;
2098 /* For Objective-C++, we will need to call __objc_gnu_init
2099 from objc_generate_static_init_call() below. */
2100 DECL_STATIC_CONSTRUCTOR (current_function_decl
) = 1;
2103 GNU_INIT_decl
= current_function_decl
;
2107 pop_lang_context ();
2112 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2113 to be called by the module initializer routine. */
2116 objc_static_init_needed_p (void)
2118 return (GNU_INIT_decl
!= NULL_TREE
);
2121 /* Generate a call to the __objc_gnu_init initializer function. */
2124 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED
)
2126 add_stmt (build_stmt (EXPR_STMT
,
2127 build_function_call (GNU_INIT_decl
, NULL_TREE
)));
2131 #endif /* OBJCPLUS */
2133 /* Return the DECL of the string IDENT in the SECTION. */
2136 get_objc_string_decl (tree ident
, enum string_section section
)
2140 if (section
== class_names
)
2141 chain
= class_names_chain
;
2142 else if (section
== meth_var_names
)
2143 chain
= meth_var_names_chain
;
2144 else if (section
== meth_var_types
)
2145 chain
= meth_var_types_chain
;
2149 for (; chain
!= 0; chain
= TREE_CHAIN (chain
))
2150 if (TREE_VALUE (chain
) == ident
)
2151 return (TREE_PURPOSE (chain
));
2157 /* Output references to all statically allocated objects. Return the DECL
2158 for the array built. */
2161 generate_static_references (void)
2163 tree decls
= NULL_TREE
, expr
= NULL_TREE
;
2164 tree class_name
, class, decl
, initlist
;
2165 tree cl_chain
, in_chain
, type
2166 = build_array_type (build_pointer_type (void_type_node
), NULL_TREE
);
2167 int num_inst
, num_class
;
2170 if (flag_next_runtime
)
2173 for (cl_chain
= objc_static_instances
, num_class
= 0;
2174 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
2176 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
2177 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
2179 sprintf (buf
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
2180 decl
= start_var_decl (type
, buf
);
2182 /* Output {class_name, ...}. */
2183 class = TREE_VALUE (cl_chain
);
2184 class_name
= get_objc_string_decl (OBJC_TYPE_NAME (class), class_names
);
2185 initlist
= build_tree_list (NULL_TREE
,
2186 build_unary_op (ADDR_EXPR
, class_name
, 1));
2188 /* Output {..., instance, ...}. */
2189 for (in_chain
= TREE_PURPOSE (cl_chain
);
2190 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
2192 expr
= build_unary_op (ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
2193 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2196 /* Output {..., NULL}. */
2197 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
2199 expr
= objc_build_constructor (TREE_TYPE (decl
), nreverse (initlist
));
2200 finish_var_decl (decl
, expr
);
2202 = tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, decl
, 1), decls
);
2205 decls
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), decls
);
2206 expr
= objc_build_constructor (type
, nreverse (decls
));
2207 static_instances_decl
= start_var_decl (type
, "_OBJC_STATIC_INSTANCES");
2208 finish_var_decl (static_instances_decl
, expr
);
2211 /* Output all strings. */
2214 generate_strings (void)
2216 tree chain
, string_expr
;
2217 tree string
, decl
, type
;
2219 for (chain
= class_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
2221 string
= TREE_VALUE (chain
);
2222 decl
= TREE_PURPOSE (chain
);
2223 type
= build_array_type
2226 (build_int_cst (NULL_TREE
,
2227 IDENTIFIER_LENGTH (string
))));
2228 decl
= start_var_decl (type
, IDENTIFIER_POINTER (DECL_NAME (decl
)));
2229 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
2230 IDENTIFIER_POINTER (string
));
2231 finish_var_decl (decl
, string_expr
);
2234 for (chain
= meth_var_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
2236 string
= TREE_VALUE (chain
);
2237 decl
= TREE_PURPOSE (chain
);
2238 type
= build_array_type
2241 (build_int_cst (NULL_TREE
,
2242 IDENTIFIER_LENGTH (string
))));
2243 decl
= start_var_decl (type
, IDENTIFIER_POINTER (DECL_NAME (decl
)));
2244 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
2245 IDENTIFIER_POINTER (string
));
2246 finish_var_decl (decl
, string_expr
);
2249 for (chain
= meth_var_types_chain
; chain
; chain
= TREE_CHAIN (chain
))
2251 string
= TREE_VALUE (chain
);
2252 decl
= TREE_PURPOSE (chain
);
2253 type
= build_array_type
2256 (build_int_cst (NULL_TREE
,
2257 IDENTIFIER_LENGTH (string
))));
2258 decl
= start_var_decl (type
, IDENTIFIER_POINTER (DECL_NAME (decl
)));
2259 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
2260 IDENTIFIER_POINTER (string
));
2261 finish_var_decl (decl
, string_expr
);
2265 static GTY(()) int selector_reference_idx
;
2268 build_selector_reference_decl (void)
2273 sprintf (buf
, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx
++);
2274 decl
= start_var_decl (objc_selector_type
, buf
);
2280 build_selector_table_decl (void)
2284 if (flag_typed_selectors
)
2286 build_selector_template ();
2287 temp
= build_array_type (objc_selector_template
, NULL_TREE
);
2290 temp
= build_array_type (objc_selector_type
, NULL_TREE
);
2292 UOBJC_SELECTOR_TABLE_decl
= start_var_decl (temp
, "_OBJC_SELECTOR_TABLE");
2295 /* Just a handy wrapper for add_objc_string. */
2298 build_selector (tree ident
)
2300 return convert (objc_selector_type
,
2301 add_objc_string (ident
, meth_var_names
));
2305 build_selector_translation_table (void)
2307 tree chain
, initlist
= NULL_TREE
;
2309 tree decl
= NULL_TREE
;
2311 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
2315 if (warn_selector
&& objc_implementation_context
)
2319 for (method_chain
= meth_var_names_chain
;
2321 method_chain
= TREE_CHAIN (method_chain
))
2323 if (TREE_VALUE (method_chain
) == TREE_VALUE (chain
))
2330 warning ("%Jcreating selector for nonexistent method %qE",
2331 TREE_PURPOSE (chain
), TREE_VALUE (chain
));
2334 expr
= build_selector (TREE_VALUE (chain
));
2335 /* add one for the '\0' character */
2336 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (chain
)) + 1;
2338 if (flag_next_runtime
)
2340 decl
= TREE_PURPOSE (chain
);
2341 finish_var_decl (decl
, expr
);
2345 if (flag_typed_selectors
)
2347 tree eltlist
= NULL_TREE
;
2348 tree encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
2349 eltlist
= tree_cons (NULL_TREE
, expr
, NULL_TREE
);
2350 eltlist
= tree_cons (NULL_TREE
, encoding
, eltlist
);
2351 expr
= objc_build_constructor (objc_selector_template
,
2352 nreverse (eltlist
));
2355 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2359 if (! flag_next_runtime
)
2361 /* Cause the selector table (previously forward-declared)
2362 to be actually output. */
2363 initlist
= tree_cons (NULL_TREE
,
2364 flag_typed_selectors
2365 ? objc_build_constructor
2366 (objc_selector_template
,
2367 tree_cons (NULL_TREE
,
2368 build_int_cst (NULL_TREE
, 0),
2369 tree_cons (NULL_TREE
,
2370 build_int_cst (NULL_TREE
, 0),
2372 : build_int_cst (NULL_TREE
, 0), initlist
);
2373 initlist
= objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
2374 nreverse (initlist
));
2375 finish_var_decl (UOBJC_SELECTOR_TABLE_decl
, initlist
);
2380 get_proto_encoding (tree proto
)
2385 if (! METHOD_ENCODING (proto
))
2387 encoding
= encode_method_prototype (proto
);
2388 METHOD_ENCODING (proto
) = encoding
;
2391 encoding
= METHOD_ENCODING (proto
);
2393 return add_objc_string (encoding
, meth_var_types
);
2396 return build_int_cst (NULL_TREE
, 0);
2399 /* sel_ref_chain is a list whose "value" fields will be instances of
2400 identifier_node that represent the selector. */
2403 build_typed_selector_reference (tree ident
, tree prototype
)
2405 tree
*chain
= &sel_ref_chain
;
2411 if (TREE_PURPOSE (*chain
) == prototype
&& TREE_VALUE (*chain
) == ident
)
2412 goto return_at_index
;
2415 chain
= &TREE_CHAIN (*chain
);
2418 *chain
= tree_cons (prototype
, ident
, NULL_TREE
);
2421 expr
= build_unary_op (ADDR_EXPR
,
2422 build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2423 build_int_cst (NULL_TREE
, index
)),
2425 return convert (objc_selector_type
, expr
);
2429 build_selector_reference (tree ident
)
2431 tree
*chain
= &sel_ref_chain
;
2437 if (TREE_VALUE (*chain
) == ident
)
2438 return (flag_next_runtime
2439 ? TREE_PURPOSE (*chain
)
2440 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2441 build_int_cst (NULL_TREE
, index
)));
2444 chain
= &TREE_CHAIN (*chain
);
2447 expr
= (flag_next_runtime
? build_selector_reference_decl (): NULL_TREE
);
2449 *chain
= tree_cons (expr
, ident
, NULL_TREE
);
2451 return (flag_next_runtime
2453 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2454 build_int_cst (NULL_TREE
, index
)));
2457 static GTY(()) int class_reference_idx
;
2460 build_class_reference_decl (void)
2465 sprintf (buf
, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx
++);
2466 decl
= start_var_decl (objc_class_type
, buf
);
2471 /* Create a class reference, but don't create a variable to reference
2475 add_class_reference (tree ident
)
2479 if ((chain
= cls_ref_chain
))
2484 if (ident
== TREE_VALUE (chain
))
2488 chain
= TREE_CHAIN (chain
);
2492 /* Append to the end of the list */
2493 TREE_CHAIN (tail
) = tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2496 cls_ref_chain
= tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2499 /* Get a class reference, creating it if necessary. Also create the
2500 reference variable. */
2503 objc_get_class_reference (tree ident
)
2508 if (processing_template_decl
)
2509 /* Must wait until template instantiation time. */
2510 return build_min_nt (CLASS_REFERENCE_EXPR
, ident
);
2511 if (TREE_CODE (ident
) == TYPE_DECL
)
2512 ident
= DECL_NAME (ident
);
2516 if (!(ident
= objc_is_class_name (ident
)))
2518 error ("`%s' is not an Objective-C class name or alias",
2519 IDENTIFIER_POINTER (orig_ident
));
2520 return error_mark_node
;
2523 if (flag_next_runtime
&& !flag_zero_link
)
2528 for (chain
= &cls_ref_chain
; *chain
; chain
= &TREE_CHAIN (*chain
))
2529 if (TREE_VALUE (*chain
) == ident
)
2531 if (! TREE_PURPOSE (*chain
))
2532 TREE_PURPOSE (*chain
) = build_class_reference_decl ();
2534 return TREE_PURPOSE (*chain
);
2537 decl
= build_class_reference_decl ();
2538 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2545 add_class_reference (ident
);
2547 params
= build_tree_list (NULL_TREE
,
2548 my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
2549 IDENTIFIER_POINTER (ident
)));
2551 assemble_external (objc_get_class_decl
);
2552 return build_function_call (objc_get_class_decl
, params
);
2556 /* For each string section we have a chain which maps identifier nodes
2557 to decls for the strings. */
2560 add_objc_string (tree ident
, enum string_section section
)
2564 if (section
== class_names
)
2565 chain
= &class_names_chain
;
2566 else if (section
== meth_var_names
)
2567 chain
= &meth_var_names_chain
;
2568 else if (section
== meth_var_types
)
2569 chain
= &meth_var_types_chain
;
2575 if (TREE_VALUE (*chain
) == ident
)
2576 return convert (string_type_node
,
2577 build_unary_op (ADDR_EXPR
, TREE_PURPOSE (*chain
), 1));
2579 chain
= &TREE_CHAIN (*chain
);
2582 decl
= build_objc_string_decl (section
);
2584 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2586 return convert (string_type_node
, build_unary_op (ADDR_EXPR
, decl
, 1));
2589 static GTY(()) int class_names_idx
;
2590 static GTY(()) int meth_var_names_idx
;
2591 static GTY(()) int meth_var_types_idx
;
2594 build_objc_string_decl (enum string_section section
)
2599 if (section
== class_names
)
2600 sprintf (buf
, "_OBJC_CLASS_NAME_%d", class_names_idx
++);
2601 else if (section
== meth_var_names
)
2602 sprintf (buf
, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx
++);
2603 else if (section
== meth_var_types
)
2604 sprintf (buf
, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx
++);
2606 ident
= get_identifier (buf
);
2608 decl
= build_decl (VAR_DECL
, ident
, build_array_type (char_type_node
, 0));
2609 DECL_EXTERNAL (decl
) = 1;
2610 TREE_PUBLIC (decl
) = 0;
2611 TREE_USED (decl
) = 1;
2612 TREE_CONSTANT (decl
) = 1;
2613 DECL_CONTEXT (decl
) = 0;
2614 DECL_ARTIFICIAL (decl
) = 1;
2616 DECL_THIS_STATIC (decl
) = 1; /* squash redeclaration errors */
2619 make_decl_rtl (decl
);
2620 pushdecl_top_level (decl
);
2627 objc_declare_alias (tree alias_ident
, tree class_ident
)
2629 tree underlying_class
;
2632 if (current_namespace
!= global_namespace
) {
2633 error ("Objective-C declarations may only appear in global scope");
2635 #endif /* OBJCPLUS */
2637 if (!(underlying_class
= objc_is_class_name (class_ident
)))
2638 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident
));
2639 else if (objc_is_class_name (alias_ident
))
2640 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident
));
2642 alias_chain
= tree_cons (underlying_class
, alias_ident
, alias_chain
);
2646 objc_declare_class (tree ident_list
)
2650 if (current_namespace
!= global_namespace
) {
2651 error ("Objective-C declarations may only appear in global scope");
2653 #endif /* OBJCPLUS */
2655 for (list
= ident_list
; list
; list
= TREE_CHAIN (list
))
2657 tree ident
= TREE_VALUE (list
);
2659 if (! objc_is_class_name (ident
))
2661 tree record
= lookup_name (ident
);
2663 if (record
&& ! TREE_STATIC_TEMPLATE (record
))
2665 error ("`%s' redeclared as different kind of symbol",
2666 IDENTIFIER_POINTER (ident
));
2667 error ("%Jprevious declaration of '%D'",
2671 record
= xref_tag (RECORD_TYPE
, ident
);
2672 TREE_STATIC_TEMPLATE (record
) = 1;
2673 class_chain
= tree_cons (NULL_TREE
, ident
, class_chain
);
2679 objc_is_class_name (tree ident
)
2683 if (ident
&& TREE_CODE (ident
) == IDENTIFIER_NODE
2684 && identifier_global_value (ident
))
2685 ident
= identifier_global_value (ident
);
2686 while (ident
&& TREE_CODE (ident
) == TYPE_DECL
&& DECL_ORIGINAL_TYPE (ident
))
2687 ident
= OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident
));
2689 if (ident
&& TREE_CODE (ident
) == RECORD_TYPE
)
2690 ident
= OBJC_TYPE_NAME (ident
);
2692 if (ident
&& TREE_CODE (ident
) == TYPE_DECL
)
2693 ident
= DECL_NAME (ident
);
2695 if (!ident
|| TREE_CODE (ident
) != IDENTIFIER_NODE
)
2698 if (lookup_interface (ident
))
2701 for (chain
= class_chain
; chain
; chain
= TREE_CHAIN (chain
))
2703 if (ident
== TREE_VALUE (chain
))
2707 for (chain
= alias_chain
; chain
; chain
= TREE_CHAIN (chain
))
2709 if (ident
== TREE_VALUE (chain
))
2710 return TREE_PURPOSE (chain
);
2716 /* Check whether TYPE is either 'id' or 'Class'. */
2719 objc_is_id (tree type
)
2721 if (type
&& TREE_CODE (type
) == IDENTIFIER_NODE
2722 && identifier_global_value (type
))
2723 type
= identifier_global_value (type
);
2725 if (type
&& TREE_CODE (type
) == TYPE_DECL
)
2726 type
= TREE_TYPE (type
);
2728 /* NB: This function may be called before the ObjC front-end has
2729 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
2730 return (objc_object_type
&& type
2731 && (IS_ID (type
) || IS_CLASS (type
) || IS_SUPER (type
))
2736 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
2737 class instance. This is needed by other parts of the compiler to
2738 handle ObjC types gracefully. */
2741 objc_is_object_ptr (tree type
)
2745 type
= TYPE_MAIN_VARIANT (type
);
2746 if (!POINTER_TYPE_P (type
))
2749 ret
= objc_is_id (type
);
2751 ret
= objc_is_class_name (TREE_TYPE (type
));
2757 lookup_interface (tree ident
)
2762 if (ident
&& TREE_CODE (ident
) == TYPE_DECL
)
2763 ident
= DECL_NAME (ident
);
2765 for (chain
= interface_chain
; chain
; chain
= TREE_CHAIN (chain
))
2767 if (ident
== CLASS_NAME (chain
))
2773 /* Implement @defs (<classname>) within struct bodies. */
2776 objc_get_class_ivars (tree class_name
)
2778 tree interface
= lookup_interface (class_name
);
2781 return get_class_ivars (interface
);
2783 error ("cannot find interface declaration for `%s'",
2784 IDENTIFIER_POINTER (class_name
));
2786 return error_mark_node
;
2789 /* Used by: build_private_template, continue_class,
2790 and for @defs constructs. */
2793 get_class_ivars (tree interface
)
2795 tree ivar_chain
= copy_list (CLASS_RAW_IVARS (interface
));
2797 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
2798 by the current class (i.e., they do not include super-class ivars).
2799 However, the CLASS_IVARS list will be side-effected by a call to
2800 finish_struct(), which will fill in field offsets. */
2801 if (!CLASS_IVARS (interface
))
2802 CLASS_IVARS (interface
) = ivar_chain
;
2804 while (CLASS_SUPER_NAME (interface
))
2806 /* Prepend super-class ivars. */
2807 interface
= lookup_interface (CLASS_SUPER_NAME (interface
));
2808 ivar_chain
= chainon (copy_list (CLASS_RAW_IVARS (interface
)),
2816 objc_create_temporary_var (tree type
)
2820 decl
= build_decl (VAR_DECL
, NULL_TREE
, type
);
2821 TREE_USED (decl
) = 1;
2822 DECL_ARTIFICIAL (decl
) = 1;
2823 DECL_IGNORED_P (decl
) = 1;
2824 DECL_CONTEXT (decl
) = current_function_decl
;
2829 /* Exception handling constructs. We begin by having the parser do most
2830 of the work and passing us blocks. What we do next depends on whether
2831 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
2832 We abstract all of this in a handful of appropriately named routines. */
2834 /* Stack of open try blocks. */
2836 struct objc_try_context
2838 struct objc_try_context
*outer
;
2840 /* Statements (or statement lists) as processed by the parser. */
2844 /* Some file position locations. */
2845 location_t try_locus
;
2846 location_t end_try_locus
;
2847 location_t end_catch_locus
;
2848 location_t finally_locus
;
2849 location_t end_finally_locus
;
2851 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
2852 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
2855 /* The CATCH_EXPR of an open @catch clause. */
2858 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
2864 static struct objc_try_context
*cur_try_context
;
2866 /* This hook, called via lang_eh_runtime_type, generates a runtime object
2867 that represents TYPE. For Objective-C, this is just the class name. */
2868 /* ??? Isn't there a class object or some such? Is it easy to get? */
2872 objc_eh_runtime_type (tree type
)
2874 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type
)), class_names
);
2878 /* Initialize exception handling. */
2881 objc_init_exceptions (void)
2883 static bool done
= false;
2888 if (flag_objc_sjlj_exceptions
)
2890 /* On Darwin, ObjC exceptions require a sufficiently recent
2891 version of the runtime, so the user must ask for them explicitly. */
2892 if (!flag_objc_exceptions
)
2893 warning ("use %<-fobjc-exceptions%> to enable Objective-C "
2894 "exception syntax");
2899 c_eh_initialized_p
= true;
2900 eh_personality_libfunc
2901 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
2902 ? "__gnu_objc_personality_sj0"
2903 : "__gnu_objc_personality_v0");
2904 using_eh_for_cleanups ();
2905 lang_eh_runtime_type
= objc_eh_runtime_type
;
2910 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
2911 we'll arrange for it to be initialized (and associated with a binding)
2915 objc_build_exc_ptr (void)
2917 if (flag_objc_sjlj_exceptions
)
2919 tree var
= cur_try_context
->caught_decl
;
2922 var
= objc_create_temporary_var (objc_object_type
);
2923 cur_try_context
->caught_decl
= var
;
2928 return build (EXC_PTR_EXPR
, objc_object_type
);
2931 /* Build "objc_exception_try_exit(&_stack)". */
2934 next_sjlj_build_try_exit (void)
2937 t
= build_fold_addr_expr (cur_try_context
->stack_decl
);
2938 t
= tree_cons (NULL
, t
, NULL
);
2939 t
= build_function_call (objc_exception_try_exit_decl
, t
);
2944 objc_exception_try_enter (&_stack);
2945 if (_setjmp(&_stack.buf))
2949 Return the COND_EXPR. Note that the THEN and ELSE fields are left
2950 empty, ready for the caller to fill them in. */
2953 next_sjlj_build_enter_and_setjmp (void)
2955 tree t
, enter
, sj
, cond
;
2957 t
= build_fold_addr_expr (cur_try_context
->stack_decl
);
2958 t
= tree_cons (NULL
, t
, NULL
);
2959 enter
= build_function_call (objc_exception_try_enter_decl
, t
);
2961 t
= build_component_ref (cur_try_context
->stack_decl
,
2962 get_identifier ("buf"));
2963 t
= build_fold_addr_expr (t
);
2964 t
= convert (ptr_type_node
, t
);
2965 t
= tree_cons (NULL
, t
, NULL
);
2966 sj
= build_function_call (objc_setjmp_decl
, t
);
2968 cond
= build (COMPOUND_EXPR
, TREE_TYPE (sj
), enter
, sj
);
2969 cond
= lang_hooks
.truthvalue_conversion (cond
);
2971 return build (COND_EXPR
, void_type_node
, cond
, NULL
, NULL
);
2975 DECL = objc_exception_extract(&_stack);
2979 next_sjlj_build_exc_extract (tree decl
)
2983 t
= build_fold_addr_expr (cur_try_context
->stack_decl
);
2984 t
= tree_cons (NULL
, t
, NULL
);
2985 t
= build_function_call (objc_exception_extract_decl
, t
);
2986 t
= convert (TREE_TYPE (decl
), t
);
2987 t
= build (MODIFY_EXPR
, void_type_node
, decl
, t
);
2993 if (objc_exception_match(obj_get_class(TYPE), _caught)
3000 objc_exception_try_exit(&_stack);
3002 from the sequence of CATCH_EXPRs in the current try context. */
3005 next_sjlj_build_catch_list (void)
3007 tree_stmt_iterator i
= tsi_start (cur_try_context
->catch_list
);
3009 tree
*last
= &catch_seq
;
3010 bool saw_id
= false;
3012 for (; !tsi_end_p (i
); tsi_next (&i
))
3014 tree stmt
= tsi_stmt (i
);
3015 tree type
= CATCH_TYPES (stmt
);
3016 tree body
= CATCH_BODY (stmt
);
3028 if (type
== error_mark_node
)
3029 cond
= error_mark_node
;
3032 args
= tree_cons (NULL
, cur_try_context
->caught_decl
, NULL
);
3033 t
= objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type
)));
3034 args
= tree_cons (NULL
, t
, args
);
3035 t
= build_function_call (objc_exception_match_decl
, args
);
3036 cond
= lang_hooks
.truthvalue_conversion (t
);
3038 t
= build (COND_EXPR
, void_type_node
, cond
, body
, NULL
);
3039 SET_EXPR_LOCUS (t
, EXPR_LOCUS (stmt
));
3042 last
= &COND_EXPR_ELSE (t
);
3048 t
= build (MODIFY_EXPR
, void_type_node
, cur_try_context
->rethrow_decl
,
3049 cur_try_context
->caught_decl
);
3050 SET_EXPR_LOCATION (t
, cur_try_context
->end_catch_locus
);
3051 append_to_statement_list (t
, last
);
3053 t
= next_sjlj_build_try_exit ();
3054 SET_EXPR_LOCATION (t
, cur_try_context
->end_catch_locus
);
3055 append_to_statement_list (t
, last
);
3061 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
3062 exception handling. We aim to build:
3065 struct _objc_exception_data _stack;
3066 id volatile _rethrow = 0;
3069 objc_exception_try_enter (&_stack);
3070 if (_setjmp(&_stack.buf))
3072 id _caught = objc_exception_extract(&_stack);
3073 objc_exception_try_enter (&_stack);
3074 if (_setjmp(&_stack.buf))
3075 _rethrow = objc_exception_extract(&_stack);
3085 objc_exception_try_exit(&_stack);
3088 objc_exception_throw(_rethrow);
3092 If CATCH-LIST is empty, we can omit all of the block containing
3093 "_caught" except for the setting of _rethrow. Note the use of
3094 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
3095 but handles goto and other exits from the block. */
3098 next_sjlj_build_try_catch_finally (void)
3100 tree rethrow_decl
, stack_decl
, t
;
3101 tree catch_seq
, try_fin
, bind
;
3103 /* Create the declarations involved. */
3104 t
= xref_tag (RECORD_TYPE
, get_identifier (UTAG_EXCDATA
));
3105 stack_decl
= objc_create_temporary_var (t
);
3106 cur_try_context
->stack_decl
= stack_decl
;
3108 rethrow_decl
= objc_create_temporary_var (objc_object_type
);
3109 cur_try_context
->rethrow_decl
= rethrow_decl
;
3110 TREE_THIS_VOLATILE (rethrow_decl
) = 1;
3111 TREE_CHAIN (rethrow_decl
) = stack_decl
;
3113 /* Build the outermost variable binding level. */
3114 bind
= build (BIND_EXPR
, void_type_node
, rethrow_decl
, NULL
, NULL
);
3115 SET_EXPR_LOCATION (bind
, cur_try_context
->try_locus
);
3116 TREE_SIDE_EFFECTS (bind
) = 1;
3118 /* Initialize rethrow_decl. */
3119 t
= build (MODIFY_EXPR
, void_type_node
, rethrow_decl
,
3120 convert (objc_object_type
, null_pointer_node
));
3121 SET_EXPR_LOCATION (t
, cur_try_context
->try_locus
);
3122 append_to_statement_list (t
, &BIND_EXPR_BODY (bind
));
3124 /* Build the outermost TRY_FINALLY_EXPR. */
3125 try_fin
= build (TRY_FINALLY_EXPR
, void_type_node
, NULL
, NULL
);
3126 SET_EXPR_LOCATION (try_fin
, cur_try_context
->try_locus
);
3127 TREE_SIDE_EFFECTS (try_fin
) = 1;
3128 append_to_statement_list (try_fin
, &BIND_EXPR_BODY (bind
));
3130 /* Create the complete catch sequence. */
3131 if (cur_try_context
->catch_list
)
3133 tree caught_decl
= objc_build_exc_ptr ();
3134 catch_seq
= build_stmt (BIND_EXPR
, caught_decl
, NULL
, NULL
);
3136 t
= next_sjlj_build_exc_extract (caught_decl
);
3137 append_to_statement_list (t
, &BIND_EXPR_BODY (catch_seq
));
3139 t
= next_sjlj_build_enter_and_setjmp ();
3140 COND_EXPR_THEN (t
) = next_sjlj_build_exc_extract (rethrow_decl
);
3141 COND_EXPR_ELSE (t
) = next_sjlj_build_catch_list ();
3142 append_to_statement_list (t
, &BIND_EXPR_BODY (catch_seq
));
3145 catch_seq
= next_sjlj_build_exc_extract (rethrow_decl
);
3146 SET_EXPR_LOCATION (catch_seq
, cur_try_context
->end_try_locus
);
3148 /* Build the main register-and-try if statement. */
3149 t
= next_sjlj_build_enter_and_setjmp ();
3150 SET_EXPR_LOCATION (t
, cur_try_context
->try_locus
);
3151 COND_EXPR_THEN (t
) = catch_seq
;
3152 COND_EXPR_ELSE (t
) = cur_try_context
->try_body
;
3153 TREE_OPERAND (try_fin
, 0) = t
;
3155 /* Build the complete FINALLY statement list. */
3156 t
= next_sjlj_build_try_exit ();
3157 t
= build_stmt (COND_EXPR
,
3158 lang_hooks
.truthvalue_conversion (rethrow_decl
),
3160 SET_EXPR_LOCATION (t
, cur_try_context
->finally_locus
);
3161 append_to_statement_list (t
, &TREE_OPERAND (try_fin
, 1));
3163 append_to_statement_list (cur_try_context
->finally_body
,
3164 &TREE_OPERAND (try_fin
, 1));
3166 t
= tree_cons (NULL
, rethrow_decl
, NULL
);
3167 t
= build_function_call (objc_exception_throw_decl
, t
);
3168 t
= build_stmt (COND_EXPR
,
3169 lang_hooks
.truthvalue_conversion (rethrow_decl
),
3171 SET_EXPR_LOCATION (t
, cur_try_context
->end_finally_locus
);
3172 append_to_statement_list (t
, &TREE_OPERAND (try_fin
, 1));
3177 /* Called just after parsing the @try and its associated BODY. We now
3178 must prepare for the tricky bits -- handling the catches and finally. */
3181 objc_begin_try_stmt (location_t try_locus
, tree body
)
3183 struct objc_try_context
*c
= xcalloc (1, sizeof (*c
));
3184 c
->outer
= cur_try_context
;
3186 c
->try_locus
= try_locus
;
3187 c
->end_try_locus
= input_location
;
3188 cur_try_context
= c
;
3190 objc_init_exceptions ();
3193 /* Called just after parsing "@catch (parm)". Open a binding level,
3194 enter DECL into the binding level, and initialize it. Leave the
3195 binding level open while the body of the compound statement is parsed. */
3198 objc_begin_catch_clause (tree decl
)
3200 tree compound
, type
, t
;
3202 /* Begin a new scope that the entire catch clause will live in. */
3203 compound
= c_begin_compound_stmt (true);
3205 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
3206 decl
= build_decl (VAR_DECL
, DECL_NAME (decl
), TREE_TYPE (decl
));
3207 lang_hooks
.decls
.pushdecl (decl
);
3209 /* Since a decl is required here by syntax, don't warn if its unused. */
3210 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3211 be what the previous objc implementation did. */
3212 TREE_USED (decl
) = 1;
3214 /* Verify that the type of the catch is valid. It must be a pointer
3215 to an Objective-C class, or "id" (which is catch-all). */
3216 type
= TREE_TYPE (decl
);
3218 if (POINTER_TYPE_P (type
) && objc_is_object_id (TREE_TYPE (type
)))
3220 else if (!POINTER_TYPE_P (type
) || !TYPED_OBJECT (TREE_TYPE (type
)))
3222 error ("@catch parameter is not a known Objective-C class type");
3223 type
= error_mark_node
;
3225 else if (cur_try_context
->catch_list
)
3227 /* Examine previous @catch clauses and see if we've already
3228 caught the type in question. */
3229 tree_stmt_iterator i
= tsi_start (cur_try_context
->catch_list
);
3230 for (; !tsi_end_p (i
); tsi_next (&i
))
3232 tree stmt
= tsi_stmt (i
);
3233 t
= CATCH_TYPES (stmt
);
3234 if (t
== error_mark_node
)
3236 if (!t
|| objc_comptypes (TREE_TYPE (t
), TREE_TYPE (type
), 0) == 1)
3238 warning ("exception of type %<%T%> will be caught",
3240 warning ("%H by earlier handler for %<%T%>",
3241 EXPR_LOCUS (stmt
), TREE_TYPE (t
? t
: objc_object_type
));
3247 /* Record the data for the catch in the try context so that we can
3248 finalize it later. */
3249 t
= build_stmt (CATCH_EXPR
, type
, compound
);
3250 cur_try_context
->current_catch
= t
;
3252 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3253 t
= objc_build_exc_ptr ();
3254 t
= convert (TREE_TYPE (decl
), t
);
3255 t
= build (MODIFY_EXPR
, void_type_node
, decl
, t
);
3259 /* Called just after parsing the closing brace of a @catch clause. Close
3260 the open binding level, and record a CATCH_EXPR for it. */
3263 objc_finish_catch_clause (void)
3265 tree c
= cur_try_context
->current_catch
;
3266 cur_try_context
->current_catch
= NULL
;
3267 cur_try_context
->end_catch_locus
= input_location
;
3269 CATCH_BODY (c
) = c_end_compound_stmt (CATCH_BODY (c
), 1);
3270 append_to_statement_list (c
, &cur_try_context
->catch_list
);
3273 /* Called after parsing a @finally clause and its associated BODY.
3274 Record the body for later placement. */
3277 objc_build_finally_clause (location_t finally_locus
, tree body
)
3279 cur_try_context
->finally_body
= body
;
3280 cur_try_context
->finally_locus
= finally_locus
;
3281 cur_try_context
->end_finally_locus
= input_location
;
3284 /* Called to finalize a @try construct. */
3287 objc_finish_try_stmt (void)
3289 struct objc_try_context
*c
= cur_try_context
;
3292 if (c
->catch_list
== NULL
&& c
->finally_body
== NULL
)
3293 error ("`@try' without `@catch' or `@finally'");
3295 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3296 if (flag_objc_sjlj_exceptions
)
3298 if (!cur_try_context
->finally_body
)
3300 cur_try_context
->finally_locus
= input_location
;
3301 cur_try_context
->end_finally_locus
= input_location
;
3303 stmt
= next_sjlj_build_try_catch_finally ();
3307 /* Otherwise, nest the CATCH inside a FINALLY. */
3311 stmt
= build_stmt (TRY_CATCH_EXPR
, stmt
, c
->catch_list
);
3312 SET_EXPR_LOCATION (stmt
, cur_try_context
->try_locus
);
3314 if (c
->finally_body
)
3316 stmt
= build_stmt (TRY_FINALLY_EXPR
, stmt
, c
->finally_body
);
3317 SET_EXPR_LOCATION (stmt
, cur_try_context
->try_locus
);
3322 cur_try_context
= c
->outer
;
3327 objc_build_throw_stmt (tree throw_expr
)
3331 objc_init_exceptions ();
3333 if (throw_expr
== NULL
)
3335 /* If we're not inside a @catch block, there is no "current
3336 exception" to be rethrown. */
3337 if (cur_try_context
== NULL
3338 || cur_try_context
->current_catch
== NULL
)
3340 error ("%<@throw%> (rethrow) used outside of a @catch block");
3344 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3345 value that we get from the runtime. */
3346 throw_expr
= objc_build_exc_ptr ();
3349 /* A throw is just a call to the runtime throw function with the
3350 object as a parameter. */
3351 args
= tree_cons (NULL
, throw_expr
, NULL
);
3352 return add_stmt (build_function_call (objc_exception_throw_decl
, args
));
3356 objc_build_synchronized (location_t start_locus
, tree mutex
, tree body
)
3360 /* First lock the mutex. */
3361 mutex
= save_expr (mutex
);
3362 args
= tree_cons (NULL
, mutex
, NULL
);
3363 call
= build_function_call (objc_sync_enter_decl
, args
);
3364 SET_EXPR_LOCATION (call
, start_locus
);
3367 /* Build the mutex unlock. */
3368 args
= tree_cons (NULL
, mutex
, NULL
);
3369 call
= build_function_call (objc_sync_exit_decl
, args
);
3370 SET_EXPR_LOCATION (call
, input_location
);
3372 /* Put the that and the body in a TRY_FINALLY. */
3373 objc_begin_try_stmt (start_locus
, body
);
3374 objc_build_finally_clause (input_location
, call
);
3375 objc_finish_try_stmt ();
3379 /* Predefine the following data type:
3381 struct _objc_exception_data
3387 /* The following yuckiness should prevent users from having to #include
3388 <setjmp.h> in their code... */
3390 #ifdef TARGET_POWERPC
3391 /* snarfed from /usr/include/ppc/setjmp.h */
3392 #define _JBLEN (26 + 36 + 129 + 1)
3394 /* snarfed from /usr/include/i386/{setjmp,signal}.h */
3399 build_next_objc_exception_stuff (void)
3401 tree field_decl
, field_decl_chain
, index
, temp_type
;
3403 objc_exception_data_template
3404 = start_struct (RECORD_TYPE
, get_identifier (UTAG_EXCDATA
));
3406 /* int buf[_JBLEN]; */
3408 index
= build_index_type (build_int_cst (NULL_TREE
, _JBLEN
- 1));
3409 field_decl
= create_field_decl (build_array_type (integer_type_node
, index
),
3411 field_decl_chain
= field_decl
;
3413 /* void *pointers[4]; */
3415 index
= build_index_type (build_int_cst (NULL_TREE
, 4 - 1));
3416 field_decl
= create_field_decl (build_array_type (ptr_type_node
, index
),
3418 chainon (field_decl_chain
, field_decl
);
3420 finish_struct (objc_exception_data_template
, field_decl_chain
, NULL_TREE
);
3422 /* int _setjmp(...); */
3423 /* If the user includes <setjmp.h>, this shall be superseded by
3424 'int _setjmp(jmp_buf);' */
3425 temp_type
= build_function_type (integer_type_node
, NULL_TREE
);
3427 = builtin_function (TAG_SETJMP
, temp_type
, 0, NOT_BUILT_IN
, NULL
, NULL_TREE
);
3429 /* id objc_exception_extract(struct _objc_exception_data *); */
3431 = build_function_type (objc_object_type
,
3432 tree_cons (NULL_TREE
,
3433 build_pointer_type (objc_exception_data_template
),
3435 objc_exception_extract_decl
3436 = builtin_function (TAG_EXCEPTIONEXTRACT
, temp_type
, 0, NOT_BUILT_IN
, NULL
, NULL_TREE
);
3437 /* void objc_exception_try_enter(struct _objc_exception_data *); */
3438 /* void objc_exception_try_exit(struct _objc_exception_data *); */
3440 = build_function_type (void_type_node
,
3441 tree_cons (NULL_TREE
,
3442 build_pointer_type (objc_exception_data_template
),
3444 objc_exception_try_enter_decl
3445 = builtin_function (TAG_EXCEPTIONTRYENTER
, temp_type
, 0, NOT_BUILT_IN
, NULL
, NULL_TREE
);
3446 objc_exception_try_exit_decl
3447 = builtin_function (TAG_EXCEPTIONTRYEXIT
, temp_type
, 0, NOT_BUILT_IN
, NULL
, NULL_TREE
);
3449 /* int objc_exception_match(id, id); */
3451 = build_function_type (integer_type_node
,
3452 tree_cons (NULL_TREE
, objc_object_type
,
3453 tree_cons (NULL_TREE
, objc_object_type
,
3454 OBJC_VOID_AT_END
)));
3455 objc_exception_match_decl
3456 = builtin_function (TAG_EXCEPTIONMATCH
, temp_type
, 0, NOT_BUILT_IN
, NULL
, NULL_TREE
);
3460 build_objc_exception_stuff (void)
3462 tree noreturn_list
, nothrow_list
, temp_type
;
3464 noreturn_list
= tree_cons (get_identifier ("noreturn"), NULL
, NULL
);
3465 nothrow_list
= tree_cons (get_identifier ("nothrow"), NULL
, NULL
);
3467 /* void objc_exception_throw(id) __attribute__((noreturn)); */
3468 /* void objc_sync_enter(id); */
3469 /* void objc_sync_exit(id); */
3470 temp_type
= build_function_type (void_type_node
,
3471 tree_cons (NULL_TREE
, objc_object_type
,
3473 objc_exception_throw_decl
3474 = builtin_function (TAG_EXCEPTIONTHROW
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
3476 objc_sync_enter_decl
3477 = builtin_function (TAG_SYNCENTER
, temp_type
, 0, NOT_BUILT_IN
,
3478 NULL
, nothrow_list
);
3480 = builtin_function (TAG_SYNCEXIT
, temp_type
, 0, NOT_BUILT_IN
,
3481 NULL
, nothrow_list
);
3485 /* struct <classname> {
3486 struct _objc_class *isa;
3491 build_private_template (tree
class)
3495 if (CLASS_STATIC_TEMPLATE (class))
3497 uprivate_record
= CLASS_STATIC_TEMPLATE (class);
3498 ivar_context
= TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
3502 uprivate_record
= start_struct (RECORD_TYPE
, CLASS_NAME (class));
3503 ivar_context
= get_class_ivars (class);
3505 finish_struct (uprivate_record
, ivar_context
, NULL_TREE
);
3507 CLASS_STATIC_TEMPLATE (class) = uprivate_record
;
3509 /* mark this record as class template - for class type checking */
3510 TREE_STATIC_TEMPLATE (uprivate_record
) = 1;
3513 objc_instance_type
= build_pointer_type (uprivate_record
);
3515 return ivar_context
;
3518 /* Begin code generation for protocols... */
3520 /* struct _objc_protocol {
3521 struct _objc_class *isa;
3522 char *protocol_name;
3523 struct _objc_protocol **protocol_list;
3524 struct _objc__method_prototype_list *instance_methods;
3525 struct _objc__method_prototype_list *class_methods;
3529 build_protocol_template (void)
3531 tree field_decl
, field_decl_chain
;
3533 objc_protocol_template
= start_struct (RECORD_TYPE
,
3534 get_identifier (UTAG_PROTOCOL
));
3536 /* struct _objc_class *isa; */
3537 field_decl
= create_field_decl (build_pointer_type
3538 (xref_tag (RECORD_TYPE
,
3539 get_identifier (UTAG_CLASS
))),
3541 field_decl_chain
= field_decl
;
3543 /* char *protocol_name; */
3544 field_decl
= create_field_decl (string_type_node
, "protocol_name");
3545 chainon (field_decl_chain
, field_decl
);
3547 /* struct _objc_protocol **protocol_list; */
3548 field_decl
= create_field_decl (build_pointer_type
3550 (objc_protocol_template
)),
3552 chainon (field_decl_chain
, field_decl
);
3554 /* struct objc_method_list *instance_methods; */
3555 field_decl
= create_field_decl (build_pointer_type
3556 (xref_tag (RECORD_TYPE
,
3558 (UTAG_METHOD_PROTOTYPE_LIST
))),
3559 "instance_methods");
3560 chainon (field_decl_chain
, field_decl
);
3562 /* struct objc_method_list *class_methods; */
3563 field_decl
= create_field_decl (build_pointer_type
3564 (xref_tag (RECORD_TYPE
,
3566 (UTAG_METHOD_PROTOTYPE_LIST
))),
3568 chainon (field_decl_chain
, field_decl
);
3570 finish_struct (objc_protocol_template
, field_decl_chain
, NULL_TREE
);
3574 build_descriptor_table_initializer (tree type
, tree entries
)
3576 tree initlist
= NULL_TREE
;
3580 tree eltlist
= NULL_TREE
;
3583 = tree_cons (NULL_TREE
,
3584 build_selector (METHOD_SEL_NAME (entries
)), NULL_TREE
);
3586 = tree_cons (NULL_TREE
,
3587 add_objc_string (METHOD_ENCODING (entries
),
3592 = tree_cons (NULL_TREE
,
3593 objc_build_constructor (type
, nreverse (eltlist
)),
3596 entries
= TREE_CHAIN (entries
);
3600 return objc_build_constructor (build_array_type (type
, 0),
3601 nreverse (initlist
));
3604 /* struct objc_method_prototype_list {
3606 struct objc_method_prototype {
3613 build_method_prototype_list_template (tree list_type
, int size
)
3615 tree objc_ivar_list_record
;
3616 tree field_decl
, field_decl_chain
;
3618 /* Generate an unnamed struct definition. */
3620 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3622 /* int method_count; */
3623 field_decl
= create_field_decl (integer_type_node
, "method_count");
3624 field_decl_chain
= field_decl
;
3626 /* struct objc_method method_list[]; */
3627 field_decl
= create_field_decl (build_array_type
3630 (build_int_cst (NULL_TREE
, size
- 1))),
3632 chainon (field_decl_chain
, field_decl
);
3634 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3636 return objc_ivar_list_record
;
3640 build_method_prototype_template (void)
3643 tree field_decl
, field_decl_chain
;
3646 = start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD_PROTOTYPE
));
3649 field_decl
= create_field_decl (objc_selector_type
, "_cmd");
3650 field_decl_chain
= field_decl
;
3652 /* char *method_types; */
3653 field_decl
= create_field_decl (string_type_node
, "method_types");
3654 chainon (field_decl_chain
, field_decl
);
3656 finish_struct (proto_record
, field_decl_chain
, NULL_TREE
);
3658 return proto_record
;
3662 objc_method_parm_type (tree type
)
3664 type
= TREE_VALUE (TREE_TYPE (type
));
3665 if (TREE_CODE (type
) == TYPE_DECL
)
3666 type
= TREE_TYPE (type
);
3667 return TYPE_MAIN_VARIANT (type
);
3671 objc_encoded_type_size (tree type
)
3673 int sz
= int_size_in_bytes (type
);
3675 /* Make all integer and enum types at least as large
3677 if (sz
> 0 && INTEGRAL_TYPE_P (type
))
3678 sz
= MAX (sz
, int_size_in_bytes (integer_type_node
));
3679 /* Treat arrays as pointers, since that's how they're
3681 else if (TREE_CODE (type
) == ARRAY_TYPE
)
3682 sz
= int_size_in_bytes (ptr_type_node
);
3687 encode_method_prototype (tree method_decl
)
3694 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
3695 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl
)));
3697 /* Encode return type. */
3698 encode_type (objc_method_parm_type (method_decl
),
3699 obstack_object_size (&util_obstack
),
3700 OBJC_ENCODE_INLINE_DEFS
);
3703 /* The first two arguments (self and _cmd) are pointers; account for
3705 i
= int_size_in_bytes (ptr_type_node
);
3706 parm_offset
= 2 * i
;
3707 for (parms
= METHOD_SEL_ARGS (method_decl
); parms
;
3708 parms
= TREE_CHAIN (parms
))
3710 tree type
= objc_method_parm_type (parms
);
3711 int sz
= objc_encoded_type_size (type
);
3713 /* If a type size is not known, bail out. */
3716 error ("%Jtype '%D' does not have a known size",
3718 /* Pretend that the encoding succeeded; the compilation will
3719 fail nevertheless. */
3720 goto finish_encoding
;
3725 sprintf (buf
, "%d@0:%d", parm_offset
, i
);
3726 obstack_grow (&util_obstack
, buf
, strlen (buf
));
3728 /* Argument types. */
3729 parm_offset
= 2 * i
;
3730 for (parms
= METHOD_SEL_ARGS (method_decl
); parms
;
3731 parms
= TREE_CHAIN (parms
))
3733 tree type
= objc_method_parm_type (parms
);
3735 /* Process argument qualifiers for user supplied arguments. */
3736 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms
)));
3739 encode_type (type
, obstack_object_size (&util_obstack
),
3740 OBJC_ENCODE_INLINE_DEFS
);
3742 /* Compute offset. */
3743 sprintf (buf
, "%d", parm_offset
);
3744 parm_offset
+= objc_encoded_type_size (type
);
3746 obstack_grow (&util_obstack
, buf
, strlen (buf
));
3750 obstack_1grow (&util_obstack
, '\0');
3751 result
= get_identifier (obstack_finish (&util_obstack
));
3752 obstack_free (&util_obstack
, util_firstobj
);
3757 generate_descriptor_table (tree type
, const char *name
, int size
, tree list
,
3760 tree decl
, initlist
;
3762 decl
= start_var_decl (type
, synth_id_with_class_suffix (name
, proto
));
3764 initlist
= build_tree_list (NULL_TREE
, build_int_cst (NULL_TREE
, size
));
3765 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3767 finish_var_decl (decl
, objc_build_constructor (type
, nreverse (initlist
)));
3773 generate_method_descriptors (tree protocol
)
3775 tree initlist
, chain
, method_list_template
;
3776 tree variable_length_type
3777 = xref_tag (RECORD_TYPE
,
3778 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
));
3781 if (!objc_method_prototype_template
)
3782 objc_method_prototype_template
= build_method_prototype_template ();
3784 chain
= PROTOCOL_CLS_METHODS (protocol
);
3787 size
= list_length (chain
);
3789 method_list_template
3790 = build_method_prototype_list_template (objc_method_prototype_template
,
3794 = build_descriptor_table_initializer (objc_method_prototype_template
,
3797 UOBJC_CLASS_METHODS_decl
3798 = generate_descriptor_table (method_list_template
,
3799 "_OBJC_PROTOCOL_CLASS_METHODS",
3800 size
, initlist
, protocol
);
3801 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
3804 UOBJC_CLASS_METHODS_decl
= 0;
3806 chain
= PROTOCOL_NST_METHODS (protocol
);
3809 size
= list_length (chain
);
3811 method_list_template
3812 = build_method_prototype_list_template (objc_method_prototype_template
,
3815 = build_descriptor_table_initializer (objc_method_prototype_template
,
3818 UOBJC_INSTANCE_METHODS_decl
3819 = generate_descriptor_table (method_list_template
,
3820 "_OBJC_PROTOCOL_INSTANCE_METHODS",
3821 size
, initlist
, protocol
);
3822 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
3825 UOBJC_INSTANCE_METHODS_decl
= 0;
3829 generate_protocol_references (tree plist
)
3833 /* Forward declare protocols referenced. */
3834 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
3836 tree proto
= TREE_VALUE (lproto
);
3838 if (TREE_CODE (proto
) == PROTOCOL_INTERFACE_TYPE
3839 && PROTOCOL_NAME (proto
))
3841 if (! PROTOCOL_FORWARD_DECL (proto
))
3842 build_protocol_reference (proto
);
3844 if (PROTOCOL_LIST (proto
))
3845 generate_protocol_references (PROTOCOL_LIST (proto
));
3850 /* For each protocol which was referenced either from a @protocol()
3851 expression, or because a class/category implements it (then a
3852 pointer to the protocol is stored in the struct describing the
3853 class/category), we create a statically allocated instance of the
3854 Protocol class. The code is written in such a way as to generate
3855 as few Protocol objects as possible; we generate a unique Protocol
3856 instance for each protocol, and we don't generate a Protocol
3857 instance if the protocol is never referenced (either from a
3858 @protocol() or from a class/category implementation). These
3859 statically allocated objects can be referred to via the static
3860 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
3862 The statically allocated Protocol objects that we generate here
3863 need to be fixed up at runtime in order to be used: the 'isa'
3864 pointer of the objects need to be set up to point to the 'Protocol'
3865 class, as known at runtime.
3867 The NeXT runtime fixes up all protocols at program startup time,
3868 before main() is entered. It uses a low-level trick to look up all
3869 those symbols, then loops on them and fixes them up.
3871 The GNU runtime as well fixes up all protocols before user code
3872 from the module is executed; it requires pointers to those symbols
3873 to be put in the objc_symtab (which is then passed as argument to
3874 the function __objc_exec_class() which the compiler sets up to be
3875 executed automatically when the module is loaded); setup of those
3876 Protocol objects happen in two ways in the GNU runtime: all
3877 Protocol objects referred to by a class or category implementation
3878 are fixed up when the class/category is loaded; all Protocol
3879 objects referred to by a @protocol() expression are added by the
3880 compiler to the list of statically allocated instances to fixup
3881 (the same list holding the statically allocated constant string
3882 objects). Because, as explained above, the compiler generates as
3883 few Protocol objects as possible, some Protocol object might end up
3884 being referenced multiple times when compiled with the GNU runtime,
3885 and end up being fixed up multiple times at runtime initialization.
3886 But that doesn't hurt, it's just a little inefficient. */
3889 generate_protocols (void)
3893 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
3895 /* If a protocol was directly referenced, pull in indirect references. */
3896 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3897 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
3898 generate_protocol_references (PROTOCOL_LIST (p
));
3900 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3902 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
3903 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
3905 /* If protocol wasn't referenced, don't generate any code. */
3906 decl
= PROTOCOL_FORWARD_DECL (p
);
3911 /* Make sure we link in the Protocol class. */
3912 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
3916 if (! METHOD_ENCODING (nst_methods
))
3918 encoding
= encode_method_prototype (nst_methods
);
3919 METHOD_ENCODING (nst_methods
) = encoding
;
3921 nst_methods
= TREE_CHAIN (nst_methods
);
3926 if (! METHOD_ENCODING (cls_methods
))
3928 encoding
= encode_method_prototype (cls_methods
);
3929 METHOD_ENCODING (cls_methods
) = encoding
;
3932 cls_methods
= TREE_CHAIN (cls_methods
);
3934 generate_method_descriptors (p
);
3936 if (PROTOCOL_LIST (p
))
3937 refs_decl
= generate_protocol_list (p
);
3941 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3942 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
3945 refs_expr
= convert (build_pointer_type (build_pointer_type
3946 (objc_protocol_template
)),
3947 build_unary_op (ADDR_EXPR
, refs_decl
, 0));
3949 refs_expr
= build_int_cst (NULL_TREE
, 0);
3951 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3952 by generate_method_descriptors, which is called above. */
3953 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
3954 protocol_name_expr
, refs_expr
,
3955 UOBJC_INSTANCE_METHODS_decl
,
3956 UOBJC_CLASS_METHODS_decl
);
3957 finish_var_decl (decl
, initlist
);
3962 build_protocol_initializer (tree type
, tree protocol_name
,
3963 tree protocol_list
, tree instance_methods
,
3966 tree initlist
= NULL_TREE
, expr
;
3967 tree cast_type
= build_pointer_type
3968 (xref_tag (RECORD_TYPE
,
3969 get_identifier (UTAG_CLASS
)));
3971 /* Filling the "isa" in with one allows the runtime system to
3972 detect that the version change...should remove before final release. */
3974 expr
= build_int_cst (cast_type
, PROTOCOL_VERSION
);
3975 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3976 initlist
= tree_cons (NULL_TREE
, protocol_name
, initlist
);
3977 initlist
= tree_cons (NULL_TREE
, protocol_list
, initlist
);
3979 if (!instance_methods
)
3980 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
3983 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
3984 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3988 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
3991 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
3992 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3995 return objc_build_constructor (type
, nreverse (initlist
));
3998 /* struct _objc_category {
3999 char *category_name;
4001 struct _objc_method_list *instance_methods;
4002 struct _objc_method_list *class_methods;
4003 struct _objc_protocol_list *protocols;
4007 build_category_template (void)
4009 tree field_decl
, field_decl_chain
;
4011 objc_category_template
= start_struct (RECORD_TYPE
,
4012 get_identifier (UTAG_CATEGORY
));
4014 /* char *category_name; */
4015 field_decl
= create_field_decl (string_type_node
, "category_name");
4016 field_decl_chain
= field_decl
;
4018 /* char *class_name; */
4019 field_decl
= create_field_decl (string_type_node
, "class_name");
4020 chainon (field_decl_chain
, field_decl
);
4022 /* struct _objc_method_list *instance_methods; */
4023 field_decl
= create_field_decl (build_pointer_type
4024 (xref_tag (RECORD_TYPE
,
4026 (UTAG_METHOD_LIST
))),
4027 "instance_methods");
4028 chainon (field_decl_chain
, field_decl
);
4030 /* struct _objc_method_list *class_methods; */
4031 field_decl
= create_field_decl (build_pointer_type
4032 (xref_tag (RECORD_TYPE
,
4034 (UTAG_METHOD_LIST
))),
4036 chainon (field_decl_chain
, field_decl
);
4038 /* struct _objc_protocol **protocol_list; */
4039 field_decl
= create_field_decl (build_pointer_type
4041 (objc_protocol_template
)),
4043 chainon (field_decl_chain
, field_decl
);
4045 finish_struct (objc_category_template
, field_decl_chain
, NULL_TREE
);
4048 /* struct _objc_selector {
4054 build_selector_template (void)
4057 tree field_decl
, field_decl_chain
;
4059 objc_selector_template
4060 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SELECTOR
));
4063 field_decl
= create_field_decl (objc_selector_type
, "sel_id");
4064 field_decl_chain
= field_decl
;
4066 /* char *sel_type; */
4067 field_decl
= create_field_decl (string_type_node
, "sel_type");
4068 chainon (field_decl_chain
, field_decl
);
4070 finish_struct (objc_selector_template
, field_decl_chain
, NULL_TREE
);
4073 /* struct _objc_class {
4074 struct _objc_class *isa;
4075 struct _objc_class *super_class;
4080 struct _objc_ivar_list *ivars;
4081 struct _objc_method_list *methods;
4082 #ifdef __NEXT_RUNTIME__
4083 struct objc_cache *cache;
4085 struct sarray *dtable;
4086 struct _objc_class *subclass_list;
4087 struct _objc_class *sibling_class;
4089 struct _objc_protocol_list *protocols;
4090 #ifdef __NEXT_RUNTIME__
4093 void *gc_object_type;
4096 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4097 the NeXT/Apple runtime; still, the compiler must generate them to
4098 maintain backward binary compatibility (and to allow for future
4102 build_class_template (void)
4104 tree field_decl
, field_decl_chain
;
4107 = start_struct (RECORD_TYPE
, get_identifier (UTAG_CLASS
));
4109 /* struct _objc_class *isa; */
4110 field_decl
= create_field_decl (build_pointer_type (objc_class_template
),
4112 field_decl_chain
= field_decl
;
4114 /* struct _objc_class *super_class; */
4115 field_decl
= create_field_decl (build_pointer_type (objc_class_template
),
4117 chainon (field_decl_chain
, field_decl
);
4120 field_decl
= create_field_decl (string_type_node
, "name");
4121 chainon (field_decl_chain
, field_decl
);
4124 field_decl
= create_field_decl (long_integer_type_node
, "version");
4125 chainon (field_decl_chain
, field_decl
);
4128 field_decl
= create_field_decl (long_integer_type_node
, "info");
4129 chainon (field_decl_chain
, field_decl
);
4131 /* long instance_size; */
4132 field_decl
= create_field_decl (long_integer_type_node
, "instance_size");
4133 chainon (field_decl_chain
, field_decl
);
4135 /* struct _objc_ivar_list *ivars; */
4136 field_decl
= create_field_decl (build_pointer_type
4137 (xref_tag (RECORD_TYPE
,
4141 chainon (field_decl_chain
, field_decl
);
4143 /* struct _objc_method_list *methods; */
4144 field_decl
= create_field_decl (build_pointer_type
4145 (xref_tag (RECORD_TYPE
,
4147 (UTAG_METHOD_LIST
))),
4149 chainon (field_decl_chain
, field_decl
);
4151 if (flag_next_runtime
)
4153 /* struct objc_cache *cache; */
4154 field_decl
= create_field_decl (build_pointer_type
4155 (xref_tag (RECORD_TYPE
,
4159 chainon (field_decl_chain
, field_decl
);
4163 /* struct sarray *dtable; */
4164 field_decl
= create_field_decl (build_pointer_type
4165 (xref_tag (RECORD_TYPE
,
4169 chainon (field_decl_chain
, field_decl
);
4171 /* struct objc_class *subclass_list; */
4172 field_decl
= create_field_decl (build_pointer_type
4173 (objc_class_template
),
4175 chainon (field_decl_chain
, field_decl
);
4177 /* struct objc_class *sibling_class; */
4178 field_decl
= create_field_decl (build_pointer_type
4179 (objc_class_template
),
4181 chainon (field_decl_chain
, field_decl
);
4184 /* struct _objc_protocol **protocol_list; */
4185 field_decl
= create_field_decl (build_pointer_type
4187 (xref_tag (RECORD_TYPE
,
4191 chainon (field_decl_chain
, field_decl
);
4193 if (flag_next_runtime
)
4196 field_decl
= create_field_decl (build_pointer_type (void_type_node
),
4198 chainon (field_decl_chain
, field_decl
);
4201 /* void *gc_object_type; */
4202 field_decl
= create_field_decl (build_pointer_type (void_type_node
),
4204 chainon (field_decl_chain
, field_decl
);
4206 finish_struct (objc_class_template
, field_decl_chain
, NULL_TREE
);
4209 /* Generate appropriate forward declarations for an implementation. */
4212 synth_forward_declarations (void)
4216 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4217 UOBJC_CLASS_decl
= build_metadata_decl ("_OBJC_CLASS",
4218 objc_class_template
);
4220 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4221 UOBJC_METACLASS_decl
= build_metadata_decl ("_OBJC_METACLASS",
4222 objc_class_template
);
4224 /* Pre-build the following entities - for speed/convenience. */
4226 an_id
= get_identifier ("super_class");
4227 ucls_super_ref
= build_component_ref (UOBJC_CLASS_decl
, an_id
);
4228 uucls_super_ref
= build_component_ref (UOBJC_METACLASS_decl
, an_id
);
4232 error_with_ivar (const char *message
, tree decl
)
4234 error ("%J%s `%s'", decl
,
4235 message
, gen_declaration (decl
));
4240 check_ivars (tree inter
, tree imp
)
4242 tree intdecls
= CLASS_RAW_IVARS (inter
);
4243 tree impdecls
= CLASS_RAW_IVARS (imp
);
4250 if (intdecls
&& TREE_CODE (intdecls
) == TYPE_DECL
)
4251 intdecls
= TREE_CHAIN (intdecls
);
4253 if (intdecls
== 0 && impdecls
== 0)
4255 if (intdecls
== 0 || impdecls
== 0)
4257 error ("inconsistent instance variable specification");
4261 t1
= TREE_TYPE (intdecls
); t2
= TREE_TYPE (impdecls
);
4263 if (!comptypes (t1
, t2
)
4264 || !tree_int_cst_equal (DECL_INITIAL (intdecls
),
4265 DECL_INITIAL (impdecls
)))
4267 if (DECL_NAME (intdecls
) == DECL_NAME (impdecls
))
4269 error_with_ivar ("conflicting instance variable type",
4271 error_with_ivar ("previous declaration of",
4274 else /* both the type and the name don't match */
4276 error ("inconsistent instance variable specification");
4281 else if (DECL_NAME (intdecls
) != DECL_NAME (impdecls
))
4283 error_with_ivar ("conflicting instance variable name",
4285 error_with_ivar ("previous declaration of",
4289 intdecls
= TREE_CHAIN (intdecls
);
4290 impdecls
= TREE_CHAIN (impdecls
);
4294 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
4295 This needs to be done just once per compilation. */
4297 /* struct _objc_super {
4298 struct _objc_object *self;
4299 struct _objc_class *super_class;
4303 build_super_template (void)
4305 tree field_decl
, field_decl_chain
;
4307 objc_super_template
= start_struct (RECORD_TYPE
, get_identifier (UTAG_SUPER
));
4309 /* struct _objc_object *self; */
4310 field_decl
= create_field_decl (objc_object_type
, "self");
4311 field_decl_chain
= field_decl
;
4313 /* struct _objc_class *super_class; */
4314 field_decl
= create_field_decl (build_pointer_type (objc_class_template
),
4316 chainon (field_decl_chain
, field_decl
);
4318 finish_struct (objc_super_template
, field_decl_chain
, NULL_TREE
);
4321 /* struct _objc_ivar {
4328 build_ivar_template (void)
4330 tree objc_ivar_id
, objc_ivar_record
;
4331 tree field_decl
, field_decl_chain
;
4333 objc_ivar_id
= get_identifier (UTAG_IVAR
);
4334 objc_ivar_record
= start_struct (RECORD_TYPE
, objc_ivar_id
);
4336 /* char *ivar_name; */
4337 field_decl
= create_field_decl (string_type_node
, "ivar_name");
4338 field_decl_chain
= field_decl
;
4340 /* char *ivar_type; */
4341 field_decl
= create_field_decl (string_type_node
, "ivar_type");
4342 chainon (field_decl_chain
, field_decl
);
4344 /* int ivar_offset; */
4345 field_decl
= create_field_decl (integer_type_node
, "ivar_offset");
4346 chainon (field_decl_chain
, field_decl
);
4348 finish_struct (objc_ivar_record
, field_decl_chain
, NULL_TREE
);
4350 return objc_ivar_record
;
4355 struct objc_ivar ivar_list[ivar_count];
4359 build_ivar_list_template (tree list_type
, int size
)
4361 tree objc_ivar_list_record
;
4362 tree field_decl
, field_decl_chain
;
4364 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
4366 /* int ivar_count; */
4367 field_decl
= create_field_decl (integer_type_node
, "ivar_count");
4368 field_decl_chain
= field_decl
;
4370 /* struct objc_ivar ivar_list[]; */
4371 field_decl
= create_field_decl (build_array_type
4374 (build_int_cst (NULL_TREE
, size
- 1))),
4376 chainon (field_decl_chain
, field_decl
);
4378 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
4380 return objc_ivar_list_record
;
4384 struct _objc__method_prototype_list *method_next;
4386 struct objc_method method_list[method_count];
4390 build_method_list_template (tree list_type
, int size
)
4392 tree objc_ivar_list_record
;
4393 tree field_decl
, field_decl_chain
;
4395 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
4397 /* struct _objc__method_prototype_list *method_next; */
4398 field_decl
= create_field_decl (build_pointer_type
4399 (xref_tag (RECORD_TYPE
,
4401 (UTAG_METHOD_PROTOTYPE_LIST
))),
4403 field_decl_chain
= field_decl
;
4405 /* int method_count; */
4406 field_decl
= create_field_decl (integer_type_node
, "method_count");
4407 chainon (field_decl_chain
, field_decl
);
4409 /* struct objc_method method_list[]; */
4410 field_decl
= create_field_decl (build_array_type
4413 (build_int_cst (NULL_TREE
, size
- 1))),
4415 chainon (field_decl_chain
, field_decl
);
4417 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
4419 return objc_ivar_list_record
;
4423 build_ivar_list_initializer (tree type
, tree field_decl
)
4425 tree initlist
= NULL_TREE
;
4429 tree ivar
= NULL_TREE
;
4432 if (DECL_NAME (field_decl
))
4433 ivar
= tree_cons (NULL_TREE
,
4434 add_objc_string (DECL_NAME (field_decl
),
4438 /* Unnamed bit-field ivar (yuck). */
4439 ivar
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), ivar
);
4442 encode_field_decl (field_decl
,
4443 obstack_object_size (&util_obstack
),
4444 OBJC_ENCODE_DONT_INLINE_DEFS
);
4446 /* Null terminate string. */
4447 obstack_1grow (&util_obstack
, 0);
4451 add_objc_string (get_identifier (obstack_finish (&util_obstack
)),
4454 obstack_free (&util_obstack
, util_firstobj
);
4457 ivar
= tree_cons (NULL_TREE
, byte_position (field_decl
), ivar
);
4458 initlist
= tree_cons (NULL_TREE
,
4459 objc_build_constructor (type
, nreverse (ivar
)),
4462 field_decl
= TREE_CHAIN (field_decl
);
4463 while (field_decl
&& TREE_CODE (field_decl
) != FIELD_DECL
);
4467 return objc_build_constructor (build_array_type (type
, 0),
4468 nreverse (initlist
));
4472 generate_ivars_list (tree type
, const char *name
, int size
, tree list
)
4474 tree decl
, initlist
;
4476 decl
= start_var_decl (type
, synth_id_with_class_suffix
4477 (name
, objc_implementation_context
));
4479 initlist
= build_tree_list (NULL_TREE
, build_int_cst (NULL_TREE
, size
));
4480 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
4482 finish_var_decl (decl
,
4483 objc_build_constructor (TREE_TYPE (decl
),
4484 nreverse (initlist
)));
4489 /* Count only the fields occurring in T. */
4491 ivar_list_length (tree t
)
4495 for (; t
; t
= TREE_CHAIN (t
))
4496 if (TREE_CODE (t
) == FIELD_DECL
)
4503 generate_ivar_lists (void)
4505 tree initlist
, ivar_list_template
, chain
;
4506 tree variable_length_type
4507 = xref_tag (RECORD_TYPE
, get_identifier (UTAG_IVAR_LIST
));
4510 generating_instance_variables
= 1;
4512 if (!objc_ivar_template
)
4513 objc_ivar_template
= build_ivar_template ();
4515 /* Only generate class variables for the root of the inheritance
4516 hierarchy since these will be the same for every class. */
4518 if (CLASS_SUPER_NAME (implementation_template
) == NULL_TREE
4519 && (chain
= TYPE_FIELDS (objc_class_template
)))
4521 size
= ivar_list_length (chain
);
4523 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
4524 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
4526 UOBJC_CLASS_VARIABLES_decl
4527 = generate_ivars_list (ivar_list_template
, "_OBJC_CLASS_VARIABLES",
4529 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl
) = variable_length_type
;
4532 UOBJC_CLASS_VARIABLES_decl
= 0;
4534 chain
= CLASS_IVARS (implementation_template
);
4537 size
= ivar_list_length (chain
);
4538 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
4539 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
4541 UOBJC_INSTANCE_VARIABLES_decl
4542 = generate_ivars_list (ivar_list_template
, "_OBJC_INSTANCE_VARIABLES",
4544 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl
) = variable_length_type
;
4547 UOBJC_INSTANCE_VARIABLES_decl
= 0;
4549 generating_instance_variables
= 0;
4553 build_dispatch_table_initializer (tree type
, tree entries
)
4555 tree initlist
= NULL_TREE
;
4559 tree elemlist
= NULL_TREE
;
4561 elemlist
= tree_cons (NULL_TREE
,
4562 build_selector (METHOD_SEL_NAME (entries
)),
4565 /* Generate the method encoding if we don't have one already. */
4566 if (! METHOD_ENCODING (entries
))
4567 METHOD_ENCODING (entries
) =
4568 encode_method_prototype (entries
);
4570 elemlist
= tree_cons (NULL_TREE
,
4571 add_objc_string (METHOD_ENCODING (entries
),
4576 = tree_cons (NULL_TREE
,
4577 convert (ptr_type_node
,
4578 build_unary_op (ADDR_EXPR
,
4579 METHOD_DEFINITION (entries
), 1)),
4582 initlist
= tree_cons (NULL_TREE
,
4583 objc_build_constructor (type
, nreverse (elemlist
)),
4586 entries
= TREE_CHAIN (entries
);
4590 return objc_build_constructor (build_array_type (type
, 0),
4591 nreverse (initlist
));
4594 /* To accomplish method prototyping without generating all kinds of
4595 inane warnings, the definition of the dispatch table entries were
4598 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
4600 struct objc_method { SEL _cmd; ...; void *_imp; }; */
4603 build_method_template (void)
4606 tree field_decl
, field_decl_chain
;
4608 _SLT_record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD
));
4611 field_decl
= create_field_decl (objc_selector_type
, "_cmd");
4612 field_decl_chain
= field_decl
;
4614 /* char *method_types; */
4615 field_decl
= create_field_decl (string_type_node
, "method_types");
4616 chainon (field_decl_chain
, field_decl
);
4619 field_decl
= create_field_decl (build_pointer_type (void_type_node
),
4621 chainon (field_decl_chain
, field_decl
);
4623 finish_struct (_SLT_record
, field_decl_chain
, NULL_TREE
);
4630 generate_dispatch_table (tree type
, const char *name
, int size
, tree list
)
4632 tree decl
, initlist
;
4634 decl
= start_var_decl (type
, synth_id_with_class_suffix
4635 (name
, objc_implementation_context
));
4637 initlist
= build_tree_list (NULL_TREE
, build_int_cst (NULL_TREE
, 0));
4638 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, size
), initlist
);
4639 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
4641 finish_var_decl (decl
,
4642 objc_build_constructor (TREE_TYPE (decl
),
4643 nreverse (initlist
)));
4649 mark_referenced_methods (void)
4651 struct imp_entry
*impent
;
4654 for (impent
= imp_list
; impent
; impent
= impent
->next
)
4656 chain
= CLASS_CLS_METHODS (impent
->imp_context
);
4659 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain
)));
4660 chain
= TREE_CHAIN (chain
);
4663 chain
= CLASS_NST_METHODS (impent
->imp_context
);
4666 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain
)));
4667 chain
= TREE_CHAIN (chain
);
4673 generate_dispatch_tables (void)
4675 tree initlist
, chain
, method_list_template
;
4676 tree variable_length_type
4677 = xref_tag (RECORD_TYPE
, get_identifier (UTAG_METHOD_LIST
));
4680 if (!objc_method_template
)
4681 objc_method_template
= build_method_template ();
4683 chain
= CLASS_CLS_METHODS (objc_implementation_context
);
4686 size
= list_length (chain
);
4688 method_list_template
4689 = build_method_list_template (objc_method_template
, size
);
4691 = build_dispatch_table_initializer (objc_method_template
, chain
);
4693 UOBJC_CLASS_METHODS_decl
4694 = generate_dispatch_table (method_list_template
,
4695 ((TREE_CODE (objc_implementation_context
)
4696 == CLASS_IMPLEMENTATION_TYPE
)
4697 ? "_OBJC_CLASS_METHODS"
4698 : "_OBJC_CATEGORY_CLASS_METHODS"),
4700 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
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",
4726 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
4729 UOBJC_INSTANCE_METHODS_decl
= 0;
4733 generate_protocol_list (tree i_or_p
)
4736 tree refs_decl
, lproto
, e
, plist
;
4738 const char *ref_name
;
4740 if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
4741 || TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4742 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
4743 else if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4744 plist
= PROTOCOL_LIST (i_or_p
);
4749 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4750 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
4751 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
4754 /* Build initializer. */
4755 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), NULL_TREE
);
4756 e
= build_int_cst (build_pointer_type (objc_protocol_template
), size
);
4757 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4759 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4761 tree pval
= TREE_VALUE (lproto
);
4763 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
4764 && PROTOCOL_FORWARD_DECL (pval
))
4766 e
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (pval
), 0);
4767 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4771 /* static struct objc_protocol *refs[n]; */
4773 if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4774 ref_name
= synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p
);
4775 else if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
)
4776 ref_name
= synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p
);
4777 else if (TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4778 ref_name
= synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p
);
4782 refs_decl
= start_var_decl
4784 (build_pointer_type (objc_protocol_template
),
4785 build_index_type (build_int_cst (NULL_TREE
, size
+ 2))),
4788 finish_var_decl (refs_decl
, objc_build_constructor (TREE_TYPE (refs_decl
),
4789 nreverse (initlist
)));
4795 build_category_initializer (tree type
, tree cat_name
, tree class_name
,
4796 tree instance_methods
, tree class_methods
,
4799 tree initlist
= NULL_TREE
, expr
;
4801 initlist
= tree_cons (NULL_TREE
, cat_name
, initlist
);
4802 initlist
= tree_cons (NULL_TREE
, class_name
, initlist
);
4804 if (!instance_methods
)
4805 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4808 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
4809 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4812 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4815 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
4816 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4819 /* protocol_list = */
4821 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4824 expr
= convert (build_pointer_type
4826 (objc_protocol_template
)),
4827 build_unary_op (ADDR_EXPR
, protocol_list
, 0));
4828 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4831 return objc_build_constructor (type
, nreverse (initlist
));
4834 /* struct _objc_class {
4835 struct objc_class *isa;
4836 struct objc_class *super_class;
4841 struct objc_ivar_list *ivars;
4842 struct objc_method_list *methods;
4843 if (flag_next_runtime)
4844 struct objc_cache *cache;
4846 struct sarray *dtable;
4847 struct objc_class *subclass_list;
4848 struct objc_class *sibling_class;
4850 struct objc_protocol_list *protocols;
4851 if (flag_next_runtime)
4853 void *gc_object_type;
4857 build_shared_structure_initializer (tree type
, tree isa
, tree super
,
4858 tree name
, tree size
, int status
,
4859 tree dispatch_table
, tree ivar_list
,
4862 tree initlist
= NULL_TREE
, expr
;
4865 initlist
= tree_cons (NULL_TREE
, isa
, initlist
);
4868 initlist
= tree_cons (NULL_TREE
, super
, initlist
);
4871 initlist
= tree_cons (NULL_TREE
, default_conversion (name
), initlist
);
4874 initlist
= tree_cons (NULL_TREE
, build_int_cst (long_integer_type_node
, 0),
4878 initlist
= tree_cons (NULL_TREE
,
4879 build_int_cst (long_integer_type_node
, status
),
4882 /* instance_size = */
4883 initlist
= tree_cons (NULL_TREE
, convert (long_integer_type_node
, size
),
4886 /* objc_ivar_list = */
4888 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4891 expr
= build_unary_op (ADDR_EXPR
, ivar_list
, 0);
4892 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4895 /* objc_method_list = */
4896 if (!dispatch_table
)
4897 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4900 expr
= build_unary_op (ADDR_EXPR
, dispatch_table
, 0);
4901 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4904 if (flag_next_runtime
)
4905 /* method_cache = */
4906 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4910 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4912 /* subclass_list = */
4913 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4915 /* sibling_class = */
4916 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4919 /* protocol_list = */
4920 if (! protocol_list
)
4921 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4924 expr
= convert (build_pointer_type
4926 (objc_protocol_template
)),
4927 build_unary_op (ADDR_EXPR
, protocol_list
, 0));
4928 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4931 if (flag_next_runtime
)
4933 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4935 /* gc_object_type = NULL */
4936 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4938 return objc_build_constructor (type
, nreverse (initlist
));
4941 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
4944 lookup_category (tree
class, tree cat_name
)
4946 tree category
= CLASS_CATEGORY_LIST (class);
4948 while (category
&& CLASS_SUPER_NAME (category
) != cat_name
)
4949 category
= CLASS_CATEGORY_LIST (category
);
4953 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4956 generate_category (tree cat
)
4959 tree initlist
, cat_name_expr
, class_name_expr
;
4960 tree protocol_decl
, category
;
4962 add_class_reference (CLASS_NAME (cat
));
4963 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
4965 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
4967 category
= lookup_category (implementation_template
,
4968 CLASS_SUPER_NAME (cat
));
4970 if (category
&& CLASS_PROTOCOL_LIST (category
))
4972 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
4973 protocol_decl
= generate_protocol_list (category
);
4978 decl
= start_var_decl (objc_category_template
,
4979 synth_id_with_class_suffix
4980 ("_OBJC_CATEGORY", objc_implementation_context
));
4982 initlist
= build_category_initializer (TREE_TYPE (decl
),
4983 cat_name_expr
, class_name_expr
,
4984 UOBJC_INSTANCE_METHODS_decl
,
4985 UOBJC_CLASS_METHODS_decl
,
4988 finish_var_decl (decl
, initlist
);
4991 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4992 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4995 generate_shared_structures (void)
4997 tree sc_spec
, decl_specs
, decl
;
4998 tree name_expr
, super_expr
, root_expr
;
4999 tree my_root_id
= NULL_TREE
, my_super_id
= NULL_TREE
;
5000 tree cast_type
, initlist
, protocol_decl
;
5002 my_super_id
= CLASS_SUPER_NAME (implementation_template
);
5005 add_class_reference (my_super_id
);
5007 /* Compute "my_root_id" - this is required for code generation.
5008 the "isa" for all meta class structures points to the root of
5009 the inheritance hierarchy (e.g. "__Object")... */
5010 my_root_id
= my_super_id
;
5013 tree my_root_int
= lookup_interface (my_root_id
);
5015 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
5016 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
5023 /* No super class. */
5024 my_root_id
= CLASS_NAME (implementation_template
);
5026 cast_type
= build_pointer_type (objc_class_template
);
5027 name_expr
= add_objc_string (CLASS_NAME (implementation_template
),
5030 /* Install class `isa' and `super' pointers at runtime. */
5033 super_expr
= add_objc_string (my_super_id
, class_names
);
5034 super_expr
= build_c_cast (cast_type
, super_expr
); /* cast! */
5037 super_expr
= build_int_cst (NULL_TREE
, 0);
5039 root_expr
= add_objc_string (my_root_id
, class_names
);
5040 root_expr
= build_c_cast (cast_type
, root_expr
); /* cast! */
5042 if (CLASS_PROTOCOL_LIST (implementation_template
))
5044 generate_protocol_references
5045 (CLASS_PROTOCOL_LIST (implementation_template
));
5046 protocol_decl
= generate_protocol_list (implementation_template
);
5051 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5053 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
5054 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
5056 decl
= start_var_decl (objc_class_template
,
5058 (DECL_NAME (UOBJC_METACLASS_decl
)));
5061 = build_shared_structure_initializer
5063 root_expr
, super_expr
, name_expr
,
5064 convert (integer_type_node
, TYPE_SIZE_UNIT (objc_class_template
)),
5066 UOBJC_CLASS_METHODS_decl
,
5067 UOBJC_CLASS_VARIABLES_decl
,
5070 finish_var_decl (decl
, initlist
);
5072 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5074 decl
= start_var_decl (objc_class_template
,
5076 (DECL_NAME (UOBJC_CLASS_decl
)));
5079 = build_shared_structure_initializer
5081 build_unary_op (ADDR_EXPR
, UOBJC_METACLASS_decl
, 0),
5082 super_expr
, name_expr
,
5083 convert (integer_type_node
,
5084 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5085 (implementation_template
))),
5087 UOBJC_INSTANCE_METHODS_decl
,
5088 UOBJC_INSTANCE_VARIABLES_decl
,
5091 finish_var_decl (decl
, initlist
);
5096 synth_id_with_class_suffix (const char *preamble
, tree ctxt
)
5098 static char string
[BUFSIZE
];
5100 if (TREE_CODE (ctxt
) == CLASS_IMPLEMENTATION_TYPE
5101 || TREE_CODE (ctxt
) == CLASS_INTERFACE_TYPE
)
5103 sprintf (string
, "%s_%s", preamble
,
5104 IDENTIFIER_POINTER (CLASS_NAME (ctxt
)));
5106 else if (TREE_CODE (ctxt
) == CATEGORY_IMPLEMENTATION_TYPE
5107 || TREE_CODE (ctxt
) == CATEGORY_INTERFACE_TYPE
)
5109 /* We have a category. */
5110 const char *const class_name
5111 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
5112 const char *const class_super_name
5113 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
));
5114 sprintf (string
, "%s_%s_%s", preamble
, class_name
, class_super_name
);
5116 else if (TREE_CODE (ctxt
) == PROTOCOL_INTERFACE_TYPE
)
5118 const char *protocol_name
= IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt
));
5119 sprintf (string
, "%s_%s", preamble
, protocol_name
);
5127 /* If type is empty or only type qualifiers are present, add default
5128 type of id (otherwise grokdeclarator will default to int). */
5131 adjust_type_for_id_default (tree type
)
5134 type
= make_node (TREE_LIST
);
5136 if (!TREE_VALUE (type
))
5137 TREE_VALUE (type
) = objc_object_type
;
5138 else if (TREE_CODE (TREE_VALUE (type
)) == RECORD_TYPE
5139 && TYPED_OBJECT (TREE_VALUE (type
)))
5140 error ("can not use an object as parameter to a method");
5147 selector ':' '(' typename ')' identifier
5150 Transform an Objective-C keyword argument into
5151 the C equivalent parameter declarator.
5153 In: key_name, an "identifier_node" (optional).
5154 arg_type, a "tree_list" (optional).
5155 arg_name, an "identifier_node".
5157 Note: It would be really nice to strongly type the preceding
5158 arguments in the function prototype; however, then I
5159 could not use the "accessor" macros defined in "tree.h".
5161 Out: an instance of "keyword_decl". */
5164 objc_build_keyword_decl (tree key_name
, tree arg_type
, tree arg_name
)
5168 /* If no type is specified, default to "id". */
5169 arg_type
= adjust_type_for_id_default (arg_type
);
5171 keyword_decl
= make_node (KEYWORD_DECL
);
5173 TREE_TYPE (keyword_decl
) = arg_type
;
5174 KEYWORD_ARG_NAME (keyword_decl
) = arg_name
;
5175 KEYWORD_KEY_NAME (keyword_decl
) = key_name
;
5177 return keyword_decl
;
5180 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5183 build_keyword_selector (tree selector
)
5186 tree key_chain
, key_name
;
5189 /* Scan the selector to see how much space we'll need. */
5190 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
5192 if (TREE_CODE (selector
) == KEYWORD_DECL
)
5193 key_name
= KEYWORD_KEY_NAME (key_chain
);
5194 else if (TREE_CODE (selector
) == TREE_LIST
)
5195 key_name
= TREE_PURPOSE (key_chain
);
5200 len
+= IDENTIFIER_LENGTH (key_name
) + 1;
5202 /* Just a ':' arg. */
5206 buf
= (char *) alloca (len
+ 1);
5207 /* Start the buffer out as an empty string. */
5210 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
5212 if (TREE_CODE (selector
) == KEYWORD_DECL
)
5213 key_name
= KEYWORD_KEY_NAME (key_chain
);
5214 else if (TREE_CODE (selector
) == TREE_LIST
)
5216 key_name
= TREE_PURPOSE (key_chain
);
5217 /* The keyword decl chain will later be used as a function argument
5218 chain. Unhook the selector itself so as to not confuse other
5219 parts of the compiler. */
5220 TREE_PURPOSE (key_chain
) = NULL_TREE
;
5226 strcat (buf
, IDENTIFIER_POINTER (key_name
));
5230 return get_identifier (buf
);
5233 /* Used for declarations and definitions. */
5236 build_method_decl (enum tree_code code
, tree ret_type
, tree selector
,
5241 /* If no type is specified, default to "id". */
5242 ret_type
= adjust_type_for_id_default (ret_type
);
5244 method_decl
= make_node (code
);
5245 TREE_TYPE (method_decl
) = ret_type
;
5247 /* If we have a keyword selector, create an identifier_node that
5248 represents the full selector name (`:' included)... */
5249 if (TREE_CODE (selector
) == KEYWORD_DECL
)
5251 METHOD_SEL_NAME (method_decl
) = build_keyword_selector (selector
);
5252 METHOD_SEL_ARGS (method_decl
) = selector
;
5253 METHOD_ADD_ARGS (method_decl
) = add_args
;
5257 METHOD_SEL_NAME (method_decl
) = selector
;
5258 METHOD_SEL_ARGS (method_decl
) = NULL_TREE
;
5259 METHOD_ADD_ARGS (method_decl
) = NULL_TREE
;
5265 #define METHOD_DEF 0
5266 #define METHOD_REF 1
5268 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5269 an argument list for method METH. CONTEXT is either METHOD_DEF or
5270 METHOD_REF, saying whether we are trying to define a method or call
5271 one. SUPERFLAG says this is for a send to super; this makes a
5272 difference for the NeXT calling sequence in which the lookup and
5273 the method call are done together. If METH is null, user-defined
5274 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5277 get_arg_type_list (tree meth
, int context
, int superflag
)
5281 /* Receiver type. */
5282 if (flag_next_runtime
&& superflag
)
5283 arglist
= build_tree_list (NULL_TREE
, objc_super_type
);
5284 else if (context
== METHOD_DEF
&& TREE_CODE (meth
) == INSTANCE_METHOD_DECL
)
5285 arglist
= build_tree_list (NULL_TREE
, objc_instance_type
);
5287 arglist
= build_tree_list (NULL_TREE
, objc_object_type
);
5289 /* Selector type - will eventually change to `int'. */
5290 chainon (arglist
, build_tree_list (NULL_TREE
, objc_selector_type
));
5292 /* No actual method prototype given -- assume that remaining arguments
5297 /* Build a list of argument types. */
5298 for (akey
= METHOD_SEL_ARGS (meth
); akey
; akey
= TREE_CHAIN (akey
))
5300 tree arg_type
= TREE_VALUE (TREE_TYPE (akey
));
5302 chainon (arglist
, build_tree_list (NULL_TREE
, arg_type
));
5305 if (METHOD_ADD_ARGS (meth
))
5307 for (akey
= TREE_CHAIN (METHOD_ADD_ARGS (meth
));
5308 akey
; akey
= TREE_CHAIN (akey
))
5310 tree arg_type
= TREE_TYPE (TREE_VALUE (akey
));
5312 chainon (arglist
, build_tree_list (NULL_TREE
, arg_type
));
5315 if (!TREE_OVERFLOW (METHOD_ADD_ARGS (meth
)))
5316 goto lack_of_ellipsis
;
5321 chainon (arglist
, OBJC_VOID_AT_END
);
5328 check_duplicates (hash hsh
, int methods
, int is_class
)
5330 tree meth
= NULL_TREE
;
5338 /* We have two or more methods with the same name but
5342 warning ("multiple %s named `%c%s' found",
5343 methods
? "methods" : "selectors",
5344 (is_class
? '+' : '-'),
5345 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
5347 warn_with_method (methods
? "using" : "found",
5348 ((TREE_CODE (meth
) == INSTANCE_METHOD_DECL
)
5352 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
5353 warn_with_method ("also found",
5354 ((TREE_CODE (loop
->value
) == INSTANCE_METHOD_DECL
)
5363 /* If RECEIVER is a class reference, return the identifier node for
5364 the referenced class. RECEIVER is created by objc_get_class_reference,
5365 so we check the exact form created depending on which runtimes are
5369 receiver_is_class_object (tree receiver
, int self
, int super
)
5371 tree chain
, exp
, arg
;
5373 /* The receiver is 'self' or 'super' in the context of a class method. */
5374 if (objc_method_context
5375 && TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
5378 ? CLASS_SUPER_NAME (implementation_template
)
5379 : CLASS_NAME (implementation_template
));
5381 if (flag_next_runtime
)
5383 /* The receiver is a variable created by
5384 build_class_reference_decl. */
5385 if (TREE_CODE (receiver
) == VAR_DECL
&& IS_CLASS (TREE_TYPE (receiver
)))
5386 /* Look up the identifier. */
5387 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
5388 if (TREE_PURPOSE (chain
) == receiver
)
5389 return TREE_VALUE (chain
);
5392 /* The receiver is a function call that returns an id. Check if
5393 it is a call to objc_getClass, if so, pick up the class name. */
5394 if (TREE_CODE (receiver
) == CALL_EXPR
5395 && (exp
= TREE_OPERAND (receiver
, 0))
5396 && TREE_CODE (exp
) == ADDR_EXPR
5397 && (exp
= TREE_OPERAND (exp
, 0))
5398 && TREE_CODE (exp
) == FUNCTION_DECL
5399 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
5400 prototypes for objc_get_class(). Thankfully, they seem to share the
5401 same function type. */
5402 && TREE_TYPE (exp
) == TREE_TYPE (objc_get_class_decl
)
5403 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp
)), TAG_GETCLASS
)
5404 /* We have a call to objc_get_class/objc_getClass! */
5405 && (arg
= TREE_OPERAND (receiver
, 1))
5406 && TREE_CODE (arg
) == TREE_LIST
5407 && (arg
= TREE_VALUE (arg
)))
5410 if (TREE_CODE (arg
) == ADDR_EXPR
5411 && (arg
= TREE_OPERAND (arg
, 0))
5412 && TREE_CODE (arg
) == STRING_CST
)
5413 /* Finally, we have the class name. */
5414 return get_identifier (TREE_STRING_POINTER (arg
));
5419 /* If we are currently building a message expr, this holds
5420 the identifier of the selector of the message. This is
5421 used when printing warnings about argument mismatches. */
5423 static tree current_objc_message_selector
= 0;
5426 objc_message_selector (void)
5428 return current_objc_message_selector
;
5431 /* Construct an expression for sending a message.
5432 MESS has the object to send to in TREE_PURPOSE
5433 and the argument list (including selector) in TREE_VALUE.
5435 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
5436 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
5439 objc_build_message_expr (tree mess
)
5441 tree receiver
= TREE_PURPOSE (mess
);
5444 tree args
= TREE_PURPOSE (TREE_VALUE (mess
));
5446 tree args
= TREE_VALUE (mess
);
5448 tree method_params
= NULL_TREE
;
5450 if (TREE_CODE (receiver
) == ERROR_MARK
)
5451 return error_mark_node
;
5453 /* Obtain the full selector name. */
5454 if (TREE_CODE (args
) == IDENTIFIER_NODE
)
5455 /* A unary selector. */
5457 else if (TREE_CODE (args
) == TREE_LIST
)
5458 sel_name
= build_keyword_selector (args
);
5462 /* Build the parameter list to give to the method. */
5463 if (TREE_CODE (args
) == TREE_LIST
)
5465 method_params
= chainon (args
, TREE_VALUE (TREE_VALUE (mess
)));
5468 tree chain
= args
, prev
= NULL_TREE
;
5470 /* We have a keyword selector--check for comma expressions. */
5473 tree element
= TREE_VALUE (chain
);
5475 /* We have a comma expression, must collapse... */
5476 if (TREE_CODE (element
) == TREE_LIST
)
5479 TREE_CHAIN (prev
) = element
;
5484 chain
= TREE_CHAIN (chain
);
5486 method_params
= args
;
5491 if (processing_template_decl
)
5492 /* Must wait until template instantiation time. */
5493 return build_min_nt (MESSAGE_SEND_EXPR
, receiver
, sel_name
,
5497 return objc_finish_message_expr (receiver
, sel_name
, method_params
);
5500 /* Look up method SEL_NAME that would be suitable for receiver
5501 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
5502 nonzero), and report on any duplicates. */
5505 lookup_method_in_hash_lists (tree sel_name
, int is_class
)
5507 hash method_prototype
= NULL
;
5510 method_prototype
= hash_lookup (nst_method_hash_list
,
5513 if (!method_prototype
)
5515 method_prototype
= hash_lookup (cls_method_hash_list
,
5520 return check_duplicates (method_prototype
, 1, is_class
);
5523 /* The 'objc_finish_message_expr' routine is called from within
5524 'objc_build_message_expr' for non-template functions. In the case of
5525 C++ template functions, it is called from 'build_expr_from_tree'
5526 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
5529 objc_finish_message_expr (tree receiver
, tree sel_name
, tree method_params
)
5531 tree method_prototype
= NULL_TREE
, rprotos
= NULL_TREE
, rtype
;
5532 tree selector
, retval
, class_tree
;
5533 int self
, super
, have_cast
;
5535 /* Extract the receiver of the message, as well as its type
5536 (where the latter may take the form of a cast or be inferred
5537 from the implementation context). */
5539 while (TREE_CODE (rtype
) == COMPOUND_EXPR
5540 || TREE_CODE (rtype
) == MODIFY_EXPR
5541 || TREE_CODE (rtype
) == NOP_EXPR
5542 || TREE_CODE (rtype
) == CONVERT_EXPR
5543 || TREE_CODE (rtype
) == COMPONENT_REF
)
5544 rtype
= TREE_OPERAND (rtype
, 0);
5545 self
= (rtype
== self_decl
);
5546 super
= (rtype
== UOBJC_SUPER_decl
);
5547 rtype
= TREE_TYPE (receiver
);
5548 have_cast
= (TREE_CODE (receiver
) == NOP_EXPR
5549 || (TREE_CODE (receiver
) == COMPOUND_EXPR
5550 && !IS_SUPER (rtype
)));
5552 /* If the receiver is a class object, retrieve the corresponding
5553 @interface, if one exists. */
5554 class_tree
= receiver_is_class_object (receiver
, self
, super
);
5556 /* Now determine the receiver type (if an explicit cast has not been
5561 rtype
= lookup_interface (class_tree
);
5562 /* Handle `self' and `super'. */
5565 if (!CLASS_SUPER_NAME (implementation_template
))
5567 error ("no super class declared in @interface for `%s'",
5568 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
5569 return error_mark_node
;
5571 rtype
= lookup_interface (CLASS_SUPER_NAME (implementation_template
));
5574 rtype
= lookup_interface (CLASS_NAME (implementation_template
));
5577 /* If receiver is of type `id' or `Class' (or if the @interface for a
5578 class is not visible), we shall be satisfied with the existence of
5579 any instance or class method. */
5580 if (!rtype
|| objc_is_id (rtype
))
5583 rtype
= xref_tag (RECORD_TYPE
, class_tree
);
5586 class_tree
= (IS_CLASS (rtype
) ? objc_class_name
: NULL_TREE
);
5587 rprotos
= TYPE_PROTOCOL_LIST (rtype
);
5593 /* If messaging 'id <Protos>' or 'Class <Proto>', first search
5594 in protocols themselves for the method prototype. */
5596 = lookup_method_in_protocol_list (rprotos
, sel_name
,
5597 class_tree
!= NULL_TREE
);
5599 /* If messaging 'Class <Proto>' but did not find a class method
5600 prototype, search for an instance method instead, and warn
5601 about having done so. */
5602 if (!method_prototype
&& !rtype
&& class_tree
!= NULL_TREE
)
5605 = lookup_method_in_protocol_list (rprotos
, sel_name
, 0);
5607 if (method_prototype
)
5608 warning ("found `-%s' instead of `+%s' in protocol(s)",
5609 IDENTIFIER_POINTER (sel_name
),
5610 IDENTIFIER_POINTER (sel_name
));
5616 tree orig_rtype
= rtype
, saved_rtype
;
5618 if (TREE_CODE (rtype
) == POINTER_TYPE
)
5619 rtype
= TREE_TYPE (rtype
);
5620 /* Traverse typedef aliases */
5621 while (TREE_CODE (rtype
) == RECORD_TYPE
&& OBJC_TYPE_NAME (rtype
)
5622 && TREE_CODE (OBJC_TYPE_NAME (rtype
)) == TYPE_DECL
5623 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype
)))
5624 rtype
= DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype
));
5625 saved_rtype
= rtype
;
5626 if (TYPED_OBJECT (rtype
))
5628 rprotos
= TYPE_PROTOCOL_LIST (rtype
);
5629 rtype
= lookup_interface (OBJC_TYPE_NAME (rtype
));
5631 /* If we could not find an @interface declaration, we must have
5632 only seen a @class declaration; so, we cannot say anything
5633 more intelligent about which methods the receiver will
5636 rtype
= saved_rtype
;
5637 else if (TREE_CODE (rtype
) == CLASS_INTERFACE_TYPE
5638 || TREE_CODE (rtype
) == CLASS_IMPLEMENTATION_TYPE
)
5640 /* We have a valid ObjC class name. Look up the method name
5641 in the published @interface for the class (and its
5644 = lookup_method_static (rtype
, sel_name
, class_tree
!= NULL_TREE
);
5646 /* If the method was not found in the @interface, it may still
5647 exist locally as part of the @implementation. */
5648 if (!method_prototype
&& objc_implementation_context
5649 && CLASS_NAME (objc_implementation_context
)
5650 == OBJC_TYPE_NAME (rtype
))
5654 ? CLASS_CLS_METHODS (objc_implementation_context
)
5655 : CLASS_NST_METHODS (objc_implementation_context
)),
5658 /* If we haven't found a candidate method by now, try looking for
5659 it in the protocol list. */
5660 if (!method_prototype
&& rprotos
)
5662 = lookup_method_in_protocol_list (rprotos
, sel_name
,
5663 class_tree
!= NULL_TREE
);
5667 warning ("invalid receiver type `%s'",
5668 gen_type_name (orig_rtype
));
5669 /* After issuing the "invalid receiver" warning, perform method
5670 lookup as if we were messaging 'id'. */
5671 rtype
= rprotos
= NULL_TREE
;
5676 /* For 'id' or 'Class' receivers, search in the global hash table
5677 as a last resort. For all receivers, warn if protocol searches
5679 if (!method_prototype
)
5682 warning ("`%c%s' not found in protocol(s)",
5683 (class_tree
? '+' : '-'),
5684 IDENTIFIER_POINTER (sel_name
));
5688 = lookup_method_in_hash_lists (sel_name
, class_tree
!= NULL_TREE
);
5691 if (!method_prototype
)
5693 static bool warn_missing_methods
= false;
5696 warning ("`%s' may not respond to `%c%s'",
5697 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype
)),
5698 (class_tree
? '+' : '-'),
5699 IDENTIFIER_POINTER (sel_name
));
5700 /* If we are messaging an 'id' or 'Class' object and made it here,
5701 then we have failed to find _any_ instance or class method,
5704 warning ("no `%c%s' method found",
5705 (class_tree
? '+' : '-'),
5706 IDENTIFIER_POINTER (sel_name
));
5708 if (!warn_missing_methods
)
5710 warning ("(Messages without a matching method signature");
5711 warning ("will be assumed to return `id' and accept");
5712 warning ("`...' as arguments.)");
5713 warn_missing_methods
= true;
5717 /* Save the selector name for printing error messages. */
5718 current_objc_message_selector
= sel_name
;
5720 /* Build the parameters list for looking up the method.
5721 These are the object itself and the selector. */
5723 if (flag_typed_selectors
)
5724 selector
= build_typed_selector_reference (sel_name
, method_prototype
);
5726 selector
= build_selector_reference (sel_name
);
5728 retval
= build_objc_method_call (super
, method_prototype
,
5730 selector
, method_params
);
5732 current_objc_message_selector
= 0;
5737 /* Build a tree expression to send OBJECT the operation SELECTOR,
5738 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5739 assuming the method has prototype METHOD_PROTOTYPE.
5740 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5741 Use METHOD_PARAMS as list of args to pass to the method.
5742 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5745 build_objc_method_call (int super_flag
, tree method_prototype
,
5746 tree lookup_object
, tree selector
,
5749 tree sender
= (super_flag
? umsg_super_decl
:
5750 (!flag_next_runtime
|| flag_nil_receivers
5752 : umsg_nonnil_decl
));
5753 tree rcv_p
= (super_flag
? objc_super_type
: objc_object_type
);
5755 /* If a prototype for the method to be called exists, then cast
5756 the sender's return type and arguments to match that of the method.
5757 Otherwise, leave sender as is. */
5760 ? TREE_VALUE (TREE_TYPE (method_prototype
))
5761 : objc_object_type
);
5763 = build_pointer_type
5764 (build_function_type
5767 (method_prototype
, METHOD_REF
, super_flag
)));
5770 lookup_object
= build_c_cast (rcv_p
, lookup_object
);
5772 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
5773 lookup_object
= save_expr (lookup_object
);
5775 if (flag_next_runtime
)
5777 /* If we are returning a struct in memory, and the address
5778 of that memory location is passed as a hidden first
5779 argument, then change which messenger entry point this
5780 expr will call. NB: Note that sender_cast remains
5781 unchanged (it already has a struct return type). */
5782 if (!targetm
.calls
.struct_value_rtx (0, 0)
5783 && (TREE_CODE (ret_type
) == RECORD_TYPE
5784 || TREE_CODE (ret_type
) == UNION_TYPE
)
5785 && targetm
.calls
.return_in_memory (ret_type
, 0))
5786 sender
= (super_flag
? umsg_super_stret_decl
:
5787 flag_nil_receivers
? umsg_stret_decl
: umsg_nonnil_stret_decl
);
5789 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5790 tree_cons (NULL_TREE
, selector
,
5792 method
= build_fold_addr_expr (sender
);
5796 /* This is the portable (GNU) way. */
5799 /* First, call the lookup function to get a pointer to the method,
5800 then cast the pointer, then call it with the method arguments. */
5802 object
= (super_flag
? self_decl
: lookup_object
);
5804 t
= tree_cons (NULL_TREE
, selector
, NULL_TREE
);
5805 t
= tree_cons (NULL_TREE
, lookup_object
, t
);
5806 method
= build_function_call (sender
, t
);
5808 /* Pass the object to the method. */
5809 method_params
= tree_cons (NULL_TREE
, object
,
5810 tree_cons (NULL_TREE
, selector
,
5814 /* ??? Selector is not at this point something we can use inside
5815 the compiler itself. Set it to garbage for the nonce. */
5816 t
= build (OBJ_TYPE_REF
, sender_cast
, method
, lookup_object
, size_zero_node
);
5817 return build_function_call (t
, method_params
);
5821 build_protocol_reference (tree p
)
5824 const char *proto_name
;
5826 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
5828 proto_name
= synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
);
5829 decl
= start_var_decl (objc_protocol_template
, proto_name
);
5831 PROTOCOL_FORWARD_DECL (p
) = decl
;
5834 /* This function is called by the parser when (and only when) a
5835 @protocol() expression is found, in order to compile it. */
5837 objc_build_protocol_expr (tree protoname
)
5840 tree p
= lookup_protocol (protoname
);
5844 error ("cannot find protocol declaration for `%s'",
5845 IDENTIFIER_POINTER (protoname
));
5846 return error_mark_node
;
5849 if (!PROTOCOL_FORWARD_DECL (p
))
5850 build_protocol_reference (p
);
5852 expr
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
5854 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
5855 if we have it, rather than converting it here. */
5856 expr
= convert (objc_protocol_type
, expr
);
5858 /* The @protocol() expression is being compiled into a pointer to a
5859 statically allocated instance of the Protocol class. To become
5860 usable at runtime, the 'isa' pointer of the instance need to be
5861 fixed up at runtime by the runtime library, to point to the
5862 actual 'Protocol' class. */
5864 /* For the GNU runtime, put the static Protocol instance in the list
5865 of statically allocated instances, so that we make sure that its
5866 'isa' pointer is fixed up at runtime by the GNU runtime library
5867 to point to the Protocol class (at runtime, when loading the
5868 module, the GNU runtime library loops on the statically allocated
5869 instances (as found in the defs field in objc_symtab) and fixups
5870 all the 'isa' pointers of those objects). */
5871 if (! flag_next_runtime
)
5873 /* This type is a struct containing the fields of a Protocol
5874 object. (Cfr. objc_protocol_type instead is the type of a pointer
5875 to such a struct). */
5876 tree protocol_struct_type
= xref_tag
5877 (RECORD_TYPE
, get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
5880 /* Look for the list of Protocol statically allocated instances
5881 to fixup at runtime. Create a new list to hold Protocol
5882 statically allocated instances, if the list is not found. At
5883 present there is only another list, holding NSConstantString
5884 static instances to be fixed up at runtime. */
5885 for (chain
= &objc_static_instances
;
5886 *chain
&& TREE_VALUE (*chain
) != protocol_struct_type
;
5887 chain
= &TREE_CHAIN (*chain
));
5890 *chain
= tree_cons (NULL_TREE
, protocol_struct_type
, NULL_TREE
);
5891 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type
),
5895 /* Add this statically allocated instance to the Protocol list. */
5896 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
,
5897 PROTOCOL_FORWARD_DECL (p
),
5898 TREE_PURPOSE (*chain
));
5905 /* This function is called by the parser when a @selector() expression
5906 is found, in order to compile it. It is only called by the parser
5907 and only to compile a @selector(). */
5909 objc_build_selector_expr (tree selnamelist
)
5913 /* Obtain the full selector name. */
5914 if (TREE_CODE (selnamelist
) == IDENTIFIER_NODE
)
5915 /* A unary selector. */
5916 selname
= selnamelist
;
5917 else if (TREE_CODE (selnamelist
) == TREE_LIST
)
5918 selname
= build_keyword_selector (selnamelist
);
5922 /* If we are required to check @selector() expressions as they
5923 are found, check that the selector has been declared. */
5924 if (warn_undeclared_selector
)
5926 /* Look the selector up in the list of all known class and
5927 instance methods (up to this line) to check that the selector
5931 /* First try with instance methods. */
5932 hsh
= hash_lookup (nst_method_hash_list
, selname
);
5934 /* If not found, try with class methods. */
5937 hsh
= hash_lookup (cls_method_hash_list
, selname
);
5940 /* If still not found, print out a warning. */
5943 warning ("undeclared selector `%s'", IDENTIFIER_POINTER (selname
));
5948 if (flag_typed_selectors
)
5949 return build_typed_selector_reference (selname
, 0);
5951 return build_selector_reference (selname
);
5955 objc_build_encode_expr (tree type
)
5960 encode_type (type
, obstack_object_size (&util_obstack
),
5961 OBJC_ENCODE_INLINE_DEFS
);
5962 obstack_1grow (&util_obstack
, 0); /* null terminate string */
5963 string
= obstack_finish (&util_obstack
);
5965 /* Synthesize a string that represents the encoded struct/union. */
5966 result
= my_build_string (strlen (string
) + 1, string
);
5967 obstack_free (&util_obstack
, util_firstobj
);
5972 build_ivar_reference (tree id
)
5974 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
5976 /* Historically, a class method that produced objects (factory
5977 method) would assign `self' to the instance that it
5978 allocated. This would effectively turn the class method into
5979 an instance method. Following this assignment, the instance
5980 variables could be accessed. That practice, while safe,
5981 violates the simple rule that a class method should not refer
5982 to an instance variable. It's better to catch the cases
5983 where this is done unknowingly than to support the above
5985 warning ("instance variable `%s' accessed in class method",
5986 IDENTIFIER_POINTER (id
));
5987 self_decl
= convert (objc_instance_type
, self_decl
); /* cast */
5990 return build_component_ref (build_indirect_ref (self_decl
, "->"), id
);
5993 /* Compute a hash value for a given method SEL_NAME. */
5996 hash_func (tree sel_name
)
5998 const unsigned char *s
5999 = (const unsigned char *)IDENTIFIER_POINTER (sel_name
);
6003 h
= h
* 67 + *s
++ - 113;
6010 nst_method_hash_list
6011 = (hash
*) ggc_alloc_cleared (SIZEHASHTABLE
* sizeof (hash
));
6012 cls_method_hash_list
6013 = (hash
*) ggc_alloc_cleared (SIZEHASHTABLE
* sizeof (hash
));
6015 /* Initialize the hash table used to hold the constant string objects. */
6016 string_htab
= htab_create_ggc (31, string_hash
,
6020 /* WARNING!!!! hash_enter is called with a method, and will peek
6021 inside to find its selector! But hash_lookup is given a selector
6022 directly, and looks for the selector that's inside the found
6023 entry's key (method) for comparison. */
6026 hash_enter (hash
*hashlist
, tree method
)
6029 int slot
= hash_func (METHOD_SEL_NAME (method
)) % SIZEHASHTABLE
;
6031 obj
= (hash
) ggc_alloc (sizeof (struct hashed_entry
));
6033 obj
->next
= hashlist
[slot
];
6036 hashlist
[slot
] = obj
; /* append to front */
6040 hash_lookup (hash
*hashlist
, tree sel_name
)
6044 target
= hashlist
[hash_func (sel_name
) % SIZEHASHTABLE
];
6048 if (sel_name
== METHOD_SEL_NAME (target
->key
))
6051 target
= target
->next
;
6057 hash_add_attr (hash entry
, tree value
)
6061 obj
= (attr
) ggc_alloc (sizeof (struct hashed_attribute
));
6062 obj
->next
= entry
->list
;
6065 entry
->list
= obj
; /* append to front */
6069 lookup_method (tree mchain
, tree method
)
6073 if (TREE_CODE (method
) == IDENTIFIER_NODE
)
6076 key
= METHOD_SEL_NAME (method
);
6080 if (METHOD_SEL_NAME (mchain
) == key
)
6083 mchain
= TREE_CHAIN (mchain
);
6089 lookup_method_static (tree interface
, tree ident
, int is_class
)
6091 tree meth
= NULL_TREE
, root_inter
= NULL_TREE
;
6092 tree inter
= interface
;
6096 tree chain
= is_class
? CLASS_CLS_METHODS (inter
) : CLASS_NST_METHODS (inter
);
6097 tree category
= inter
;
6099 /* First, look up the method in the class itself. */
6100 if ((meth
= lookup_method (chain
, ident
)))
6103 /* Failing that, look for the method in each category of the class. */
6104 while ((category
= CLASS_CATEGORY_LIST (category
)))
6106 chain
= is_class
? CLASS_CLS_METHODS (category
) : CLASS_NST_METHODS (category
);
6108 /* Check directly in each category. */
6109 if ((meth
= lookup_method (chain
, ident
)))
6112 /* Failing that, check in each category's protocols. */
6113 if (CLASS_PROTOCOL_LIST (category
))
6115 if ((meth
= (lookup_method_in_protocol_list
6116 (CLASS_PROTOCOL_LIST (category
), ident
, is_class
))))
6121 /* If not found in categories, check in protocols of the main class. */
6122 if (CLASS_PROTOCOL_LIST (inter
))
6124 if ((meth
= (lookup_method_in_protocol_list
6125 (CLASS_PROTOCOL_LIST (inter
), ident
, is_class
))))
6129 /* Failing that, climb up the inheritance hierarchy. */
6131 inter
= lookup_interface (CLASS_SUPER_NAME (inter
));
6135 /* If no class (factory) method was found, check if an _instance_
6136 method of the same name exists in the root class. This is what
6137 the Objective-C runtime will do. If an instance method was not
6139 return is_class
? lookup_method_static (root_inter
, ident
, 0): NULL_TREE
;
6142 /* Add the method to the hash list if it doesn't contain an identical
6145 add_method_to_hash_list (hash
*hash_list
, tree method
)
6149 if (!(hsh
= hash_lookup (hash_list
, METHOD_SEL_NAME (method
))))
6151 /* Install on a global chain. */
6152 hash_enter (hash_list
, method
);
6156 /* Check types against those; if different, add to a list. */
6158 int already_there
= comp_proto_with_proto (method
, hsh
->key
);
6159 for (loop
= hsh
->list
; !already_there
&& loop
; loop
= loop
->next
)
6160 already_there
|= comp_proto_with_proto (method
, loop
->value
);
6162 hash_add_attr (hsh
, method
);
6167 objc_add_method (tree
class, tree method
, int is_class
)
6171 if (!(mth
= lookup_method (is_class
6172 ? CLASS_CLS_METHODS (class)
6173 : CLASS_NST_METHODS (class), method
)))
6175 /* put method on list in reverse order */
6178 TREE_CHAIN (method
) = CLASS_CLS_METHODS (class);
6179 CLASS_CLS_METHODS (class) = method
;
6183 TREE_CHAIN (method
) = CLASS_NST_METHODS (class);
6184 CLASS_NST_METHODS (class) = method
;
6189 /* When processing an @interface for a class or category, give hard
6190 errors on methods with identical selectors but differing argument
6191 and/or return types. We do not do this for @implementations, because
6192 C/C++ will do it for us (i.e., there will be duplicate function
6193 definition errors). */
6194 if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
6195 || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
)
6196 && !comp_proto_with_proto (method
, mth
))
6197 error ("duplicate declaration of method `%c%s'",
6198 is_class
? '+' : '-',
6199 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
6203 add_method_to_hash_list (cls_method_hash_list
, method
);
6206 add_method_to_hash_list (nst_method_hash_list
, method
);
6208 /* Instance methods in root classes (and categories thereof)
6209 may act as class methods as a last resort. We also add
6210 instance methods listed in @protocol declarations to
6211 the class hash table, on the assumption that @protocols
6212 may be adopted by root classes or categories. */
6213 if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
6214 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6215 class = lookup_interface (CLASS_NAME (class));
6217 if (TREE_CODE (class) == PROTOCOL_INTERFACE_TYPE
6218 || !CLASS_SUPER_NAME (class))
6219 add_method_to_hash_list (cls_method_hash_list
, method
);
6226 add_class (tree
class)
6228 /* Put interfaces on list in reverse order. */
6229 TREE_CHAIN (class) = interface_chain
;
6230 interface_chain
= class;
6231 return interface_chain
;
6235 add_category (tree
class, tree category
)
6237 /* Put categories on list in reverse order. */
6238 tree cat
= lookup_category (class, CLASS_SUPER_NAME (category
));
6242 warning ("duplicate interface declaration for category `%s(%s)'",
6243 IDENTIFIER_POINTER (CLASS_NAME (class)),
6244 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category
)));
6248 CLASS_CATEGORY_LIST (category
) = CLASS_CATEGORY_LIST (class);
6249 CLASS_CATEGORY_LIST (class) = category
;
6253 /* Called after parsing each instance variable declaration. Necessary to
6254 preserve typedefs and implement public/private...
6256 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
6259 add_instance_variable (tree
class, int public, tree field_decl
)
6261 tree field_type
= TREE_TYPE (field_decl
);
6262 const char *ivar_name
= DECL_NAME (field_decl
)
6263 ? IDENTIFIER_POINTER (DECL_NAME (field_decl
))
6267 if (TREE_CODE (field_type
) == REFERENCE_TYPE
)
6269 error ("illegal reference type specified for instance variable `%s'",
6271 /* Return class as is without adding this ivar. */
6276 if (field_type
== error_mark_node
|| !TYPE_SIZE (field_type
)
6277 || TYPE_SIZE (field_type
) == error_mark_node
)
6278 /* 'type[0]' is allowed, but 'type[]' is not! */
6280 error ("instance variable `%s' has unknown size", ivar_name
);
6281 /* Return class as is without adding this ivar. */
6286 /* zlaski 2001-Apr-24: C++ classes with non-trivial constructors and/or destructors
6287 cannot be ivars; ditto for classes with vtables. */
6288 if(IS_AGGR_TYPE (field_type
) && (TYPE_NEEDS_CONSTRUCTING (field_type
)
6289 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type
) || TYPE_POLYMORPHIC_P (field_type
)))
6291 const char *type_name
= IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type
));
6292 if(TYPE_POLYMORPHIC_P (field_type
)) {
6293 /* vtable pointers are Real Bad(tm), since Obj-C cannot initialize them */
6294 error ("type `%s' has virtual member functions", type_name
);
6295 error ("illegal aggregate type `%s' specified for instance variable `%s'",
6296 type_name
, ivar_name
);
6297 /* Return class as is without adding this ivar. */
6300 /* user-defined constructors and destructors are not known to Obj-C and
6301 hence will not be called. This may or may not be a problem. */
6302 if (TYPE_NEEDS_CONSTRUCTING (field_type
))
6303 warning ("type `%s' has a user-defined constructor", type_name
);
6304 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type
))
6305 warning ("type `%s' has a user-defined destructor", type_name
);
6306 warning ("C++ constructors and destructors will not be invoked for Objective-C fields");
6310 /* Overload the public attribute, it is not used for FIELD_DECLs. */
6314 TREE_PUBLIC (field_decl
) = 0;
6315 TREE_PRIVATE (field_decl
) = 0;
6316 TREE_PROTECTED (field_decl
) = 1;
6320 TREE_PUBLIC (field_decl
) = 1;
6321 TREE_PRIVATE (field_decl
) = 0;
6322 TREE_PROTECTED (field_decl
) = 0;
6326 TREE_PUBLIC (field_decl
) = 0;
6327 TREE_PRIVATE (field_decl
) = 1;
6328 TREE_PROTECTED (field_decl
) = 0;
6333 CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), field_decl
);
6339 is_ivar (tree decl_chain
, tree ident
)
6341 for ( ; decl_chain
; decl_chain
= TREE_CHAIN (decl_chain
))
6342 if (DECL_NAME (decl_chain
) == ident
)
6347 /* True if the ivar is private and we are not in its implementation. */
6350 is_private (tree decl
)
6352 return (TREE_PRIVATE (decl
)
6353 && ! is_ivar (CLASS_IVARS (implementation_template
),
6357 /* We have an instance variable reference;, check to see if it is public. */
6360 objc_is_public (tree expr
, tree identifier
)
6362 tree basetype
= TREE_TYPE (expr
);
6363 enum tree_code code
= TREE_CODE (basetype
);
6366 if (code
== RECORD_TYPE
)
6368 if (TREE_STATIC_TEMPLATE (basetype
))
6370 if (!lookup_interface (OBJC_TYPE_NAME (basetype
)))
6372 error ("cannot find interface declaration for `%s'",
6373 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype
)));
6377 if ((decl
= is_ivar (TYPE_FIELDS (basetype
), identifier
)))
6379 if (TREE_PUBLIC (decl
))
6382 /* Important difference between the Stepstone translator:
6383 all instance variables should be public within the context
6384 of the implementation. */
6385 if (objc_implementation_context
6386 && (((TREE_CODE (objc_implementation_context
)
6387 == CLASS_IMPLEMENTATION_TYPE
)
6388 || (TREE_CODE (objc_implementation_context
)
6389 == CATEGORY_IMPLEMENTATION_TYPE
))
6390 && (CLASS_NAME (objc_implementation_context
)
6391 == OBJC_TYPE_NAME (basetype
))))
6393 int private = is_private (decl
);
6396 error ("instance variable `%s' is declared private",
6397 IDENTIFIER_POINTER (DECL_NAME (decl
)));
6401 /* The 2.95.2 compiler sometimes allowed C functions to access
6402 non-@public ivars. We will let this slide for now... */
6403 if (!objc_method_context
)
6405 warning ("instance variable `%s' is %s; "
6406 "this will be a hard error in the future",
6407 IDENTIFIER_POINTER (identifier
),
6408 TREE_PRIVATE (decl
) ? "@private" : "@protected");
6412 error ("instance variable `%s' is declared %s",
6413 IDENTIFIER_POINTER (identifier
),
6414 TREE_PRIVATE (decl
) ? "private" : "protected");
6419 else if (objc_implementation_context
&& (basetype
== objc_object_reference
))
6421 expr
= convert (uprivate_record
, expr
);
6422 warning ("static access to object of type `id'");
6429 /* Make sure all entries in CHAIN are also in LIST. */
6432 check_methods (tree chain
, tree list
, int mtype
)
6438 if (!lookup_method (list
, chain
))
6442 if (TREE_CODE (objc_implementation_context
)
6443 == CLASS_IMPLEMENTATION_TYPE
)
6444 warning ("incomplete implementation of class `%s'",
6445 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
)));
6446 else if (TREE_CODE (objc_implementation_context
)
6447 == CATEGORY_IMPLEMENTATION_TYPE
)
6448 warning ("incomplete implementation of category `%s'",
6449 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
6453 warning ("method definition for `%c%s' not found",
6454 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
6457 chain
= TREE_CHAIN (chain
);
6463 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
6466 conforms_to_protocol (tree
class, tree protocol
)
6468 if (TREE_CODE (protocol
) == PROTOCOL_INTERFACE_TYPE
)
6470 tree p
= CLASS_PROTOCOL_LIST (class);
6471 while (p
&& TREE_VALUE (p
) != protocol
)
6476 tree super
= (CLASS_SUPER_NAME (class)
6477 ? lookup_interface (CLASS_SUPER_NAME (class))
6479 int tmp
= super
? conforms_to_protocol (super
, protocol
) : 0;
6488 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
6489 CONTEXT. This is one of two mechanisms to check protocol integrity. */
6492 check_methods_accessible (tree chain
, tree context
, int mtype
)
6496 tree base_context
= context
;
6500 context
= base_context
;
6504 list
= CLASS_CLS_METHODS (context
);
6506 list
= CLASS_NST_METHODS (context
);
6508 if (lookup_method (list
, chain
))
6511 else if (TREE_CODE (context
) == CLASS_IMPLEMENTATION_TYPE
6512 || TREE_CODE (context
) == CLASS_INTERFACE_TYPE
)
6513 context
= (CLASS_SUPER_NAME (context
)
6514 ? lookup_interface (CLASS_SUPER_NAME (context
))
6517 else if (TREE_CODE (context
) == CATEGORY_IMPLEMENTATION_TYPE
6518 || TREE_CODE (context
) == CATEGORY_INTERFACE_TYPE
)
6519 context
= (CLASS_NAME (context
)
6520 ? lookup_interface (CLASS_NAME (context
))
6526 if (context
== NULL_TREE
)
6530 if (TREE_CODE (objc_implementation_context
)
6531 == CLASS_IMPLEMENTATION_TYPE
)
6532 warning ("incomplete implementation of class `%s'",
6534 (CLASS_NAME (objc_implementation_context
)));
6535 else if (TREE_CODE (objc_implementation_context
)
6536 == CATEGORY_IMPLEMENTATION_TYPE
)
6537 warning ("incomplete implementation of category `%s'",
6539 (CLASS_SUPER_NAME (objc_implementation_context
)));
6542 warning ("method definition for `%c%s' not found",
6543 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
6546 chain
= TREE_CHAIN (chain
); /* next method... */
6551 /* Check whether the current interface (accessible via
6552 'objc_implementation_context') actually implements protocol P, along
6553 with any protocols that P inherits. */
6556 check_protocol (tree p
, const char *type
, const char *name
)
6558 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
6562 /* Ensure that all protocols have bodies! */
6565 f1
= check_methods (PROTOCOL_CLS_METHODS (p
),
6566 CLASS_CLS_METHODS (objc_implementation_context
),
6568 f2
= check_methods (PROTOCOL_NST_METHODS (p
),
6569 CLASS_NST_METHODS (objc_implementation_context
),
6574 f1
= check_methods_accessible (PROTOCOL_CLS_METHODS (p
),
6575 objc_implementation_context
,
6577 f2
= check_methods_accessible (PROTOCOL_NST_METHODS (p
),
6578 objc_implementation_context
,
6583 warning ("%s `%s' does not fully implement the `%s' protocol",
6584 type
, name
, IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
6587 /* Check protocols recursively. */
6588 if (PROTOCOL_LIST (p
))
6590 tree subs
= PROTOCOL_LIST (p
);
6592 lookup_interface (CLASS_SUPER_NAME (implementation_template
));
6596 tree sub
= TREE_VALUE (subs
);
6598 /* If the superclass does not conform to the protocols
6599 inherited by P, then we must! */
6600 if (!super_class
|| !conforms_to_protocol (super_class
, sub
))
6601 check_protocol (sub
, type
, name
);
6602 subs
= TREE_CHAIN (subs
);
6607 /* Check whether the current interface (accessible via
6608 'objc_implementation_context') actually implements the protocols listed
6612 check_protocols (tree proto_list
, const char *type
, const char *name
)
6614 for ( ; proto_list
; proto_list
= TREE_CHAIN (proto_list
))
6616 tree p
= TREE_VALUE (proto_list
);
6618 check_protocol (p
, type
, name
);
6622 /* Make sure that the class CLASS_NAME is defined
6623 CODE says which kind of thing CLASS_NAME ought to be.
6624 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6625 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6628 start_class (enum tree_code code
, tree class_name
, tree super_name
,
6634 if (current_namespace
!= global_namespace
) {
6635 error ("Objective-C declarations may only appear in global scope");
6637 #endif /* OBJCPLUS */
6639 if (objc_implementation_context
)
6641 warning ("`@end' missing in implementation context");
6642 finish_class (objc_implementation_context
);
6643 objc_ivar_chain
= NULL_TREE
;
6644 objc_implementation_context
= NULL_TREE
;
6647 class = make_node (code
);
6648 TYPE_LANG_SLOT_1 (class) = make_tree_vec (CLASS_LANG_SLOT_ELTS
);
6650 /* Check for existence of the super class, if one was specified. */
6651 if ((code
== CLASS_INTERFACE_TYPE
|| code
== CLASS_IMPLEMENTATION_TYPE
)
6652 && super_name
&& !objc_is_class_name (super_name
))
6654 error ("cannot find interface declaration for `%s', superclass of `%s'",
6655 IDENTIFIER_POINTER (super_name
),
6656 IDENTIFIER_POINTER (class_name
));
6657 super_name
= NULL_TREE
;
6660 CLASS_NAME (class) = class_name
;
6661 CLASS_SUPER_NAME (class) = super_name
;
6662 CLASS_CLS_METHODS (class) = NULL_TREE
;
6664 if (! objc_is_class_name (class_name
)
6665 && (decl
= lookup_name (class_name
)))
6667 error ("`%s' redeclared as different kind of symbol",
6668 IDENTIFIER_POINTER (class_name
));
6669 error ("%Jprevious declaration of '%D'",
6673 if (code
== CLASS_IMPLEMENTATION_TYPE
)
6678 for (chain
= implemented_classes
; chain
; chain
= TREE_CHAIN (chain
))
6679 if (TREE_VALUE (chain
) == class_name
)
6681 error ("reimplementation of class `%s'",
6682 IDENTIFIER_POINTER (class_name
));
6683 return error_mark_node
;
6685 implemented_classes
= tree_cons (NULL_TREE
, class_name
,
6686 implemented_classes
);
6689 /* Reset for multiple classes per file. */
6692 objc_implementation_context
= class;
6694 /* Lookup the interface for this implementation. */
6696 if (!(implementation_template
= lookup_interface (class_name
)))
6698 warning ("cannot find interface declaration for `%s'",
6699 IDENTIFIER_POINTER (class_name
));
6700 add_class (implementation_template
= objc_implementation_context
);
6703 /* If a super class has been specified in the implementation,
6704 insure it conforms to the one specified in the interface. */
6707 && (super_name
!= CLASS_SUPER_NAME (implementation_template
)))
6709 tree previous_name
= CLASS_SUPER_NAME (implementation_template
);
6710 const char *const name
=
6711 previous_name
? IDENTIFIER_POINTER (previous_name
) : "";
6712 error ("conflicting super class name `%s'",
6713 IDENTIFIER_POINTER (super_name
));
6714 error ("previous declaration of `%s'", name
);
6717 else if (! super_name
)
6719 CLASS_SUPER_NAME (objc_implementation_context
)
6720 = CLASS_SUPER_NAME (implementation_template
);
6724 else if (code
== CLASS_INTERFACE_TYPE
)
6726 if (lookup_interface (class_name
))
6728 error ("duplicate interface declaration for class `%s'",
6730 warning ("duplicate interface declaration for class `%s'",
6732 IDENTIFIER_POINTER (class_name
));
6737 CLASS_PROTOCOL_LIST (class)
6738 = lookup_and_install_protocols (protocol_list
);
6741 else if (code
== CATEGORY_INTERFACE_TYPE
)
6743 tree class_category_is_assoc_with
;
6745 /* For a category, class_name is really the name of the class that
6746 the following set of methods will be associated with. We must
6747 find the interface so that can derive the objects template. */
6749 if (!(class_category_is_assoc_with
= lookup_interface (class_name
)))
6751 error ("cannot find interface declaration for `%s'",
6752 IDENTIFIER_POINTER (class_name
));
6753 exit (FATAL_EXIT_CODE
);
6756 add_category (class_category_is_assoc_with
, class);
6759 CLASS_PROTOCOL_LIST (class)
6760 = lookup_and_install_protocols (protocol_list
);
6763 else if (code
== CATEGORY_IMPLEMENTATION_TYPE
)
6765 /* Reset for multiple classes per file. */
6768 objc_implementation_context
= class;
6770 /* For a category, class_name is really the name of the class that
6771 the following set of methods will be associated with. We must
6772 find the interface so that can derive the objects template. */
6774 if (!(implementation_template
= lookup_interface (class_name
)))
6776 error ("cannot find interface declaration for `%s'",
6777 IDENTIFIER_POINTER (class_name
));
6778 exit (FATAL_EXIT_CODE
);
6785 continue_class (tree
class)
6787 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6788 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6790 struct imp_entry
*imp_entry
;
6793 /* Check consistency of the instance variables. */
6795 if (CLASS_RAW_IVARS (class))
6796 check_ivars (implementation_template
, class);
6798 /* code generation */
6801 push_lang_context (lang_name_c
);
6804 ivar_context
= build_private_template (implementation_template
);
6806 imp_entry
= (struct imp_entry
*) ggc_alloc (sizeof (struct imp_entry
));
6808 imp_entry
->next
= imp_list
;
6809 imp_entry
->imp_context
= class;
6810 imp_entry
->imp_template
= implementation_template
;
6812 synth_forward_declarations ();
6813 imp_entry
->class_decl
= UOBJC_CLASS_decl
;
6814 imp_entry
->meta_decl
= UOBJC_METACLASS_decl
;
6816 /* Append to front and increment count. */
6817 imp_list
= imp_entry
;
6818 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6824 pop_lang_context ();
6825 #endif /* OBJCPLUS */
6827 return ivar_context
;
6830 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6833 push_lang_context (lang_name_c
);
6834 #endif /* OBJCPLUS */
6836 if (!CLASS_STATIC_TEMPLATE (class))
6838 tree record
= start_struct (RECORD_TYPE
, CLASS_NAME (class));
6839 finish_struct (record
, get_class_ivars (class), NULL_TREE
);
6840 CLASS_STATIC_TEMPLATE (class) = record
;
6842 /* Mark this record as a class template for static typing. */
6843 TREE_STATIC_TEMPLATE (record
) = 1;
6847 pop_lang_context ();
6848 #endif /* OBJCPLUS */
6854 return error_mark_node
;
6857 /* This is called once we see the "@end" in an interface/implementation. */
6860 finish_class (tree
class)
6862 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6864 /* All code generation is done in finish_objc. */
6866 if (implementation_template
!= objc_implementation_context
)
6868 /* Ensure that all method listed in the interface contain bodies. */
6869 check_methods (CLASS_CLS_METHODS (implementation_template
),
6870 CLASS_CLS_METHODS (objc_implementation_context
), '+');
6871 check_methods (CLASS_NST_METHODS (implementation_template
),
6872 CLASS_NST_METHODS (objc_implementation_context
), '-');
6874 if (CLASS_PROTOCOL_LIST (implementation_template
))
6875 check_protocols (CLASS_PROTOCOL_LIST (implementation_template
),
6877 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
)));
6881 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6883 tree category
= lookup_category (implementation_template
, CLASS_SUPER_NAME (class));
6887 /* Ensure all method listed in the interface contain bodies. */
6888 check_methods (CLASS_CLS_METHODS (category
),
6889 CLASS_CLS_METHODS (objc_implementation_context
), '+');
6890 check_methods (CLASS_NST_METHODS (category
),
6891 CLASS_NST_METHODS (objc_implementation_context
), '-');
6893 if (CLASS_PROTOCOL_LIST (category
))
6894 check_protocols (CLASS_PROTOCOL_LIST (category
),
6896 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
6900 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6903 const char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (class));
6904 char *string
= (char *) alloca (strlen (class_name
) + 3);
6906 /* extern struct objc_object *_<my_name>; */
6908 sprintf (string
, "_%s", class_name
);
6910 decl
= build_decl (VAR_DECL
, get_identifier (string
),
6911 build_pointer_type (objc_object_reference
));
6912 DECL_EXTERNAL (decl
) = 1;
6913 lang_hooks
.decls
.pushdecl (decl
);
6914 finish_decl (decl
, NULL_TREE
, NULL_TREE
);
6919 add_protocol (tree protocol
)
6921 /* Put protocol on list in reverse order. */
6922 TREE_CHAIN (protocol
) = protocol_chain
;
6923 protocol_chain
= protocol
;
6924 return protocol_chain
;
6928 lookup_protocol (tree ident
)
6932 for (chain
= protocol_chain
; chain
; chain
= TREE_CHAIN (chain
))
6933 if (ident
== PROTOCOL_NAME (chain
))
6939 /* This function forward declares the protocols named by NAMES. If
6940 they are already declared or defined, the function has no effect. */
6943 objc_declare_protocols (tree names
)
6948 if (current_namespace
!= global_namespace
) {
6949 error ("Objective-C declarations may only appear in global scope");
6951 #endif /* OBJCPLUS */
6953 for (list
= names
; list
; list
= TREE_CHAIN (list
))
6955 tree name
= TREE_VALUE (list
);
6957 if (lookup_protocol (name
) == NULL_TREE
)
6959 tree protocol
= make_node (PROTOCOL_INTERFACE_TYPE
);
6961 TYPE_LANG_SLOT_1 (protocol
)
6962 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS
);
6963 PROTOCOL_NAME (protocol
) = name
;
6964 PROTOCOL_LIST (protocol
) = NULL_TREE
;
6965 add_protocol (protocol
);
6966 PROTOCOL_DEFINED (protocol
) = 0;
6967 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6973 start_protocol (enum tree_code code
, tree name
, tree list
)
6978 if (current_namespace
!= global_namespace
) {
6979 error ("Objective-C declarations may only appear in global scope");
6981 #endif /* OBJCPLUS */
6983 protocol
= lookup_protocol (name
);
6987 protocol
= make_node (code
);
6988 TYPE_LANG_SLOT_1 (protocol
) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS
);
6990 PROTOCOL_NAME (protocol
) = name
;
6991 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
6992 add_protocol (protocol
);
6993 PROTOCOL_DEFINED (protocol
) = 1;
6994 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6996 check_protocol_recursively (protocol
, list
);
6998 else if (! PROTOCOL_DEFINED (protocol
))
7000 PROTOCOL_DEFINED (protocol
) = 1;
7001 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
7003 check_protocol_recursively (protocol
, list
);
7007 warning ("duplicate declaration for protocol `%s'",
7008 IDENTIFIER_POINTER (name
));
7014 /* "Encode" a data type into a string, which grows in util_obstack.
7015 ??? What is the FORMAT? Someone please document this! */
7018 encode_type_qualifiers (tree declspecs
)
7022 for (spec
= declspecs
; spec
; spec
= TREE_CHAIN (spec
))
7024 if (ridpointers
[(int) RID_IN
] == TREE_VALUE (spec
))
7025 obstack_1grow (&util_obstack
, 'n');
7026 else if (ridpointers
[(int) RID_INOUT
] == TREE_VALUE (spec
))
7027 obstack_1grow (&util_obstack
, 'N');
7028 else if (ridpointers
[(int) RID_OUT
] == TREE_VALUE (spec
))
7029 obstack_1grow (&util_obstack
, 'o');
7030 else if (ridpointers
[(int) RID_BYCOPY
] == TREE_VALUE (spec
))
7031 obstack_1grow (&util_obstack
, 'O');
7032 else if (ridpointers
[(int) RID_BYREF
] == TREE_VALUE (spec
))
7033 obstack_1grow (&util_obstack
, 'R');
7034 else if (ridpointers
[(int) RID_ONEWAY
] == TREE_VALUE (spec
))
7035 obstack_1grow (&util_obstack
, 'V');
7039 /* Encode a pointer type. */
7042 encode_pointer (tree type
, int curtype
, int format
)
7044 tree pointer_to
= TREE_TYPE (type
);
7046 if (TREE_CODE (pointer_to
) == RECORD_TYPE
)
7048 if (OBJC_TYPE_NAME (pointer_to
)
7049 && TREE_CODE (OBJC_TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
)
7051 const char *name
= IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to
));
7053 if (strcmp (name
, TAG_OBJECT
) == 0) /* '@' */
7055 obstack_1grow (&util_obstack
, '@');
7058 else if (TREE_STATIC_TEMPLATE (pointer_to
))
7060 if (generating_instance_variables
)
7062 obstack_1grow (&util_obstack
, '@');
7063 obstack_1grow (&util_obstack
, '"');
7064 obstack_grow (&util_obstack
, name
, strlen (name
));
7065 obstack_1grow (&util_obstack
, '"');
7070 obstack_1grow (&util_obstack
, '@');
7074 else if (strcmp (name
, TAG_CLASS
) == 0) /* '#' */
7076 obstack_1grow (&util_obstack
, '#');
7079 else if (strcmp (name
, TAG_SELECTOR
) == 0) /* ':' */
7081 obstack_1grow (&util_obstack
, ':');
7086 else if (TREE_CODE (pointer_to
) == INTEGER_TYPE
7087 && TYPE_MODE (pointer_to
) == QImode
)
7089 tree pname
= TREE_CODE (OBJC_TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
7090 ? OBJC_TYPE_NAME (pointer_to
)
7091 : DECL_NAME (OBJC_TYPE_NAME (pointer_to
));
7093 if (!flag_next_runtime
|| strcmp (IDENTIFIER_POINTER (pname
), "BOOL"))
7095 /* It appears that "r*" means "const char *" rather than
7097 if (TYPE_READONLY (pointer_to
))
7098 obstack_1grow (&util_obstack
, 'r');
7100 obstack_1grow (&util_obstack
, '*');
7105 /* We have a type that does not get special treatment. */
7107 /* NeXT extension */
7108 obstack_1grow (&util_obstack
, '^');
7109 encode_type (pointer_to
, curtype
, format
);
7113 encode_array (tree type
, int curtype
, int format
)
7115 tree an_int_cst
= TYPE_SIZE (type
);
7116 tree array_of
= TREE_TYPE (type
);
7119 /* An incomplete array is treated like a pointer. */
7120 if (an_int_cst
== NULL
)
7122 encode_pointer (type
, curtype
, format
);
7126 sprintf (buffer
, "[" HOST_WIDE_INT_PRINT_DEC
,
7127 (TREE_INT_CST_LOW (an_int_cst
)
7128 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
7130 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7131 encode_type (array_of
, curtype
, format
);
7132 obstack_1grow (&util_obstack
, ']');
7137 encode_aggregate_within (tree type
, int curtype
, int format
, int left
,
7141 /* NB: aggregates that are pointed to have slightly different encoding
7142 rules in that you never encode the names of instance variables. */
7144 = (obstack_object_size (&util_obstack
) > 0
7145 && *(obstack_next_free (&util_obstack
) - 1) == '^');
7147 = ((format
== OBJC_ENCODE_INLINE_DEFS
|| generating_instance_variables
)
7148 && (!pointed_to
|| obstack_object_size (&util_obstack
) - curtype
== 1));
7150 /* Traverse struct aliases; it is important to get the
7151 original struct and its tag name (if any). */
7152 type
= TYPE_MAIN_VARIANT (type
);
7153 name
= OBJC_TYPE_NAME (type
);
7154 /* Open parenth/bracket. */
7155 obstack_1grow (&util_obstack
, left
);
7157 /* Encode the struct/union tag name, or '?' if a tag was
7158 not provided. Typedef aliases do not qualify. */
7159 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
7161 /* Did this struct have a tag? */
7162 && !TYPE_WAS_ANONYMOUS (type
)
7165 obstack_grow (&util_obstack
,
7166 IDENTIFIER_POINTER (name
),
7167 strlen (IDENTIFIER_POINTER (name
)));
7169 obstack_1grow (&util_obstack
, '?');
7171 /* Encode the types (and possibly names) of the inner fields,
7173 if (inline_contents
)
7175 tree fields
= TYPE_FIELDS (type
);
7177 obstack_1grow (&util_obstack
, '=');
7178 for (; fields
; fields
= TREE_CHAIN (fields
))
7181 /* C++ static members, and things that are not fields at all,
7182 should not appear in the encoding. */
7183 if (TREE_CODE (fields
) != FIELD_DECL
|| TREE_STATIC (fields
))
7186 if (generating_instance_variables
&& !pointed_to
)
7188 tree fname
= DECL_NAME (fields
);
7190 obstack_1grow (&util_obstack
, '"');
7191 if (fname
&& TREE_CODE (fname
) == IDENTIFIER_NODE
)
7192 obstack_grow (&util_obstack
,
7193 IDENTIFIER_POINTER (fname
),
7194 strlen (IDENTIFIER_POINTER (fname
)));
7195 obstack_1grow (&util_obstack
, '"');
7197 encode_field_decl (fields
, curtype
, format
);
7200 /* Close parenth/bracket. */
7201 obstack_1grow (&util_obstack
, right
);
7205 encode_aggregate (tree type
, int curtype
, int format
)
7207 enum tree_code code
= TREE_CODE (type
);
7213 encode_aggregate_within (type
, curtype
, format
, '{', '}');
7218 encode_aggregate_within (type
, curtype
, format
, '(', ')');
7223 obstack_1grow (&util_obstack
, 'i');
7231 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
7235 encode_next_bitfield (int width
)
7238 sprintf (buffer
, "b%d", width
);
7239 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7242 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
7244 encode_type (tree type
, int curtype
, int format
)
7246 enum tree_code code
= TREE_CODE (type
);
7249 if (TYPE_READONLY (type
))
7250 obstack_1grow (&util_obstack
, 'r');
7252 if (code
== INTEGER_TYPE
)
7254 switch (GET_MODE_BITSIZE (TYPE_MODE (type
)))
7256 case 8: c
= TYPE_UNSIGNED (type
) ? 'C' : 'c'; break;
7257 case 16: c
= TYPE_UNSIGNED (type
) ? 'S' : 's'; break;
7259 if (type
== long_unsigned_type_node
7260 || type
== long_integer_type_node
)
7261 c
= TYPE_UNSIGNED (type
) ? 'L' : 'l';
7263 c
= TYPE_UNSIGNED (type
) ? 'I' : 'i';
7265 case 64: c
= TYPE_UNSIGNED (type
) ? 'Q' : 'q'; break;
7268 obstack_1grow (&util_obstack
, c
);
7271 else if (code
== REAL_TYPE
)
7273 /* Floating point types. */
7274 switch (GET_MODE_BITSIZE (TYPE_MODE (type
)))
7276 case 32: c
= 'f'; break;
7278 case 128: c
= 'd'; break;
7281 obstack_1grow (&util_obstack
, c
);
7284 else if (code
== VOID_TYPE
)
7285 obstack_1grow (&util_obstack
, 'v');
7287 else if (code
== BOOLEAN_TYPE
)
7288 obstack_1grow (&util_obstack
, 'B');
7290 else if (code
== ARRAY_TYPE
)
7291 encode_array (type
, curtype
, format
);
7293 else if (code
== POINTER_TYPE
)
7294 encode_pointer (type
, curtype
, format
);
7296 else if (code
== RECORD_TYPE
|| code
== UNION_TYPE
|| code
== ENUMERAL_TYPE
)
7297 encode_aggregate (type
, curtype
, format
);
7299 else if (code
== FUNCTION_TYPE
) /* '?' */
7300 obstack_1grow (&util_obstack
, '?');
7304 encode_gnu_bitfield (int position
, tree type
, int size
)
7306 enum tree_code code
= TREE_CODE (type
);
7308 char charType
= '?';
7310 if (code
== INTEGER_TYPE
)
7312 if (integer_zerop (TYPE_MIN_VALUE (type
)))
7314 /* Unsigned integer types. */
7316 if (TYPE_MODE (type
) == QImode
)
7318 else if (TYPE_MODE (type
) == HImode
)
7320 else if (TYPE_MODE (type
) == SImode
)
7322 if (type
== long_unsigned_type_node
)
7327 else if (TYPE_MODE (type
) == DImode
)
7332 /* Signed integer types. */
7334 if (TYPE_MODE (type
) == QImode
)
7336 else if (TYPE_MODE (type
) == HImode
)
7338 else if (TYPE_MODE (type
) == SImode
)
7340 if (type
== long_integer_type_node
)
7346 else if (TYPE_MODE (type
) == DImode
)
7350 else if (code
== ENUMERAL_TYPE
)
7355 sprintf (buffer
, "b%d%c%d", position
, charType
, size
);
7356 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7360 encode_field_decl (tree field_decl
, int curtype
, int format
)
7365 /* C++ static members, and things that are not fields at all,
7366 should not appear in the encoding. */
7367 if (TREE_CODE (field_decl
) != FIELD_DECL
|| TREE_STATIC (field_decl
))
7371 type
= TREE_TYPE (field_decl
);
7373 /* Generate the bitfield typing information, if needed. Note the difference
7374 between GNU and NeXT runtimes. */
7375 if (DECL_BIT_FIELD_TYPE (field_decl
))
7377 int size
= tree_low_cst (DECL_SIZE (field_decl
), 1);
7379 if (flag_next_runtime
)
7380 encode_next_bitfield (size
);
7382 encode_gnu_bitfield (int_bit_position (field_decl
),
7383 DECL_BIT_FIELD_TYPE (field_decl
), size
);
7386 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
7389 static GTY(()) tree objc_parmlist
= NULL_TREE
;
7391 /* Append PARM to a list of formal parameters of a method, making a necessary
7392 array-to-pointer adjustment along the way. */
7395 objc_push_parm (tree parm
)
7397 /* Convert array parameters of unknown size into pointers. */
7398 if (TREE_CODE (TREE_TYPE (parm
)) == ARRAY_TYPE
7399 && !TYPE_SIZE (TREE_TYPE (parm
)))
7400 TREE_TYPE (parm
) = build_pointer_type (TREE_TYPE (TREE_TYPE (parm
)));
7402 objc_parmlist
= chainon (objc_parmlist
, parm
);
7405 /* Retrieve the formal parameter list constructed via preceding calls to
7406 objc_push_parm(). */
7410 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED
)
7412 static struct c_arg_info
*
7413 objc_get_parm_info (int have_ellipsis
)
7417 tree parm_info
= objc_parmlist
;
7418 objc_parmlist
= NULL_TREE
;
7422 tree parm_info
= objc_parmlist
;
7423 struct c_arg_info
*arg_info
;
7424 /* The C front-end requires an elaborate song and dance at
7427 declare_parm_level ();
7430 tree next
= TREE_CHAIN (parm_info
);
7432 TREE_CHAIN (parm_info
) = NULL_TREE
;
7433 pushdecl (parm_info
);
7436 arg_info
= get_parm_info (have_ellipsis
);
7438 objc_parmlist
= NULL_TREE
;
7443 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
7444 method definitions. In the case of instance methods, we can be more
7445 specific as to the type of 'self'. */
7448 synth_self_and_ucmd_args (void)
7452 if (objc_method_context
7453 && TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
)
7454 self_type
= objc_instance_type
;
7456 /* Really a `struct objc_class *'. However, we allow people to
7457 assign to self, which changes its type midstream. */
7458 self_type
= objc_object_type
;
7461 objc_push_parm (build_decl (PARM_DECL
, self_id
, self_type
));
7464 objc_push_parm (build_decl (PARM_DECL
, ucmd_id
, objc_selector_type
));
7467 /* Transform an Objective-C method definition into a static C function
7468 definition, synthesizing the first two arguments, "self" and "_cmd",
7472 start_method_def (tree method
)
7478 struct c_arg_info
*parm_info
;
7480 int have_ellipsis
= 0;
7482 /* Required to implement _msgSuper. */
7483 objc_method_context
= method
;
7484 UOBJC_SUPER_decl
= NULL_TREE
;
7486 /* Generate prototype declarations for arguments..."new-style". */
7487 synth_self_and_ucmd_args ();
7489 /* Generate argument declarations if a keyword_decl. */
7490 parmlist
= METHOD_SEL_ARGS (method
);
7493 tree parm
= build_decl (PARM_DECL
, KEYWORD_ARG_NAME (parmlist
),
7494 TREE_VALUE (TREE_TYPE (parmlist
)));
7496 objc_push_parm (parm
);
7497 parmlist
= TREE_CHAIN (parmlist
);
7500 if (METHOD_ADD_ARGS (method
))
7504 for (akey
= TREE_CHAIN (METHOD_ADD_ARGS (method
));
7505 akey
; akey
= TREE_CHAIN (akey
))
7507 objc_push_parm (TREE_VALUE (akey
));
7510 if (TREE_OVERFLOW (METHOD_ADD_ARGS (method
)))
7514 parm_info
= objc_get_parm_info (have_ellipsis
);
7516 really_start_method (objc_method_context
, parm_info
);
7520 warn_with_method (const char *message
, int mtype
, tree method
)
7522 /* Add a readable method name to the warning. */
7523 warning ("%J%s `%c%s'", method
,
7524 message
, mtype
, gen_method_decl (method
));
7527 /* Return 1 if TYPE1 is equivalent to TYPE2
7528 for purposes of method overloading. */
7531 objc_types_are_equivalent (tree type1
, tree type2
)
7536 /* Strip away indirections. */
7537 while ((TREE_CODE (type1
) == ARRAY_TYPE
|| TREE_CODE (type1
) == POINTER_TYPE
)
7538 && (TREE_CODE (type1
) == TREE_CODE (type2
)))
7539 type1
= TREE_TYPE (type1
), type2
= TREE_TYPE (type2
);
7540 if (TYPE_MAIN_VARIANT (type1
) != TYPE_MAIN_VARIANT (type2
))
7543 type1
= TYPE_PROTOCOL_LIST (type1
);
7544 type2
= TYPE_PROTOCOL_LIST (type2
);
7545 if (list_length (type1
) == list_length (type2
))
7547 for (; type2
; type2
= TREE_CHAIN (type2
))
7548 if (!lookup_protocol_in_reflist (type1
, TREE_VALUE (type2
)))
7555 /* Return 1 if PROTO1 is equivalent to PROTO2
7556 for purposes of method overloading. */
7559 comp_proto_with_proto (tree proto1
, tree proto2
)
7563 /* The following test is needed in case there are hashing
7565 if (METHOD_SEL_NAME (proto1
) != METHOD_SEL_NAME (proto2
))
7568 /* Compare return types. */
7569 type1
= TREE_VALUE (TREE_TYPE (proto1
));
7570 type2
= TREE_VALUE (TREE_TYPE (proto2
));
7572 if (!objc_types_are_equivalent (type1
, type2
))
7575 /* Compare argument types. */
7576 for (type1
= get_arg_type_list (proto1
, METHOD_REF
, 0),
7577 type2
= get_arg_type_list (proto2
, METHOD_REF
, 0);
7579 type1
= TREE_CHAIN (type1
), type2
= TREE_CHAIN (type2
))
7581 if (!objc_types_are_equivalent (TREE_VALUE (type1
), TREE_VALUE (type2
)))
7585 return (!type1
&& !type2
);
7588 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
7589 this occurs. ObjC method dispatches are _not_ like C++ virtual
7590 member function dispatches, and we account for the difference here. */
7593 objc_fold_obj_type_ref (tree ref
, tree known_type
)
7595 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED
,
7596 tree known_type ATTRIBUTE_UNUSED
)
7600 tree v
= BINFO_VIRTUALS (TYPE_BINFO (known_type
));
7602 /* If the receiver does not have virtual member functions, there
7603 is nothing we can (or need to) do here. */
7607 /* Let C++ handle C++ virtual functions. */
7608 return cp_fold_obj_type_ref (ref
, known_type
);
7610 /* For plain ObjC, we currently do not need to do anything. */
7616 objc_start_function (tree name
, tree type
, tree attrs
,
7620 struct c_arg_info
*params
7624 tree fndecl
= build_decl (FUNCTION_DECL
, name
, type
);
7627 DECL_ARGUMENTS (fndecl
) = params
;
7629 DECL_INITIAL (fndecl
) = error_mark_node
;
7630 DECL_EXTERNAL (fndecl
) = 0;
7631 TREE_STATIC (fndecl
) = 1;
7634 retrofit_lang_decl (fndecl
);
7635 cplus_decl_attributes (&fndecl
, attrs
, 0);
7636 start_preparsed_function (fndecl
, attrs
, /*flags=*/SF_DEFAULT
);
7638 decl_attributes (&fndecl
, attrs
, 0);
7639 announce_function (fndecl
);
7640 current_function_decl
= pushdecl (fndecl
);
7642 declare_parm_level ();
7643 DECL_RESULT (current_function_decl
)
7644 = build_decl (RESULT_DECL
, NULL_TREE
,
7645 TREE_TYPE (TREE_TYPE (current_function_decl
)));
7646 start_fname_decls ();
7647 store_parm_decls_from (params
);
7650 TREE_USED (current_function_decl
) = 1;
7653 /* - Generate an identifier for the function. the format is "_n_cls",
7654 where 1 <= n <= nMethods, and cls is the name the implementation we
7656 - Install the return type from the method declaration.
7657 - If we have a prototype, check for type consistency. */
7660 really_start_method (tree method
,
7664 struct c_arg_info
*parmlist
7668 tree ret_type
, meth_type
;
7670 const char *sel_name
, *class_name
, *cat_name
;
7673 /* Synth the storage class & assemble the return type. */
7674 ret_type
= TREE_VALUE (TREE_TYPE (method
));
7676 sel_name
= IDENTIFIER_POINTER (METHOD_SEL_NAME (method
));
7677 class_name
= IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
7678 cat_name
= ((TREE_CODE (objc_implementation_context
)
7679 == CLASS_IMPLEMENTATION_TYPE
)
7681 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
7684 /* Make sure this is big enough for any plausible method label. */
7685 buf
= (char *) alloca (50 + strlen (sel_name
) + strlen (class_name
)
7686 + (cat_name
? strlen (cat_name
) : 0));
7688 OBJC_GEN_METHOD_LABEL (buf
, TREE_CODE (method
) == INSTANCE_METHOD_DECL
,
7689 class_name
, cat_name
, sel_name
, method_slot
);
7691 method_id
= get_identifier (buf
);
7694 /* Objective-C methods cannot be overloaded, so we don't need
7695 the type encoding appended. It looks bad anyway... */
7696 push_lang_context (lang_name_c
);
7700 = build_function_type (ret_type
,
7701 get_arg_type_list (method
, METHOD_DEF
, 0));
7702 objc_start_function (method_id
, meth_type
, NULL_TREE
, parmlist
);
7704 /* Set self_decl from the first argument. */
7705 self_decl
= DECL_ARGUMENTS (current_function_decl
);
7707 /* Suppress unused warnings. */
7708 TREE_USED (self_decl
) = 1;
7709 TREE_USED (TREE_CHAIN (self_decl
)) = 1;
7711 pop_lang_context ();
7714 METHOD_DEFINITION (method
) = current_function_decl
;
7716 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7718 if (implementation_template
!= objc_implementation_context
)
7721 = lookup_method_static (implementation_template
,
7722 METHOD_SEL_NAME (method
),
7723 TREE_CODE (method
) == CLASS_METHOD_DECL
);
7727 if (!comp_proto_with_proto (method
, proto
))
7729 char type
= (TREE_CODE (method
) == INSTANCE_METHOD_DECL
? '-' : '+');
7731 warn_with_method ("conflicting types for", type
, method
);
7732 warn_with_method ("previous declaration of", type
, proto
);
7737 /* We have a method @implementation even though we did not
7738 see a corresponding @interface declaration (which is allowed
7739 by Objective-C rules). Go ahead and place the method in
7740 the @interface anyway, so that message dispatch lookups
7742 tree interface
= implementation_template
;
7744 if (TREE_CODE (objc_implementation_context
)
7745 == CATEGORY_IMPLEMENTATION_TYPE
)
7746 interface
= lookup_category
7748 CLASS_SUPER_NAME (objc_implementation_context
));
7751 objc_add_method (interface
, copy_node (method
),
7752 TREE_CODE (method
) == CLASS_METHOD_DECL
);
7757 static void *UOBJC_SUPER_scope
= 0;
7759 /* _n_Method (id self, SEL sel, ...)
7761 struct objc_super _S;
7762 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7766 get_super_receiver (void)
7768 if (objc_method_context
)
7770 tree super_expr
, super_expr_list
;
7772 if (!UOBJC_SUPER_decl
)
7774 UOBJC_SUPER_decl
= build_decl (VAR_DECL
, get_identifier (TAG_SUPER
),
7775 objc_super_template
);
7776 /* This prevents `unused variable' warnings when compiling with -Wall. */
7777 TREE_USED (UOBJC_SUPER_decl
) = 1;
7778 lang_hooks
.decls
.pushdecl (UOBJC_SUPER_decl
);
7779 finish_decl (UOBJC_SUPER_decl
, NULL_TREE
, NULL_TREE
);
7780 UOBJC_SUPER_scope
= objc_get_current_scope ();
7783 /* Set receiver to self. */
7784 super_expr
= build_component_ref (UOBJC_SUPER_decl
, self_id
);
7785 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, self_decl
);
7786 super_expr_list
= super_expr
;
7788 /* Set class to begin searching. */
7789 super_expr
= build_component_ref (UOBJC_SUPER_decl
,
7790 get_identifier ("super_class"));
7792 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
7794 /* [_cls, __cls]Super are "pre-built" in
7795 synth_forward_declarations. */
7797 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
,
7798 ((TREE_CODE (objc_method_context
)
7799 == INSTANCE_METHOD_DECL
)
7801 : uucls_super_ref
));
7805 /* We have a category. */
7807 tree super_name
= CLASS_SUPER_NAME (implementation_template
);
7810 /* Barf if super used in a category of Object. */
7813 error ("no super class declared in interface for `%s'",
7814 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
7815 return error_mark_node
;
7818 if (flag_next_runtime
&& !flag_zero_link
)
7820 super_class
= objc_get_class_reference (super_name
);
7821 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
7822 /* If we are in a class method, we must retrieve the
7823 _metaclass_ for the current class, pointed at by
7824 the class's "isa" pointer. The following assumes that
7825 "isa" is the first ivar in a class (which it must be). */
7827 = build_indirect_ref
7828 (build_c_cast (build_pointer_type (objc_class_type
),
7829 super_class
), "unary *");
7833 add_class_reference (super_name
);
7834 super_class
= (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
7835 ? objc_get_class_decl
: objc_get_meta_class_decl
);
7836 assemble_external (super_class
);
7838 = build_function_call
7842 my_build_string (IDENTIFIER_LENGTH (super_name
) + 1,
7843 IDENTIFIER_POINTER (super_name
))));
7847 = build_modify_expr (super_expr
, NOP_EXPR
,
7848 build_c_cast (TREE_TYPE (super_expr
),
7852 super_expr_list
= build_compound_expr (super_expr_list
, super_expr
);
7854 super_expr
= build_unary_op (ADDR_EXPR
, UOBJC_SUPER_decl
, 0);
7855 super_expr_list
= build_compound_expr (super_expr_list
, super_expr
);
7857 return super_expr_list
;
7861 error ("[super ...] must appear in a method context");
7862 return error_mark_node
;
7866 /* When exiting a scope, sever links to a 'super' declaration (if any)
7867 therein contained. */
7870 objc_clear_super_receiver (void)
7872 if (objc_method_context
7873 && UOBJC_SUPER_scope
== objc_get_current_scope ()) {
7874 UOBJC_SUPER_decl
= 0;
7875 UOBJC_SUPER_scope
= 0;
7880 objc_finish_method_definition (tree fndecl
)
7882 /* We cannot validly inline ObjC methods, at least not without a language
7883 extension to declare that a method need not be dynamically
7884 dispatched, so suppress all thoughts of doing so. */
7885 DECL_INLINE (fndecl
) = 0;
7886 DECL_UNINLINABLE (fndecl
) = 1;
7889 /* The C++ front-end will have called finish_function() for us. */
7893 METHOD_ENCODING (objc_method_context
)
7894 = encode_method_prototype (objc_method_context
);
7896 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7897 since the optimizer may find "may be used before set" errors. */
7898 objc_method_context
= NULL_TREE
;
7903 lang_report_error_function (tree decl
)
7905 if (objc_method_context
)
7907 fprintf (stderr
, "In method `%s'\n",
7908 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context
)));
7917 /* Given a tree DECL node, produce a printable description of it in the given
7918 buffer, overwriting the buffer. */
7921 gen_declaration (tree decl
)
7927 gen_type_name_0 (TREE_TYPE (decl
));
7929 if (DECL_NAME (decl
))
7931 if (!POINTER_TYPE_P (TREE_TYPE (decl
)))
7932 strcat (errbuf
, " ");
7934 strcat (errbuf
, IDENTIFIER_POINTER (DECL_NAME (decl
)));
7937 if (DECL_INITIAL (decl
)
7938 && TREE_CODE (DECL_INITIAL (decl
)) == INTEGER_CST
)
7939 sprintf (errbuf
+ strlen (errbuf
), ": " HOST_WIDE_INT_PRINT_DEC
,
7940 TREE_INT_CST_LOW (DECL_INITIAL (decl
)));
7946 /* Given a tree TYPE node, produce a printable description of it in the given
7947 buffer, overwriting the buffer. */
7950 gen_type_name_0 (tree type
)
7952 tree orig
= type
, proto
;
7954 if (TYPE_P (type
) && TYPE_NAME (type
))
7955 type
= TYPE_NAME (type
);
7956 else if (POINTER_TYPE_P (type
))
7958 gen_type_name_0 (TREE_TYPE (type
));
7960 if (!POINTER_TYPE_P (TREE_TYPE (type
)))
7961 strcat (errbuf
, " ");
7963 strcat (errbuf
, "*");
7967 if (TREE_CODE (type
) == TYPE_DECL
&& DECL_NAME (type
))
7968 type
= DECL_NAME (type
);
7970 strcat (errbuf
, IDENTIFIER_POINTER (type
));
7971 proto
= TYPE_PROTOCOL_LIST (orig
);
7975 strcat (errbuf
, " <");
7979 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto
))));
7980 proto
= TREE_CHAIN (proto
);
7981 strcat (errbuf
, proto
? ", " : ">");
7990 gen_type_name (tree type
)
7994 return gen_type_name_0 (type
);
7997 /* Given a method tree, put a printable description into the given
7998 buffer (overwriting) and return a pointer to the buffer. */
8001 gen_method_decl (tree method
)
8005 strcpy (errbuf
, "("); /* NB: Do _not_ call strcat() here. */
8006 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method
)));
8007 strcat (errbuf
, ")");
8008 chain
= METHOD_SEL_ARGS (method
);
8012 /* We have a chain of keyword_decls. */
8015 if (KEYWORD_KEY_NAME (chain
))
8016 strcat (errbuf
, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain
)));
8018 strcat (errbuf
, ":(");
8019 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain
)));
8020 strcat (errbuf
, ")");
8022 strcat (errbuf
, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain
)));
8023 if ((chain
= TREE_CHAIN (chain
)))
8024 strcat (errbuf
, " ");
8028 if (METHOD_ADD_ARGS (method
))
8030 chain
= TREE_CHAIN (METHOD_ADD_ARGS (method
));
8032 /* Know we have a chain of parm_decls. */
8035 strcat (errbuf
, ", ");
8036 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain
)));
8037 chain
= TREE_CHAIN (chain
);
8040 if (TREE_OVERFLOW (METHOD_ADD_ARGS (method
)))
8041 strcat (errbuf
, ", ...");
8046 /* We have a unary selector. */
8047 strcat (errbuf
, IDENTIFIER_POINTER (METHOD_SEL_NAME (method
)));
8055 /* Dump an @interface declaration of the supplied class CHAIN to the
8056 supplied file FP. Used to implement the -gen-decls option (which
8057 prints out an @interface declaration of all classes compiled in
8058 this run); potentially useful for debugging the compiler too. */
8060 dump_interface (FILE *fp
, tree chain
)
8062 /* FIXME: A heap overflow here whenever a method (or ivar)
8063 declaration is so long that it doesn't fit in the buffer. The
8064 code and all the related functions should be rewritten to avoid
8065 using fixed size buffers. */
8066 const char *my_name
= IDENTIFIER_POINTER (CLASS_NAME (chain
));
8067 tree ivar_decls
= CLASS_RAW_IVARS (chain
);
8068 tree nst_methods
= CLASS_NST_METHODS (chain
);
8069 tree cls_methods
= CLASS_CLS_METHODS (chain
);
8071 fprintf (fp
, "\n@interface %s", my_name
);
8073 /* CLASS_SUPER_NAME is used to store the superclass name for
8074 classes, and the category name for categories. */
8075 if (CLASS_SUPER_NAME (chain
))
8077 const char *name
= IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain
));
8079 if (TREE_CODE (chain
) == CATEGORY_IMPLEMENTATION_TYPE
8080 || TREE_CODE (chain
) == CATEGORY_INTERFACE_TYPE
)
8082 fprintf (fp
, " (%s)\n", name
);
8086 fprintf (fp
, " : %s\n", name
);
8092 /* FIXME - the following doesn't seem to work at the moment. */
8095 fprintf (fp
, "{\n");
8098 fprintf (fp
, "\t%s;\n", gen_declaration (ivar_decls
));
8099 ivar_decls
= TREE_CHAIN (ivar_decls
);
8102 fprintf (fp
, "}\n");
8107 fprintf (fp
, "- %s;\n", gen_method_decl (nst_methods
));
8108 nst_methods
= TREE_CHAIN (nst_methods
);
8113 fprintf (fp
, "+ %s;\n", gen_method_decl (cls_methods
));
8114 cls_methods
= TREE_CHAIN (cls_methods
);
8117 fprintf (fp
, "@end\n");
8120 /* Demangle function for Objective-C */
8122 objc_demangle (const char *mangled
)
8124 char *demangled
, *cp
;
8126 if (mangled
[0] == '_' &&
8127 (mangled
[1] == 'i' || mangled
[1] == 'c') &&
8130 cp
= demangled
= xmalloc(strlen(mangled
) + 2);
8131 if (mangled
[1] == 'i')
8132 *cp
++ = '-'; /* for instance method */
8134 *cp
++ = '+'; /* for class method */
8135 *cp
++ = '['; /* opening left brace */
8136 strcpy(cp
, mangled
+3); /* tack on the rest of the mangled name */
8137 while (*cp
&& *cp
== '_')
8138 cp
++; /* skip any initial underbars in class name */
8139 cp
= strchr(cp
, '_'); /* find first non-initial underbar */
8142 free(demangled
); /* not mangled name */
8145 if (cp
[1] == '_') /* easy case: no category name */
8147 *cp
++ = ' '; /* replace two '_' with one ' ' */
8148 strcpy(cp
, mangled
+ (cp
- demangled
) + 2);
8152 *cp
++ = '('; /* less easy case: category name */
8153 cp
= strchr(cp
, '_');
8156 free(demangled
); /* not mangled name */
8160 *cp
++ = ' '; /* overwriting 1st char of method name... */
8161 strcpy(cp
, mangled
+ (cp
- demangled
)); /* get it back */
8163 while (*cp
&& *cp
== '_')
8164 cp
++; /* skip any initial underbars in method name */
8167 *cp
= ':'; /* replace remaining '_' with ':' */
8168 *cp
++ = ']'; /* closing right brace */
8169 *cp
++ = 0; /* string terminator */
8173 return mangled
; /* not an objc mangled name */
8177 objc_printable_name (tree decl
, int kind ATTRIBUTE_UNUSED
)
8179 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl
)));
8185 gcc_obstack_init (&util_obstack
);
8186 util_firstobj
= (char *) obstack_finish (&util_obstack
);
8188 errbuf
= (char *) xmalloc (1024 * 10);
8190 synth_module_prologue ();
8196 struct imp_entry
*impent
;
8198 /* The internally generated initializers appear to have missing braces.
8199 Don't warn about this. */
8200 int save_warn_missing_braces
= warn_missing_braces
;
8201 warn_missing_braces
= 0;
8203 /* A missing @end may not be detected by the parser. */
8204 if (objc_implementation_context
)
8206 warning ("`@end' missing in implementation context");
8207 finish_class (objc_implementation_context
);
8208 objc_ivar_chain
= NULL_TREE
;
8209 objc_implementation_context
= NULL_TREE
;
8212 /* Process the static instances here because initialization of objc_symtab
8214 if (objc_static_instances
)
8215 generate_static_references ();
8217 if (imp_list
|| class_names_chain
8218 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8219 generate_objc_symtab_decl ();
8221 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8223 objc_implementation_context
= impent
->imp_context
;
8224 implementation_template
= impent
->imp_template
;
8226 UOBJC_CLASS_decl
= impent
->class_decl
;
8227 UOBJC_METACLASS_decl
= impent
->meta_decl
;
8229 /* Dump the @interface of each class as we compile it, if the
8230 -gen-decls option is in use. TODO: Dump the classes in the
8231 order they were found, rather than in reverse order as we
8233 if (flag_gen_declaration
)
8235 dump_interface (gen_declaration_file
, objc_implementation_context
);
8238 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
8240 /* all of the following reference the string pool... */
8241 generate_ivar_lists ();
8242 generate_dispatch_tables ();
8243 generate_shared_structures ();
8247 generate_dispatch_tables ();
8248 generate_category (objc_implementation_context
);
8252 /* If we are using an array of selectors, we must always
8253 finish up the array decl even if no selectors were used. */
8254 if (! flag_next_runtime
|| sel_ref_chain
)
8255 build_selector_translation_table ();
8258 generate_protocols ();
8260 if (flag_replace_objc_classes
&& imp_list
)
8261 generate_objc_image_info ();
8263 /* Arrange for ObjC data structures to be initialized at run time. */
8264 if (objc_implementation_context
|| class_names_chain
|| objc_static_instances
8265 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8267 build_module_descriptor ();
8269 if (!flag_next_runtime
)
8270 build_module_initializer_routine ();
8273 /* Dump the class references. This forces the appropriate classes
8274 to be linked into the executable image, preserving unix archive
8275 semantics. This can be removed when we move to a more dynamically
8276 linked environment. */
8278 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
8280 handle_class_ref (chain
);
8281 if (TREE_PURPOSE (chain
))
8282 generate_classref_translation_entry (chain
);
8285 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8286 handle_impent (impent
);
8288 /* Dump the string table last. */
8290 generate_strings ();
8297 /* Run through the selector hash tables and print a warning for any
8298 selector which has multiple methods. */
8300 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8302 for (hsh
= cls_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8303 check_duplicates (hsh
, 0, 1);
8304 for (hsh
= nst_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8305 check_duplicates (hsh
, 0, 1);
8309 warn_missing_braces
= save_warn_missing_braces
;
8312 /* Subroutines of finish_objc. */
8315 generate_classref_translation_entry (tree chain
)
8317 tree expr
, decl
, type
;
8319 decl
= TREE_PURPOSE (chain
);
8320 type
= TREE_TYPE (decl
);
8322 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
8323 expr
= convert (type
, expr
); /* cast! */
8325 /* The decl that is the one that we
8326 forward declared in build_class_reference. */
8327 finish_var_decl (decl
, expr
);
8332 handle_class_ref (tree chain
)
8334 const char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
8335 char *string
= (char *) alloca (strlen (name
) + 30);
8339 sprintf (string
, "%sobjc_class_name_%s",
8340 (flag_next_runtime
? "." : "__"), name
);
8342 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8343 if (flag_next_runtime
)
8345 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file
, string
);
8350 /* Make a decl for this name, so we can use its address in a tree. */
8351 decl
= build_decl (VAR_DECL
, get_identifier (string
), char_type_node
);
8352 DECL_EXTERNAL (decl
) = 1;
8353 TREE_PUBLIC (decl
) = 1;
8356 rest_of_decl_compilation (decl
, 0, 0);
8358 /* Make a decl for the address. */
8359 sprintf (string
, "%sobjc_class_ref_%s",
8360 (flag_next_runtime
? "." : "__"), name
);
8361 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
8362 decl
= build_decl (VAR_DECL
, get_identifier (string
), string_type_node
);
8363 DECL_INITIAL (decl
) = exp
;
8364 TREE_STATIC (decl
) = 1;
8365 TREE_USED (decl
) = 1;
8368 rest_of_decl_compilation (decl
, 0, 0);
8372 handle_impent (struct imp_entry
*impent
)
8376 objc_implementation_context
= impent
->imp_context
;
8377 implementation_template
= impent
->imp_template
;
8379 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
8381 const char *const class_name
=
8382 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8384 string
= (char *) alloca (strlen (class_name
) + 30);
8386 sprintf (string
, "%sobjc_class_name_%s",
8387 (flag_next_runtime
? "." : "__"), class_name
);
8389 else if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
8391 const char *const class_name
=
8392 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8393 const char *const class_super_name
=
8394 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
8396 string
= (char *) alloca (strlen (class_name
)
8397 + strlen (class_super_name
) + 30);
8399 /* Do the same for categories. Even though no references to
8400 these symbols are generated automatically by the compiler, it
8401 gives you a handle to pull them into an archive by hand. */
8402 sprintf (string
, "*%sobjc_category_name_%s_%s",
8403 (flag_next_runtime
? "." : "__"), class_name
, class_super_name
);
8408 #ifdef ASM_DECLARE_CLASS_REFERENCE
8409 if (flag_next_runtime
)
8411 ASM_DECLARE_CLASS_REFERENCE (asm_out_file
, string
);
8419 init
= build_int_cst (c_common_type_for_size (BITS_PER_WORD
, 1), 0);
8420 decl
= build_decl (VAR_DECL
, get_identifier (string
), TREE_TYPE (init
));
8421 TREE_PUBLIC (decl
) = 1;
8422 TREE_READONLY (decl
) = 1;
8423 TREE_USED (decl
) = 1;
8424 TREE_CONSTANT (decl
) = 1;
8425 DECL_CONTEXT (decl
) = 0;
8426 DECL_ARTIFICIAL (decl
) = 1;
8427 DECL_INITIAL (decl
) = init
;
8428 assemble_variable (decl
, 1, 0, 0);
8432 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
8433 later requires that ObjC translation units participating in F&C be
8434 specially marked. The following routine accomplishes this. */
8436 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
8439 generate_objc_image_info (void)
8441 tree decl
, initlist
;
8443 decl
= start_var_decl (build_array_type
8445 build_index_type (build_int_cst (NULL_TREE
, 2 - 1))),
8446 "_OBJC_IMAGE_INFO");
8448 initlist
= build_tree_list (NULL_TREE
, build_int_cst (NULL_TREE
, 0));
8449 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 1), initlist
);
8450 initlist
= objc_build_constructor (TREE_TYPE (decl
), nreverse (initlist
));
8452 finish_var_decl (decl
, initlist
);
8455 /* Look up ID as an instance variable. */
8458 objc_lookup_ivar (tree id
)
8462 if (objc_method_context
&& !strcmp (IDENTIFIER_POINTER (id
), "super"))
8463 /* We have a message to super. */
8464 return get_super_receiver ();
8465 else if (objc_method_context
&& (decl
= is_ivar (objc_ivar_chain
, id
)))
8467 if (is_private (decl
))
8470 return build_ivar_reference (id
);
8476 #include "gt-objc-objc-act.h"