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_ID (lhs
);
870 int rhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (rhs
);
874 tree lproto
, lproto_list
= TYPE_PROTOCOL_LIST (lhs
);
875 tree rproto
, rproto_list
;
878 /* <Protocol> = <Protocol> */
881 rproto_list
= TYPE_PROTOCOL_LIST (rhs
);
885 /* An assignment between objects of type 'id
886 <Protocol>'; make sure the protocol on the lhs is
887 supported by the object on the rhs. */
888 for (lproto
= lproto_list
; lproto
;
889 lproto
= TREE_CHAIN (lproto
))
891 p
= TREE_VALUE (lproto
);
892 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
896 ("object does not conform to the `%s' protocol",
897 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
903 /* Obscure case - a comparison between two objects
904 of type 'id <Protocol>'. Check that either the
905 protocol on the lhs is supported by the object on
906 the rhs, or viceversa. */
908 /* Check if the protocol on the lhs is supported by the
909 object on the rhs. */
910 for (lproto
= lproto_list
; lproto
;
911 lproto
= TREE_CHAIN (lproto
))
913 p
= TREE_VALUE (lproto
);
914 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
918 /* Check failed - check if the protocol on the rhs
919 is supported by the object on the lhs. */
920 for (rproto
= rproto_list
; rproto
;
921 rproto
= TREE_CHAIN (rproto
))
923 p
= TREE_VALUE (rproto
);
924 lproto
= lookup_protocol_in_reflist (lproto_list
,
929 /* This check failed too: incompatible */
939 /* <Protocol> = <class> * */
940 else if (TYPED_OBJECT (TREE_TYPE (rhs
)))
942 tree rname
= OBJC_TYPE_NAME (TREE_TYPE (rhs
));
945 /* Make sure the protocol is supported by the object on
947 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
949 p
= TREE_VALUE (lproto
);
951 rinter
= lookup_interface (rname
);
953 while (rinter
&& !rproto
)
957 rproto_list
= CLASS_PROTOCOL_LIST (rinter
);
958 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
959 /* If the underlying ObjC class does not have
960 the protocol we're looking for, check for "one-off"
961 protocols (e.g., `NSObject<MyProt> *foo;') attached
965 rproto_list
= TYPE_PROTOCOL_LIST (TREE_TYPE (rhs
));
966 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
969 /* Check for protocols adopted by categories. */
970 cat
= CLASS_CATEGORY_LIST (rinter
);
971 while (cat
&& !rproto
)
973 rproto_list
= CLASS_PROTOCOL_LIST (cat
);
974 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
975 cat
= CLASS_CATEGORY_LIST (cat
);
978 rinter
= lookup_interface (CLASS_SUPER_NAME (rinter
));
982 warning ("class `%s' does not implement the `%s' protocol",
983 IDENTIFIER_POINTER (OBJC_TYPE_NAME (TREE_TYPE (rhs
))),
984 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
988 /* <Protocol> = id */
989 else if (objc_is_object_id (TREE_TYPE (rhs
)))
993 /* <Protocol> = Class */
994 else if (objc_is_class_id (TREE_TYPE (rhs
)))
998 /* <Protocol> = ?? : let comptypes decide. */
1001 else if (rhs_is_proto
)
1003 /* <class> * = <Protocol> */
1004 if (TYPED_OBJECT (TREE_TYPE (lhs
)))
1008 tree rname
= OBJC_TYPE_NAME (TREE_TYPE (lhs
));
1010 tree rproto
, rproto_list
= TYPE_PROTOCOL_LIST (rhs
);
1012 /* Make sure the protocol is supported by the object on
1014 for (rproto
= rproto_list
; rproto
;
1015 rproto
= TREE_CHAIN (rproto
))
1017 tree p
= TREE_VALUE (rproto
);
1019 rinter
= lookup_interface (rname
);
1021 while (rinter
&& !lproto
)
1025 tree lproto_list
= CLASS_PROTOCOL_LIST (rinter
);
1026 lproto
= lookup_protocol_in_reflist (lproto_list
, p
);
1027 /* If the underlying ObjC class does not
1028 have the protocol we're looking for,
1029 check for "one-off" protocols (e.g.,
1030 `NSObject<MyProt> *foo;') attached to the
1034 lproto_list
= TYPE_PROTOCOL_LIST
1036 lproto
= lookup_protocol_in_reflist
1040 /* Check for protocols adopted by categories. */
1041 cat
= CLASS_CATEGORY_LIST (rinter
);
1042 while (cat
&& !lproto
)
1044 lproto_list
= CLASS_PROTOCOL_LIST (cat
);
1045 lproto
= lookup_protocol_in_reflist (lproto_list
,
1047 cat
= CLASS_CATEGORY_LIST (cat
);
1050 rinter
= lookup_interface (CLASS_SUPER_NAME
1055 warning ("class `%s' does not implement the `%s' protocol",
1056 IDENTIFIER_POINTER (OBJC_TYPE_NAME
1058 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
1065 /* id = <Protocol> */
1066 else if (objc_is_object_id (TREE_TYPE (lhs
)))
1070 /* Class = <Protocol> */
1071 else if (objc_is_class_id (TREE_TYPE (lhs
)))
1075 /* ??? = <Protocol> : let comptypes decide */
1083 /* Attention: we shouldn't defer to comptypes here. One bad
1084 side effect would be that we might loose the REFLEXIVE
1087 lhs
= TREE_TYPE (lhs
);
1088 rhs
= TREE_TYPE (rhs
);
1092 if (TREE_CODE (lhs
) != RECORD_TYPE
|| TREE_CODE (rhs
) != RECORD_TYPE
)
1094 /* Nothing to do with ObjC - let immediately comptypes take
1095 responsibility for checking. */
1099 /* `id' = `<class> *' `<class> *' = `id': always allow it.
1101 'Object *o = [[Object alloc] init]; falls
1102 in the case <class> * = `id'.
1104 if ((objc_is_object_id (lhs
) && TYPED_OBJECT (rhs
))
1105 || (objc_is_object_id (rhs
) && TYPED_OBJECT (lhs
)))
1108 /* `id' = `Class', `Class' = `id' */
1110 else if ((objc_is_object_id (lhs
) && objc_is_class_id (rhs
))
1111 || (objc_is_class_id (lhs
) && objc_is_object_id (rhs
)))
1114 /* `Class' != `<class> *' && `<class> *' != `Class'! */
1115 else if ((OBJC_TYPE_NAME (lhs
) == objc_class_id
&& TYPED_OBJECT (rhs
))
1116 || (OBJC_TYPE_NAME (rhs
) == objc_class_id
&& TYPED_OBJECT (lhs
)))
1119 /* `<class> *' = `<class> *' */
1121 else if (TYPED_OBJECT (lhs
) && TYPED_OBJECT (rhs
))
1123 tree lname
= OBJC_TYPE_NAME (lhs
);
1124 tree rname
= OBJC_TYPE_NAME (rhs
);
1130 /* If the left hand side is a super class of the right hand side,
1132 for (inter
= lookup_interface (rname
); inter
;
1133 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
1134 if (lname
== CLASS_SUPER_NAME (inter
))
1137 /* Allow the reverse when reflexive. */
1139 for (inter
= lookup_interface (lname
); inter
;
1140 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
1141 if (rname
== CLASS_SUPER_NAME (inter
))
1147 /* Not an ObjC type - let comptypes do the check. */
1151 /* Called from finish_decl. */
1154 objc_check_decl (tree decl
)
1156 tree type
= TREE_TYPE (decl
);
1158 if (TREE_CODE (type
) != RECORD_TYPE
)
1160 if (OBJC_TYPE_NAME (type
) && (type
= objc_is_class_name (OBJC_TYPE_NAME (type
))))
1161 error ("statically allocated instance of Objective-C class `%s'",
1162 IDENTIFIER_POINTER (type
));
1165 /* Construct a PROTOCOLS-qualified variant of INTERFACE, where INTERFACE may
1166 either name an Objective-C class, or refer to the special 'id' or 'Class'
1167 types. If INTERFACE is not a valid ObjC type, just return it unchanged. */
1170 objc_get_protocol_qualified_type (tree interface
, tree protocols
)
1175 type
= objc_object_type
;
1176 else if (!(type
= objc_is_id (interface
)))
1178 type
= objc_is_class_name (interface
);
1181 type
= xref_tag (RECORD_TYPE
, type
);
1188 type
= build_variant_type_copy (type
);
1189 /* Look up protocols and install in lang specific list. Note
1190 that the protocol list can have a different lifetime than T! */
1191 SET_TYPE_PROTOCOL_LIST (type
, lookup_and_install_protocols (protocols
));
1193 /* Establish the ObjC-ness of this record. */
1194 if (TREE_CODE (type
) == RECORD_TYPE
)
1195 TREE_STATIC_TEMPLATE (type
) = 1;
1201 /* Check for circular dependencies in protocols. The arguments are
1202 PROTO, the protocol to check, and LIST, a list of protocol it
1206 check_protocol_recursively (tree proto
, tree list
)
1210 for (p
= list
; p
; p
= TREE_CHAIN (p
))
1212 tree pp
= TREE_VALUE (p
);
1214 if (TREE_CODE (pp
) == IDENTIFIER_NODE
)
1215 pp
= lookup_protocol (pp
);
1218 fatal_error ("protocol `%s' has circular dependency",
1219 IDENTIFIER_POINTER (PROTOCOL_NAME (pp
)));
1221 check_protocol_recursively (proto
, PROTOCOL_LIST (pp
));
1225 /* Look up PROTOCOLS, and return a list of those that are found.
1226 If none are found, return NULL. */
1229 lookup_and_install_protocols (tree protocols
)
1232 tree return_value
= NULL_TREE
;
1234 for (proto
= protocols
; proto
; proto
= TREE_CHAIN (proto
))
1236 tree ident
= TREE_VALUE (proto
);
1237 tree p
= lookup_protocol (ident
);
1240 error ("cannot find protocol declaration for `%s'",
1241 IDENTIFIER_POINTER (ident
));
1243 return_value
= chainon (return_value
,
1244 build_tree_list (NULL_TREE
, p
));
1247 return return_value
;
1250 /* Create a declaration for field NAME of a given TYPE. */
1253 create_field_decl (tree type
, const char *name
)
1255 return build_decl (FIELD_DECL
, get_identifier (name
), type
);
1258 /* Create a global, static declaration for variable NAME of a given TYPE. The
1259 finish_var_decl() routine will need to be called on it afterwards. */
1262 start_var_decl (tree type
, const char *name
)
1264 tree var
= build_decl (VAR_DECL
, get_identifier (name
), type
);
1266 TREE_STATIC (var
) = 1;
1267 DECL_INITIAL (var
) = error_mark_node
; /* A real initializer is coming... */
1268 DECL_IGNORED_P (var
) = 1;
1269 DECL_ARTIFICIAL (var
) = 1;
1270 DECL_CONTEXT (var
) = NULL_TREE
;
1272 DECL_THIS_STATIC (var
) = 1; /* squash redeclaration errors */
1278 /* Finish off the variable declaration created by start_var_decl(). */
1281 finish_var_decl (tree var
, tree initializer
)
1283 finish_decl (var
, initializer
, NULL_TREE
);
1284 /* Ensure that the variable actually gets output. */
1285 mark_decl_referenced (var
);
1286 /* Mark the decl to avoid "defined but not used" warning. */
1287 TREE_USED (var
) = 1;
1290 /* Find the decl for the constant string class refernce. This is only
1291 used for the NeXT runtime. */
1294 setup_string_decl (void)
1299 /* %s in format will provide room for terminating null */
1300 length
= strlen (STRING_OBJECT_GLOBAL_FORMAT
)
1301 + strlen (constant_string_class_name
);
1302 name
= xmalloc (length
);
1303 sprintf (name
, STRING_OBJECT_GLOBAL_FORMAT
,
1304 constant_string_class_name
);
1305 constant_string_global_id
= get_identifier (name
);
1306 string_class_decl
= lookup_name (constant_string_global_id
);
1308 return string_class_decl
;
1311 /* Purpose: "play" parser, creating/installing representations
1312 of the declarations that are required by Objective-C.
1316 type_spec--------->sc_spec
1317 (tree_list) (tree_list)
1320 identifier_node identifier_node */
1323 synth_module_prologue (void)
1326 enum debug_info_type save_write_symbols
= write_symbols
;
1327 const struct gcc_debug_hooks
*const save_hooks
= debug_hooks
;
1329 /* Suppress outputting debug symbols, because
1330 dbxout_init hasn'r been called yet. */
1331 write_symbols
= NO_DEBUG
;
1332 debug_hooks
= &do_nothing_debug_hooks
;
1335 push_lang_context (lang_name_c
); /* extern "C" */
1338 /* The following are also defined in <objc/objc.h> and friends. */
1340 objc_object_id
= get_identifier (TAG_OBJECT
);
1341 objc_class_id
= get_identifier (TAG_CLASS
);
1343 objc_object_reference
= xref_tag (RECORD_TYPE
, objc_object_id
);
1344 objc_class_reference
= xref_tag (RECORD_TYPE
, objc_class_id
);
1346 objc_object_type
= build_pointer_type (objc_object_reference
);
1347 objc_class_type
= build_pointer_type (objc_class_reference
);
1349 objc_object_name
= get_identifier (OBJECT_TYPEDEF_NAME
);
1350 objc_class_name
= get_identifier (CLASS_TYPEDEF_NAME
);
1352 /* Declare the 'id' and 'Class' typedefs. */
1354 type
= lang_hooks
.decls
.pushdecl (build_decl (TYPE_DECL
,
1357 DECL_IN_SYSTEM_HEADER (type
) = 1;
1358 type
= lang_hooks
.decls
.pushdecl (build_decl (TYPE_DECL
,
1361 DECL_IN_SYSTEM_HEADER (type
) = 1;
1363 /* Forward-declare '@interface Protocol'. */
1365 type
= get_identifier (PROTOCOL_OBJECT_CLASS_NAME
);
1366 objc_declare_class (tree_cons (NULL_TREE
, type
, NULL_TREE
));
1367 objc_protocol_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
1370 /* Declare type of selector-objects that represent an operation name. */
1372 if (flag_next_runtime
)
1373 /* `struct objc_selector *' */
1375 = build_pointer_type (xref_tag (RECORD_TYPE
,
1376 get_identifier (TAG_SELECTOR
)));
1378 /* `const struct objc_selector *' */
1380 = build_pointer_type
1381 (build_qualified_type (xref_tag (RECORD_TYPE
,
1382 get_identifier (TAG_SELECTOR
)),
1385 /* Declare receiver type used for dispatching messages to 'super'. */
1387 /* `struct objc_super *' */
1388 objc_super_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
1389 get_identifier (TAG_SUPER
)));
1391 if (flag_next_runtime
)
1393 /* NB: In order to call one of the ..._stret (struct-returning)
1394 functions, the function *MUST* first be cast to a signature that
1395 corresponds to the actual ObjC method being invoked. This is
1396 what is done by the build_objc_method_call() routine below. */
1398 /* id objc_msgSend (id, SEL, ...); */
1399 /* id objc_msgSendNonNil (id, SEL, ...); */
1400 /* id objc_msgSend_stret (id, SEL, ...); */
1401 /* id objc_msgSendNonNil_stret (id, SEL, ...); */
1403 = build_function_type (objc_object_type
,
1404 tree_cons (NULL_TREE
, objc_object_type
,
1405 tree_cons (NULL_TREE
, objc_selector_type
,
1407 umsg_decl
= builtin_function (TAG_MSGSEND
,
1408 type
, 0, NOT_BUILT_IN
,
1410 umsg_nonnil_decl
= builtin_function (TAG_MSGSEND_NONNIL
,
1411 type
, 0, NOT_BUILT_IN
,
1413 umsg_stret_decl
= builtin_function (TAG_MSGSEND_STRET
,
1414 type
, 0, NOT_BUILT_IN
,
1416 umsg_nonnil_stret_decl
= builtin_function (TAG_MSGSEND_NONNIL_STRET
,
1417 type
, 0, NOT_BUILT_IN
,
1420 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1421 /* id objc_msgSendSuper_stret (struct objc_super *, SEL, ...); */
1423 = build_function_type (objc_object_type
,
1424 tree_cons (NULL_TREE
, objc_super_type
,
1425 tree_cons (NULL_TREE
, objc_selector_type
,
1427 umsg_super_decl
= builtin_function (TAG_MSGSENDSUPER
,
1428 type
, 0, NOT_BUILT_IN
,
1430 umsg_super_stret_decl
= builtin_function (TAG_MSGSENDSUPER_STRET
,
1431 type
, 0, NOT_BUILT_IN
, 0,
1436 /* GNU runtime messenger entry points. */
1438 /* typedef id (*IMP)(id, SEL, ...); */
1440 = build_pointer_type
1441 (build_function_type (objc_object_type
,
1442 tree_cons (NULL_TREE
, objc_object_type
,
1443 tree_cons (NULL_TREE
, objc_selector_type
,
1446 /* IMP objc_msg_lookup (id, SEL); */
1448 = build_function_type (IMP_type
,
1449 tree_cons (NULL_TREE
, objc_object_type
,
1450 tree_cons (NULL_TREE
, objc_selector_type
,
1451 OBJC_VOID_AT_END
)));
1452 umsg_decl
= builtin_function (TAG_MSGSEND
,
1453 type
, 0, NOT_BUILT_IN
,
1456 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
1458 = build_function_type (IMP_type
,
1459 tree_cons (NULL_TREE
, objc_super_type
,
1460 tree_cons (NULL_TREE
, objc_selector_type
,
1461 OBJC_VOID_AT_END
)));
1462 umsg_super_decl
= builtin_function (TAG_MSGSENDSUPER
,
1463 type
, 0, NOT_BUILT_IN
,
1466 /* The following GNU runtime entry point is called to initialize
1469 __objc_exec_class (void *); */
1471 = build_function_type (void_type_node
,
1472 tree_cons (NULL_TREE
, ptr_type_node
,
1474 execclass_decl
= builtin_function (TAG_EXECCLASS
,
1475 type
, 0, NOT_BUILT_IN
,
1479 /* id objc_getClass (const char *); */
1481 type
= build_function_type (objc_object_type
,
1482 tree_cons (NULL_TREE
,
1483 const_string_type_node
,
1487 = builtin_function (TAG_GETCLASS
, type
, 0, NOT_BUILT_IN
,
1490 /* id objc_getMetaClass (const char *); */
1492 objc_get_meta_class_decl
1493 = builtin_function (TAG_GETMETACLASS
, type
, 0, NOT_BUILT_IN
, NULL
, NULL_TREE
);
1495 build_class_template ();
1496 build_super_template ();
1497 build_protocol_template ();
1498 build_category_template ();
1499 build_objc_exception_stuff ();
1501 if (flag_next_runtime
)
1502 build_next_objc_exception_stuff ();
1504 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1506 if (! flag_next_runtime
)
1507 build_selector_table_decl ();
1509 /* Forward declare constant_string_id and constant_string_type. */
1510 if (!constant_string_class_name
)
1511 constant_string_class_name
= default_constant_string_class_name
;
1513 constant_string_id
= get_identifier (constant_string_class_name
);
1514 objc_declare_class (tree_cons (NULL_TREE
, constant_string_id
, NULL_TREE
));
1516 /* Pre-build the following entities - for speed/convenience. */
1517 self_id
= get_identifier ("self");
1518 ucmd_id
= get_identifier ("_cmd");
1520 /* The C++ front-end does not appear to grok __attribute__((__unused__)). */
1521 unused_list
= build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
1525 pop_lang_context ();
1528 write_symbols
= save_write_symbols
;
1529 debug_hooks
= save_hooks
;
1532 /* Ensure that the ivar list for NSConstantString/NXConstantString
1533 (or whatever was specified via `-fconstant-string-class')
1534 contains fields at least as large as the following three, so that
1535 the runtime can stomp on them with confidence:
1537 struct STRING_OBJECT_CLASS_NAME
1541 unsigned int length;
1545 check_string_class_template (void)
1547 tree field_decl
= TYPE_FIELDS (constant_string_type
);
1549 #define AT_LEAST_AS_LARGE_AS(F, T) \
1550 (F && TREE_CODE (F) == FIELD_DECL \
1551 && (TREE_INT_CST_LOW (DECL_SIZE (F)) \
1552 >= TREE_INT_CST_LOW (TYPE_SIZE (T))))
1554 if (!AT_LEAST_AS_LARGE_AS (field_decl
, ptr_type_node
))
1557 field_decl
= TREE_CHAIN (field_decl
);
1558 if (!AT_LEAST_AS_LARGE_AS (field_decl
, ptr_type_node
))
1561 field_decl
= TREE_CHAIN (field_decl
);
1562 return AT_LEAST_AS_LARGE_AS (field_decl
, unsigned_type_node
);
1564 #undef AT_LEAST_AS_LARGE_AS
1567 /* Avoid calling `check_string_class_template ()' more than once. */
1568 static GTY(()) int string_layout_checked
;
1570 /* Custom build_string which sets TREE_TYPE! */
1573 my_build_string (int len
, const char *str
)
1575 return fix_string_type (build_string (len
, str
));
1580 string_hash (const void *ptr
)
1582 tree str
= ((struct string_descriptor
*)ptr
)->literal
;
1583 const unsigned char *p
= (const unsigned char *) TREE_STRING_POINTER (str
);
1584 int i
, len
= TREE_STRING_LENGTH (str
);
1587 for (i
= 0; i
< len
; i
++)
1588 h
= ((h
* 613) + p
[i
]);
1594 string_eq (const void *ptr1
, const void *ptr2
)
1596 tree str1
= ((struct string_descriptor
*)ptr1
)->literal
;
1597 tree str2
= ((struct string_descriptor
*)ptr2
)->literal
;
1598 int len1
= TREE_STRING_LENGTH (str1
);
1600 return (len1
== TREE_STRING_LENGTH (str2
)
1601 && !memcmp (TREE_STRING_POINTER (str1
), TREE_STRING_POINTER (str2
),
1605 /* Given a chain of STRING_CST's, build a static instance of
1606 NXConstantString which points at the concatenation of those
1607 strings. We place the string object in the __string_objects
1608 section of the __OBJC segment. The Objective-C runtime will
1609 initialize the isa pointers of the string objects to point at the
1610 NXConstantString class object. */
1613 objc_build_string_object (tree string
)
1615 tree initlist
, constructor
, constant_string_class
;
1618 struct string_descriptor
*desc
, key
;
1621 /* Prep the string argument. */
1622 string
= fix_string_type (string
);
1623 TREE_SET_CODE (string
, STRING_CST
);
1624 length
= TREE_STRING_LENGTH (string
) - 1;
1626 /* Check whether the string class being used actually exists and has the
1627 correct ivar layout. */
1628 if (!string_layout_checked
)
1630 string_layout_checked
= -1;
1631 constant_string_class
= lookup_interface (constant_string_id
);
1633 if (!constant_string_class
1634 || !(constant_string_type
1635 = CLASS_STATIC_TEMPLATE (constant_string_class
)))
1636 error ("cannot find interface declaration for `%s'",
1637 IDENTIFIER_POINTER (constant_string_id
));
1638 /* The NSConstantString/NXConstantString ivar layout is now known. */
1639 else if (!check_string_class_template ())
1640 error ("interface `%s' does not have valid constant string layout",
1641 IDENTIFIER_POINTER (constant_string_id
));
1642 /* For the NeXT runtime, we can generate a literal reference
1643 to the string class, don't need to run a constructor. */
1644 else if (flag_next_runtime
&& !setup_string_decl ())
1645 error ("cannot find reference tag for class `%s'",
1646 IDENTIFIER_POINTER (constant_string_id
));
1649 string_layout_checked
= 1; /* Success! */
1650 add_class_reference (constant_string_id
);
1654 if (string_layout_checked
== -1)
1655 return error_mark_node
;
1657 /* Perhaps we already constructed a constant string just like this one? */
1658 key
.literal
= string
;
1659 loc
= htab_find_slot (string_htab
, &key
, INSERT
);
1664 *loc
= desc
= ggc_alloc (sizeof (*desc
));
1665 desc
->literal
= string
;
1667 /* GNU: & ((NXConstantString) { NULL, string, length }) */
1668 /* NeXT: & ((NSConstantString) { isa, string, length }) */
1669 fields
= TYPE_FIELDS (constant_string_type
);
1671 = build_tree_list (fields
,
1673 ? build_unary_op (ADDR_EXPR
, string_class_decl
, 0)
1674 : build_int_cst (NULL_TREE
, 0));
1675 fields
= TREE_CHAIN (fields
);
1676 initlist
= tree_cons (fields
, build_unary_op (ADDR_EXPR
, string
, 1),
1678 fields
= TREE_CHAIN (fields
);
1679 initlist
= tree_cons (fields
, build_int_cst (NULL_TREE
, length
),
1681 constructor
= objc_build_constructor (constant_string_type
,
1682 nreverse (initlist
));
1683 TREE_INVARIANT (constructor
) = true;
1685 if (!flag_next_runtime
)
1687 = objc_add_static_instance (constructor
, constant_string_type
);
1689 desc
->constructor
= constructor
;
1692 addr
= build_unary_op (ADDR_EXPR
, desc
->constructor
, 1);
1693 TREE_CONSTANT (addr
) = true;
1694 TREE_INVARIANT (addr
) = true;
1695 TREE_STATIC (addr
) = true;
1700 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1702 static GTY(()) int num_static_inst
;
1705 objc_add_static_instance (tree constructor
, tree class_decl
)
1710 /* Find the list of static instances for the CLASS_DECL. Create one if
1712 for (chain
= &objc_static_instances
;
1713 *chain
&& TREE_VALUE (*chain
) != class_decl
;
1714 chain
= &TREE_CHAIN (*chain
));
1717 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
1718 add_objc_string (OBJC_TYPE_NAME (class_decl
), class_names
);
1721 sprintf (buf
, "_OBJC_INSTANCE_%d", num_static_inst
++);
1722 decl
= build_decl (VAR_DECL
, get_identifier (buf
), class_decl
);
1723 DECL_COMMON (decl
) = 1;
1724 TREE_STATIC (decl
) = 1;
1725 DECL_ARTIFICIAL (decl
) = 1;
1726 DECL_INITIAL (decl
) = constructor
;
1728 /* We may be writing something else just now.
1729 Postpone till end of input. */
1730 DECL_DEFER_OUTPUT (decl
) = 1;
1731 pushdecl_top_level (decl
);
1732 rest_of_decl_compilation (decl
, 1, 0);
1734 /* Add the DECL to the head of this CLASS' list. */
1735 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
1740 /* Build a static constant CONSTRUCTOR
1741 with type TYPE and elements ELTS. */
1744 objc_build_constructor (tree type
, tree elts
)
1746 tree constructor
= build_constructor (type
, elts
);
1748 TREE_CONSTANT (constructor
) = 1;
1749 TREE_STATIC (constructor
) = 1;
1750 TREE_READONLY (constructor
) = 1;
1753 /* Adjust for impedance mismatch. We should figure out how to build
1754 CONSTRUCTORs that consistently please both the C and C++ gods. */
1755 if (!TREE_PURPOSE (elts
))
1756 TREE_TYPE (constructor
) = NULL_TREE
;
1757 TREE_HAS_CONSTRUCTOR (constructor
) = 1;
1763 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1765 /* Predefine the following data type:
1773 void *defs[cls_def_cnt + cat_def_cnt];
1777 build_objc_symtab_template (void)
1779 tree field_decl
, field_decl_chain
;
1781 objc_symtab_template
1782 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SYMTAB
));
1784 /* long sel_ref_cnt; */
1785 field_decl
= create_field_decl (long_integer_type_node
, "sel_ref_cnt");
1786 field_decl_chain
= field_decl
;
1789 field_decl
= create_field_decl (build_pointer_type (objc_selector_type
),
1791 chainon (field_decl_chain
, field_decl
);
1793 /* short cls_def_cnt; */
1794 field_decl
= create_field_decl (short_integer_type_node
, "cls_def_cnt");
1795 chainon (field_decl_chain
, field_decl
);
1797 /* short cat_def_cnt; */
1798 field_decl
= create_field_decl (short_integer_type_node
,
1800 chainon (field_decl_chain
, field_decl
);
1802 if (imp_count
|| cat_count
|| !flag_next_runtime
)
1804 /* void *defs[imp_count + cat_count (+ 1)]; */
1805 /* NB: The index is one less than the size of the array. */
1806 int index
= imp_count
+ cat_count
1807 + (flag_next_runtime
? -1: 0);
1808 field_decl
= create_field_decl
1811 build_index_type (build_int_cst (NULL_TREE
, index
))),
1813 chainon (field_decl_chain
, field_decl
);
1816 finish_struct (objc_symtab_template
, field_decl_chain
, NULL_TREE
);
1819 /* Create the initial value for the `defs' field of _objc_symtab.
1820 This is a CONSTRUCTOR. */
1823 init_def_list (tree type
)
1825 tree expr
, initlist
= NULL_TREE
;
1826 struct imp_entry
*impent
;
1829 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1831 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
1833 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1834 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1839 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1841 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1843 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1844 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1848 if (!flag_next_runtime
)
1850 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1853 if (static_instances_decl
)
1854 expr
= build_unary_op (ADDR_EXPR
, static_instances_decl
, 0);
1856 expr
= build_int_cst (NULL_TREE
, 0);
1858 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1861 return objc_build_constructor (type
, nreverse (initlist
));
1864 /* Construct the initial value for all of _objc_symtab. */
1867 init_objc_symtab (tree type
)
1871 /* sel_ref_cnt = { ..., 5, ... } */
1873 initlist
= build_tree_list (NULL_TREE
,
1874 build_int_cst (long_integer_type_node
, 0));
1876 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1878 if (flag_next_runtime
|| ! sel_ref_chain
)
1879 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
1882 = tree_cons (NULL_TREE
,
1883 convert (build_pointer_type (objc_selector_type
),
1884 build_unary_op (ADDR_EXPR
,
1885 UOBJC_SELECTOR_TABLE_decl
, 1)),
1888 /* cls_def_cnt = { ..., 5, ... } */
1890 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, imp_count
), initlist
);
1892 /* cat_def_cnt = { ..., 5, ... } */
1894 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, cat_count
), initlist
);
1896 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1898 if (imp_count
|| cat_count
|| !flag_next_runtime
)
1901 tree field
= TYPE_FIELDS (type
);
1902 field
= TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field
))));
1904 initlist
= tree_cons (NULL_TREE
, init_def_list (TREE_TYPE (field
)),
1908 return objc_build_constructor (type
, nreverse (initlist
));
1911 /* Generate forward declarations for metadata such as
1912 'OBJC_CLASS_...'. */
1915 build_metadata_decl (const char *name
, tree type
)
1919 /* struct TYPE NAME_<name>; */
1920 decl
= start_var_decl (type
, synth_id_with_class_suffix
1922 objc_implementation_context
));
1927 /* Push forward-declarations of all the categories so that
1928 init_def_list can use them in a CONSTRUCTOR. */
1931 forward_declare_categories (void)
1933 struct imp_entry
*impent
;
1934 tree sav
= objc_implementation_context
;
1936 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1938 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1940 /* Set an invisible arg to synth_id_with_class_suffix. */
1941 objc_implementation_context
= impent
->imp_context
;
1942 /* extern struct objc_category _OBJC_CATEGORY_<name>; */
1943 impent
->class_decl
= build_metadata_decl ("_OBJC_CATEGORY",
1944 objc_category_template
);
1947 objc_implementation_context
= sav
;
1950 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
1951 and initialized appropriately. */
1954 generate_objc_symtab_decl (void)
1956 /* forward declare categories */
1958 forward_declare_categories ();
1960 build_objc_symtab_template ();
1961 UOBJC_SYMBOLS_decl
= start_var_decl (objc_symtab_template
, "_OBJC_SYMBOLS");
1962 finish_var_decl (UOBJC_SYMBOLS_decl
,
1963 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)));
1967 init_module_descriptor (tree type
)
1969 tree initlist
, expr
;
1971 /* version = { 1, ... } */
1973 expr
= build_int_cst (long_integer_type_node
, OBJC_VERSION
);
1974 initlist
= build_tree_list (NULL_TREE
, expr
);
1976 /* size = { ..., sizeof (struct _objc_module), ... } */
1978 expr
= convert (long_integer_type_node
,
1979 size_in_bytes (objc_module_template
));
1980 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1982 /* name = { ..., "foo.m", ... } */
1984 expr
= add_objc_string (get_identifier (input_filename
), class_names
);
1985 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1987 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1989 if (UOBJC_SYMBOLS_decl
)
1990 expr
= build_unary_op (ADDR_EXPR
, UOBJC_SYMBOLS_decl
, 0);
1992 expr
= build_int_cst (NULL_TREE
, 0);
1993 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1995 return objc_build_constructor (type
, nreverse (initlist
));
1998 /* Write out the data structures to describe Objective C classes defined.
2000 struct _objc_module { ... } _OBJC_MODULE = { ... }; */
2003 build_module_descriptor (void)
2005 tree field_decl
, field_decl_chain
;
2008 push_lang_context (lang_name_c
); /* extern "C" */
2011 objc_module_template
2012 = start_struct (RECORD_TYPE
, get_identifier (UTAG_MODULE
));
2015 field_decl
= create_field_decl (long_integer_type_node
, "version");
2016 field_decl_chain
= field_decl
;
2019 field_decl
= create_field_decl (long_integer_type_node
, "size");
2020 chainon (field_decl_chain
, field_decl
);
2023 field_decl
= create_field_decl (string_type_node
, "name");
2024 chainon (field_decl_chain
, field_decl
);
2026 /* struct _objc_symtab *symtab; */
2028 = create_field_decl (build_pointer_type
2029 (xref_tag (RECORD_TYPE
,
2030 get_identifier (UTAG_SYMTAB
))),
2032 chainon (field_decl_chain
, field_decl
);
2034 finish_struct (objc_module_template
, field_decl_chain
, NULL_TREE
);
2036 /* Create an instance of "_objc_module". */
2037 UOBJC_MODULES_decl
= start_var_decl (objc_module_template
, "_OBJC_MODULES");
2038 finish_var_decl (UOBJC_MODULES_decl
,
2039 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl
)));
2042 pop_lang_context ();
2046 /* The GNU runtime requires us to provide a static initializer function
2049 static void __objc_gnu_init (void) {
2050 __objc_exec_class (&L_OBJC_MODULES);
2054 build_module_initializer_routine (void)
2059 push_lang_context (lang_name_c
); /* extern "C" */
2062 objc_push_parm (build_decl (PARM_DECL
, NULL_TREE
, void_type_node
));
2063 objc_start_function (get_identifier (TAG_GNUINIT
),
2064 build_function_type (void_type_node
,
2066 NULL_TREE
, objc_get_parm_info (0));
2068 body
= c_begin_compound_stmt (true);
2069 add_stmt (build_function_call
2073 build_unary_op (ADDR_EXPR
,
2074 UOBJC_MODULES_decl
, 0))));
2075 add_stmt (c_end_compound_stmt (body
, true));
2077 TREE_PUBLIC (current_function_decl
) = 0;
2080 /* For Objective-C++, we will need to call __objc_gnu_init
2081 from objc_generate_static_init_call() below. */
2082 DECL_STATIC_CONSTRUCTOR (current_function_decl
) = 1;
2085 GNU_INIT_decl
= current_function_decl
;
2089 pop_lang_context ();
2094 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
2095 to be called by the module initializer routine. */
2098 objc_static_init_needed_p (void)
2100 return (GNU_INIT_decl
!= NULL_TREE
);
2103 /* Generate a call to the __objc_gnu_init initializer function. */
2106 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED
)
2108 add_stmt (build_stmt (EXPR_STMT
,
2109 build_function_call (GNU_INIT_decl
, NULL_TREE
)));
2113 #endif /* OBJCPLUS */
2115 /* Return the DECL of the string IDENT in the SECTION. */
2118 get_objc_string_decl (tree ident
, enum string_section section
)
2122 if (section
== class_names
)
2123 chain
= class_names_chain
;
2124 else if (section
== meth_var_names
)
2125 chain
= meth_var_names_chain
;
2126 else if (section
== meth_var_types
)
2127 chain
= meth_var_types_chain
;
2131 for (; chain
!= 0; chain
= TREE_CHAIN (chain
))
2132 if (TREE_VALUE (chain
) == ident
)
2133 return (TREE_PURPOSE (chain
));
2139 /* Output references to all statically allocated objects. Return the DECL
2140 for the array built. */
2143 generate_static_references (void)
2145 tree decls
= NULL_TREE
, expr
= NULL_TREE
;
2146 tree class_name
, class, decl
, initlist
;
2147 tree cl_chain
, in_chain
, type
2148 = build_array_type (build_pointer_type (void_type_node
), NULL_TREE
);
2149 int num_inst
, num_class
;
2152 if (flag_next_runtime
)
2155 for (cl_chain
= objc_static_instances
, num_class
= 0;
2156 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
2158 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
2159 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
2161 sprintf (buf
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
2162 decl
= start_var_decl (type
, buf
);
2164 /* Output {class_name, ...}. */
2165 class = TREE_VALUE (cl_chain
);
2166 class_name
= get_objc_string_decl (OBJC_TYPE_NAME (class), class_names
);
2167 initlist
= build_tree_list (NULL_TREE
,
2168 build_unary_op (ADDR_EXPR
, class_name
, 1));
2170 /* Output {..., instance, ...}. */
2171 for (in_chain
= TREE_PURPOSE (cl_chain
);
2172 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
2174 expr
= build_unary_op (ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
2175 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2178 /* Output {..., NULL}. */
2179 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
2181 expr
= objc_build_constructor (TREE_TYPE (decl
), nreverse (initlist
));
2182 finish_var_decl (decl
, expr
);
2184 = tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, decl
, 1), decls
);
2187 decls
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), decls
);
2188 expr
= objc_build_constructor (type
, nreverse (decls
));
2189 static_instances_decl
= start_var_decl (type
, "_OBJC_STATIC_INSTANCES");
2190 finish_var_decl (static_instances_decl
, expr
);
2193 /* Output all strings. */
2196 generate_strings (void)
2198 tree chain
, string_expr
;
2199 tree string
, decl
, type
;
2201 for (chain
= class_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
2203 string
= TREE_VALUE (chain
);
2204 decl
= TREE_PURPOSE (chain
);
2205 type
= build_array_type
2208 (build_int_cst (NULL_TREE
,
2209 IDENTIFIER_LENGTH (string
))));
2210 decl
= start_var_decl (type
, IDENTIFIER_POINTER (DECL_NAME (decl
)));
2211 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
2212 IDENTIFIER_POINTER (string
));
2213 finish_var_decl (decl
, string_expr
);
2216 for (chain
= meth_var_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
2218 string
= TREE_VALUE (chain
);
2219 decl
= TREE_PURPOSE (chain
);
2220 type
= build_array_type
2223 (build_int_cst (NULL_TREE
,
2224 IDENTIFIER_LENGTH (string
))));
2225 decl
= start_var_decl (type
, IDENTIFIER_POINTER (DECL_NAME (decl
)));
2226 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
2227 IDENTIFIER_POINTER (string
));
2228 finish_var_decl (decl
, string_expr
);
2231 for (chain
= meth_var_types_chain
; chain
; chain
= TREE_CHAIN (chain
))
2233 string
= TREE_VALUE (chain
);
2234 decl
= TREE_PURPOSE (chain
);
2235 type
= build_array_type
2238 (build_int_cst (NULL_TREE
,
2239 IDENTIFIER_LENGTH (string
))));
2240 decl
= start_var_decl (type
, IDENTIFIER_POINTER (DECL_NAME (decl
)));
2241 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
2242 IDENTIFIER_POINTER (string
));
2243 finish_var_decl (decl
, string_expr
);
2247 static GTY(()) int selector_reference_idx
;
2250 build_selector_reference_decl (void)
2255 sprintf (buf
, "_OBJC_SELECTOR_REFERENCES_%d", selector_reference_idx
++);
2256 decl
= start_var_decl (objc_selector_type
, buf
);
2262 build_selector_table_decl (void)
2266 if (flag_typed_selectors
)
2268 build_selector_template ();
2269 temp
= build_array_type (objc_selector_template
, NULL_TREE
);
2272 temp
= build_array_type (objc_selector_type
, NULL_TREE
);
2274 UOBJC_SELECTOR_TABLE_decl
= start_var_decl (temp
, "_OBJC_SELECTOR_TABLE");
2277 /* Just a handy wrapper for add_objc_string. */
2280 build_selector (tree ident
)
2282 return convert (objc_selector_type
,
2283 add_objc_string (ident
, meth_var_names
));
2287 build_selector_translation_table (void)
2289 tree chain
, initlist
= NULL_TREE
;
2291 tree decl
= NULL_TREE
;
2293 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
2297 if (warn_selector
&& objc_implementation_context
)
2301 for (method_chain
= meth_var_names_chain
;
2303 method_chain
= TREE_CHAIN (method_chain
))
2305 if (TREE_VALUE (method_chain
) == TREE_VALUE (chain
))
2312 warning ("%Jcreating selector for nonexistent method %qE",
2313 TREE_PURPOSE (chain
), TREE_VALUE (chain
));
2316 expr
= build_selector (TREE_VALUE (chain
));
2317 /* add one for the '\0' character */
2318 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (chain
)) + 1;
2320 if (flag_next_runtime
)
2322 decl
= TREE_PURPOSE (chain
);
2323 finish_var_decl (decl
, expr
);
2327 if (flag_typed_selectors
)
2329 tree eltlist
= NULL_TREE
;
2330 tree encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
2331 eltlist
= tree_cons (NULL_TREE
, expr
, NULL_TREE
);
2332 eltlist
= tree_cons (NULL_TREE
, encoding
, eltlist
);
2333 expr
= objc_build_constructor (objc_selector_template
,
2334 nreverse (eltlist
));
2337 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2341 if (! flag_next_runtime
)
2343 /* Cause the selector table (previously forward-declared)
2344 to be actually output. */
2345 initlist
= tree_cons (NULL_TREE
,
2346 flag_typed_selectors
2347 ? objc_build_constructor
2348 (objc_selector_template
,
2349 tree_cons (NULL_TREE
,
2350 build_int_cst (NULL_TREE
, 0),
2351 tree_cons (NULL_TREE
,
2352 build_int_cst (NULL_TREE
, 0),
2354 : build_int_cst (NULL_TREE
, 0), initlist
);
2355 initlist
= objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
2356 nreverse (initlist
));
2357 finish_var_decl (UOBJC_SELECTOR_TABLE_decl
, initlist
);
2362 get_proto_encoding (tree proto
)
2367 if (! METHOD_ENCODING (proto
))
2369 encoding
= encode_method_prototype (proto
);
2370 METHOD_ENCODING (proto
) = encoding
;
2373 encoding
= METHOD_ENCODING (proto
);
2375 return add_objc_string (encoding
, meth_var_types
);
2378 return build_int_cst (NULL_TREE
, 0);
2381 /* sel_ref_chain is a list whose "value" fields will be instances of
2382 identifier_node that represent the selector. */
2385 build_typed_selector_reference (tree ident
, tree prototype
)
2387 tree
*chain
= &sel_ref_chain
;
2393 if (TREE_PURPOSE (*chain
) == prototype
&& TREE_VALUE (*chain
) == ident
)
2394 goto return_at_index
;
2397 chain
= &TREE_CHAIN (*chain
);
2400 *chain
= tree_cons (prototype
, ident
, NULL_TREE
);
2403 expr
= build_unary_op (ADDR_EXPR
,
2404 build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2405 build_int_cst (NULL_TREE
, index
)),
2407 return convert (objc_selector_type
, expr
);
2411 build_selector_reference (tree ident
)
2413 tree
*chain
= &sel_ref_chain
;
2419 if (TREE_VALUE (*chain
) == ident
)
2420 return (flag_next_runtime
2421 ? TREE_PURPOSE (*chain
)
2422 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2423 build_int_cst (NULL_TREE
, index
)));
2426 chain
= &TREE_CHAIN (*chain
);
2429 expr
= (flag_next_runtime
? build_selector_reference_decl (): NULL_TREE
);
2431 *chain
= tree_cons (expr
, ident
, NULL_TREE
);
2433 return (flag_next_runtime
2435 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2436 build_int_cst (NULL_TREE
, index
)));
2439 static GTY(()) int class_reference_idx
;
2442 build_class_reference_decl (void)
2447 sprintf (buf
, "_OBJC_CLASS_REFERENCES_%d", class_reference_idx
++);
2448 decl
= start_var_decl (objc_class_type
, buf
);
2453 /* Create a class reference, but don't create a variable to reference
2457 add_class_reference (tree ident
)
2461 if ((chain
= cls_ref_chain
))
2466 if (ident
== TREE_VALUE (chain
))
2470 chain
= TREE_CHAIN (chain
);
2474 /* Append to the end of the list */
2475 TREE_CHAIN (tail
) = tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2478 cls_ref_chain
= tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2481 /* Get a class reference, creating it if necessary. Also create the
2482 reference variable. */
2485 objc_get_class_reference (tree ident
)
2490 if (processing_template_decl
)
2491 /* Must wait until template instantiation time. */
2492 return build_min_nt (CLASS_REFERENCE_EXPR
, ident
);
2493 if (TREE_CODE (ident
) == TYPE_DECL
)
2494 ident
= DECL_NAME (ident
);
2498 if (!(ident
= objc_is_class_name (ident
)))
2500 error ("`%s' is not an Objective-C class name or alias",
2501 IDENTIFIER_POINTER (orig_ident
));
2502 return error_mark_node
;
2505 if (flag_next_runtime
&& !flag_zero_link
)
2510 for (chain
= &cls_ref_chain
; *chain
; chain
= &TREE_CHAIN (*chain
))
2511 if (TREE_VALUE (*chain
) == ident
)
2513 if (! TREE_PURPOSE (*chain
))
2514 TREE_PURPOSE (*chain
) = build_class_reference_decl ();
2516 return TREE_PURPOSE (*chain
);
2519 decl
= build_class_reference_decl ();
2520 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2527 add_class_reference (ident
);
2529 params
= build_tree_list (NULL_TREE
,
2530 my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
2531 IDENTIFIER_POINTER (ident
)));
2533 assemble_external (objc_get_class_decl
);
2534 return build_function_call (objc_get_class_decl
, params
);
2538 /* For each string section we have a chain which maps identifier nodes
2539 to decls for the strings. */
2542 add_objc_string (tree ident
, enum string_section section
)
2546 if (section
== class_names
)
2547 chain
= &class_names_chain
;
2548 else if (section
== meth_var_names
)
2549 chain
= &meth_var_names_chain
;
2550 else if (section
== meth_var_types
)
2551 chain
= &meth_var_types_chain
;
2557 if (TREE_VALUE (*chain
) == ident
)
2558 return convert (string_type_node
,
2559 build_unary_op (ADDR_EXPR
, TREE_PURPOSE (*chain
), 1));
2561 chain
= &TREE_CHAIN (*chain
);
2564 decl
= build_objc_string_decl (section
);
2566 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2568 return convert (string_type_node
, build_unary_op (ADDR_EXPR
, decl
, 1));
2571 static GTY(()) int class_names_idx
;
2572 static GTY(()) int meth_var_names_idx
;
2573 static GTY(()) int meth_var_types_idx
;
2576 build_objc_string_decl (enum string_section section
)
2581 if (section
== class_names
)
2582 sprintf (buf
, "_OBJC_CLASS_NAME_%d", class_names_idx
++);
2583 else if (section
== meth_var_names
)
2584 sprintf (buf
, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx
++);
2585 else if (section
== meth_var_types
)
2586 sprintf (buf
, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx
++);
2588 ident
= get_identifier (buf
);
2590 decl
= build_decl (VAR_DECL
, ident
, build_array_type (char_type_node
, 0));
2591 DECL_EXTERNAL (decl
) = 1;
2592 TREE_PUBLIC (decl
) = 0;
2593 TREE_USED (decl
) = 1;
2594 TREE_CONSTANT (decl
) = 1;
2595 DECL_CONTEXT (decl
) = 0;
2596 DECL_ARTIFICIAL (decl
) = 1;
2598 DECL_THIS_STATIC (decl
) = 1; /* squash redeclaration errors */
2601 make_decl_rtl (decl
);
2602 pushdecl_top_level (decl
);
2609 objc_declare_alias (tree alias_ident
, tree class_ident
)
2611 tree underlying_class
;
2614 if (current_namespace
!= global_namespace
) {
2615 error ("Objective-C declarations may only appear in global scope");
2617 #endif /* OBJCPLUS */
2619 if (!(underlying_class
= objc_is_class_name (class_ident
)))
2620 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident
));
2621 else if (objc_is_class_name (alias_ident
))
2622 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident
));
2624 alias_chain
= tree_cons (underlying_class
, alias_ident
, alias_chain
);
2628 objc_declare_class (tree ident_list
)
2632 if (current_namespace
!= global_namespace
) {
2633 error ("Objective-C declarations may only appear in global scope");
2635 #endif /* OBJCPLUS */
2637 for (list
= ident_list
; list
; list
= TREE_CHAIN (list
))
2639 tree ident
= TREE_VALUE (list
);
2641 if (! objc_is_class_name (ident
))
2643 tree record
= lookup_name (ident
);
2645 if (record
&& ! TREE_STATIC_TEMPLATE (record
))
2647 error ("`%s' redeclared as different kind of symbol",
2648 IDENTIFIER_POINTER (ident
));
2649 error ("%Jprevious declaration of '%D'",
2653 record
= xref_tag (RECORD_TYPE
, ident
);
2654 TREE_STATIC_TEMPLATE (record
) = 1;
2655 class_chain
= tree_cons (NULL_TREE
, ident
, class_chain
);
2661 objc_is_class_name (tree ident
)
2665 if (ident
&& TREE_CODE (ident
) == IDENTIFIER_NODE
2666 && identifier_global_value (ident
))
2667 ident
= identifier_global_value (ident
);
2668 while (ident
&& TREE_CODE (ident
) == TYPE_DECL
&& DECL_ORIGINAL_TYPE (ident
))
2669 ident
= OBJC_TYPE_NAME (DECL_ORIGINAL_TYPE (ident
));
2671 if (ident
&& TREE_CODE (ident
) == RECORD_TYPE
)
2672 ident
= OBJC_TYPE_NAME (ident
);
2674 if (ident
&& TREE_CODE (ident
) == TYPE_DECL
)
2675 ident
= DECL_NAME (ident
);
2677 if (!ident
|| TREE_CODE (ident
) != IDENTIFIER_NODE
)
2680 if (lookup_interface (ident
))
2683 for (chain
= class_chain
; chain
; chain
= TREE_CHAIN (chain
))
2685 if (ident
== TREE_VALUE (chain
))
2689 for (chain
= alias_chain
; chain
; chain
= TREE_CHAIN (chain
))
2691 if (ident
== TREE_VALUE (chain
))
2692 return TREE_PURPOSE (chain
);
2698 /* Check whether TYPE is either 'id' or 'Class'. */
2701 objc_is_id (tree type
)
2703 if (type
&& TREE_CODE (type
) == IDENTIFIER_NODE
2704 && identifier_global_value (type
))
2705 type
= identifier_global_value (type
);
2707 if (type
&& TREE_CODE (type
) == TYPE_DECL
)
2708 type
= TREE_TYPE (type
);
2710 /* NB: This function may be called before the ObjC front-end has
2711 been initialized, in which case OBJC_OBJECT_TYPE will (still) be NULL. */
2712 return (objc_object_type
&& type
&& (IS_ID (type
) || IS_CLASS (type
))
2717 /* Check whether TYPE is either 'id', 'Class', or a pointer to an ObjC
2718 class instance. This is needed by other parts of the compiler to
2719 handle ObjC types gracefully. */
2722 objc_is_object_ptr (tree type
)
2726 type
= TYPE_MAIN_VARIANT (type
);
2727 if (!POINTER_TYPE_P (type
))
2730 ret
= objc_is_id (type
);
2732 ret
= objc_is_class_name (TREE_TYPE (type
));
2738 lookup_interface (tree ident
)
2743 if (ident
&& TREE_CODE (ident
) == TYPE_DECL
)
2744 ident
= DECL_NAME (ident
);
2746 for (chain
= interface_chain
; chain
; chain
= TREE_CHAIN (chain
))
2748 if (ident
== CLASS_NAME (chain
))
2754 /* Implement @defs (<classname>) within struct bodies. */
2757 objc_get_class_ivars (tree class_name
)
2759 tree interface
= lookup_interface (class_name
);
2762 return get_class_ivars (interface
);
2764 error ("cannot find interface declaration for `%s'",
2765 IDENTIFIER_POINTER (class_name
));
2767 return error_mark_node
;
2770 /* Used by: build_private_template, continue_class,
2771 and for @defs constructs. */
2774 get_class_ivars (tree interface
)
2776 tree ivar_chain
= copy_list (CLASS_RAW_IVARS (interface
));
2778 /* Both CLASS_RAW_IVARS and CLASS_IVARS contain a list of ivars declared
2779 by the current class (i.e., they do not include super-class ivars).
2780 However, the CLASS_IVARS list will be side-effected by a call to
2781 finish_struct(), which will fill in field offsets. */
2782 if (!CLASS_IVARS (interface
))
2783 CLASS_IVARS (interface
) = ivar_chain
;
2785 while (CLASS_SUPER_NAME (interface
))
2787 /* Prepend super-class ivars. */
2788 interface
= lookup_interface (CLASS_SUPER_NAME (interface
));
2789 ivar_chain
= chainon (copy_list (CLASS_RAW_IVARS (interface
)),
2797 objc_create_temporary_var (tree type
)
2801 decl
= build_decl (VAR_DECL
, NULL_TREE
, type
);
2802 TREE_USED (decl
) = 1;
2803 DECL_ARTIFICIAL (decl
) = 1;
2804 DECL_IGNORED_P (decl
) = 1;
2805 DECL_CONTEXT (decl
) = current_function_decl
;
2810 /* Exception handling constructs. We begin by having the parser do most
2811 of the work and passing us blocks. What we do next depends on whether
2812 we're doing "native" exception handling or legacy Darwin setjmp exceptions.
2813 We abstract all of this in a handful of appropriately named routines. */
2815 /* Stack of open try blocks. */
2817 struct objc_try_context
2819 struct objc_try_context
*outer
;
2821 /* Statements (or statement lists) as processed by the parser. */
2825 /* Some file position locations. */
2826 location_t try_locus
;
2827 location_t end_try_locus
;
2828 location_t end_catch_locus
;
2829 location_t finally_locus
;
2830 location_t end_finally_locus
;
2832 /* A STATEMENT_LIST of CATCH_EXPRs, appropriate for sticking into op1
2833 of a TRY_CATCH_EXPR. Even when doing Darwin setjmp. */
2836 /* The CATCH_EXPR of an open @catch clause. */
2839 /* The VAR_DECL holding the Darwin equivalent of EXC_PTR_EXPR. */
2845 static struct objc_try_context
*cur_try_context
;
2847 /* This hook, called via lang_eh_runtime_type, generates a runtime object
2848 that represents TYPE. For Objective-C, this is just the class name. */
2849 /* ??? Isn't there a class object or some such? Is it easy to get? */
2853 objc_eh_runtime_type (tree type
)
2855 return add_objc_string (OBJC_TYPE_NAME (TREE_TYPE (type
)), class_names
);
2859 /* Initialize exception handling. */
2862 objc_init_exceptions (void)
2864 static bool done
= false;
2869 if (flag_objc_sjlj_exceptions
)
2871 /* On Darwin, ObjC exceptions require a sufficiently recent
2872 version of the runtime, so the user must ask for them explicitly. */
2873 if (!flag_objc_exceptions
)
2874 warning ("use %<-fobjc-exceptions%> to enable Objective-C "
2875 "exception syntax");
2880 c_eh_initialized_p
= true;
2881 eh_personality_libfunc
2882 = init_one_libfunc (USING_SJLJ_EXCEPTIONS
2883 ? "__gnu_objc_personality_sj0"
2884 : "__gnu_objc_personality_v0");
2885 using_eh_for_cleanups ();
2886 lang_eh_runtime_type
= objc_eh_runtime_type
;
2891 /* Build an EXC_PTR_EXPR, or the moral equivalent. In the case of Darwin,
2892 we'll arrange for it to be initialized (and associated with a binding)
2896 objc_build_exc_ptr (void)
2898 if (flag_objc_sjlj_exceptions
)
2900 tree var
= cur_try_context
->caught_decl
;
2903 var
= objc_create_temporary_var (objc_object_type
);
2904 cur_try_context
->caught_decl
= var
;
2909 return build (EXC_PTR_EXPR
, objc_object_type
);
2912 /* Build "objc_exception_try_exit(&_stack)". */
2915 next_sjlj_build_try_exit (void)
2918 t
= build_fold_addr_expr (cur_try_context
->stack_decl
);
2919 t
= tree_cons (NULL
, t
, NULL
);
2920 t
= build_function_call (objc_exception_try_exit_decl
, t
);
2925 objc_exception_try_enter (&_stack);
2926 if (_setjmp(&_stack.buf))
2930 Return the COND_EXPR. Note that the THEN and ELSE fields are left
2931 empty, ready for the caller to fill them in. */
2934 next_sjlj_build_enter_and_setjmp (void)
2936 tree t
, enter
, sj
, cond
;
2938 t
= build_fold_addr_expr (cur_try_context
->stack_decl
);
2939 t
= tree_cons (NULL
, t
, NULL
);
2940 enter
= build_function_call (objc_exception_try_enter_decl
, t
);
2942 t
= build_component_ref (cur_try_context
->stack_decl
,
2943 get_identifier ("buf"));
2944 t
= build_fold_addr_expr (t
);
2945 t
= convert (ptr_type_node
, t
);
2946 t
= tree_cons (NULL
, t
, NULL
);
2947 sj
= build_function_call (objc_setjmp_decl
, t
);
2949 cond
= build (COMPOUND_EXPR
, TREE_TYPE (sj
), enter
, sj
);
2950 cond
= lang_hooks
.truthvalue_conversion (cond
);
2952 return build (COND_EXPR
, void_type_node
, cond
, NULL
, NULL
);
2956 DECL = objc_exception_extract(&_stack);
2960 next_sjlj_build_exc_extract (tree decl
)
2964 t
= build_fold_addr_expr (cur_try_context
->stack_decl
);
2965 t
= tree_cons (NULL
, t
, NULL
);
2966 t
= build_function_call (objc_exception_extract_decl
, t
);
2967 t
= convert (TREE_TYPE (decl
), t
);
2968 t
= build (MODIFY_EXPR
, void_type_node
, decl
, t
);
2974 if (objc_exception_match(obj_get_class(TYPE), _caught)
2981 objc_exception_try_exit(&_stack);
2983 from the sequence of CATCH_EXPRs in the current try context. */
2986 next_sjlj_build_catch_list (void)
2988 tree_stmt_iterator i
= tsi_start (cur_try_context
->catch_list
);
2990 tree
*last
= &catch_seq
;
2991 bool saw_id
= false;
2993 for (; !tsi_end_p (i
); tsi_next (&i
))
2995 tree stmt
= tsi_stmt (i
);
2996 tree type
= CATCH_TYPES (stmt
);
2997 tree body
= CATCH_BODY (stmt
);
3009 if (type
== error_mark_node
)
3010 cond
= error_mark_node
;
3013 args
= tree_cons (NULL
, cur_try_context
->caught_decl
, NULL
);
3014 t
= objc_get_class_reference (OBJC_TYPE_NAME (TREE_TYPE (type
)));
3015 args
= tree_cons (NULL
, t
, args
);
3016 t
= build_function_call (objc_exception_match_decl
, args
);
3017 cond
= lang_hooks
.truthvalue_conversion (t
);
3019 t
= build (COND_EXPR
, void_type_node
, cond
, body
, NULL
);
3020 SET_EXPR_LOCUS (t
, EXPR_LOCUS (stmt
));
3023 last
= &COND_EXPR_ELSE (t
);
3029 t
= build (MODIFY_EXPR
, void_type_node
, cur_try_context
->rethrow_decl
,
3030 cur_try_context
->caught_decl
);
3031 SET_EXPR_LOCATION (t
, cur_try_context
->end_catch_locus
);
3032 append_to_statement_list (t
, last
);
3034 t
= next_sjlj_build_try_exit ();
3035 SET_EXPR_LOCATION (t
, cur_try_context
->end_catch_locus
);
3036 append_to_statement_list (t
, last
);
3042 /* Build a complete @try-@catch-@finally block for legacy Darwin setjmp
3043 exception handling. We aim to build:
3046 struct _objc_exception_data _stack;
3047 id volatile _rethrow = 0;
3050 objc_exception_try_enter (&_stack);
3051 if (_setjmp(&_stack.buf))
3053 id _caught = objc_exception_extract(&_stack);
3054 objc_exception_try_enter (&_stack);
3055 if (_setjmp(&_stack.buf))
3056 _rethrow = objc_exception_extract(&_stack);
3066 objc_exception_try_exit(&_stack);
3069 objc_exception_throw(_rethrow);
3073 If CATCH-LIST is empty, we can omit all of the block containing
3074 "_caught" except for the setting of _rethrow. Note the use of
3075 a real TRY_FINALLY_EXPR here, which is not involved in EH per-se,
3076 but handles goto and other exits from the block. */
3079 next_sjlj_build_try_catch_finally (void)
3081 tree rethrow_decl
, stack_decl
, t
;
3082 tree catch_seq
, try_fin
, bind
;
3084 /* Create the declarations involved. */
3085 t
= xref_tag (RECORD_TYPE
, get_identifier (UTAG_EXCDATA
));
3086 stack_decl
= objc_create_temporary_var (t
);
3087 cur_try_context
->stack_decl
= stack_decl
;
3089 rethrow_decl
= objc_create_temporary_var (objc_object_type
);
3090 cur_try_context
->rethrow_decl
= rethrow_decl
;
3091 TREE_THIS_VOLATILE (rethrow_decl
) = 1;
3092 TREE_CHAIN (rethrow_decl
) = stack_decl
;
3094 /* Build the outermost varible binding level. */
3095 bind
= build (BIND_EXPR
, void_type_node
, rethrow_decl
, NULL
, NULL
);
3096 SET_EXPR_LOCATION (bind
, cur_try_context
->try_locus
);
3097 TREE_SIDE_EFFECTS (bind
) = 1;
3099 /* Initialize rethrow_decl. */
3100 t
= build (MODIFY_EXPR
, void_type_node
, rethrow_decl
,
3101 convert (objc_object_type
, null_pointer_node
));
3102 SET_EXPR_LOCATION (t
, cur_try_context
->try_locus
);
3103 append_to_statement_list (t
, &BIND_EXPR_BODY (bind
));
3105 /* Build the outermost TRY_FINALLY_EXPR. */
3106 try_fin
= build (TRY_FINALLY_EXPR
, void_type_node
, NULL
, NULL
);
3107 SET_EXPR_LOCATION (try_fin
, cur_try_context
->try_locus
);
3108 TREE_SIDE_EFFECTS (try_fin
) = 1;
3109 append_to_statement_list (try_fin
, &BIND_EXPR_BODY (bind
));
3111 /* Create the complete catch sequence. */
3112 if (cur_try_context
->catch_list
)
3114 tree caught_decl
= objc_build_exc_ptr ();
3115 catch_seq
= build_stmt (BIND_EXPR
, caught_decl
, NULL
, NULL
);
3117 t
= next_sjlj_build_exc_extract (caught_decl
);
3118 append_to_statement_list (t
, &BIND_EXPR_BODY (catch_seq
));
3120 t
= next_sjlj_build_enter_and_setjmp ();
3121 COND_EXPR_THEN (t
) = next_sjlj_build_exc_extract (rethrow_decl
);
3122 COND_EXPR_ELSE (t
) = next_sjlj_build_catch_list ();
3123 append_to_statement_list (t
, &BIND_EXPR_BODY (catch_seq
));
3126 catch_seq
= next_sjlj_build_exc_extract (rethrow_decl
);
3127 SET_EXPR_LOCATION (catch_seq
, cur_try_context
->end_try_locus
);
3129 /* Build the main register-and-try if statement. */
3130 t
= next_sjlj_build_enter_and_setjmp ();
3131 SET_EXPR_LOCATION (t
, cur_try_context
->try_locus
);
3132 COND_EXPR_THEN (t
) = catch_seq
;
3133 COND_EXPR_ELSE (t
) = cur_try_context
->try_body
;
3134 TREE_OPERAND (try_fin
, 0) = t
;
3136 /* Build the complete FINALLY statement list. */
3137 t
= next_sjlj_build_try_exit ();
3138 t
= build_stmt (COND_EXPR
,
3139 lang_hooks
.truthvalue_conversion (rethrow_decl
),
3141 SET_EXPR_LOCATION (t
, cur_try_context
->finally_locus
);
3142 append_to_statement_list (t
, &TREE_OPERAND (try_fin
, 1));
3144 append_to_statement_list (cur_try_context
->finally_body
,
3145 &TREE_OPERAND (try_fin
, 1));
3147 t
= tree_cons (NULL
, rethrow_decl
, NULL
);
3148 t
= build_function_call (objc_exception_throw_decl
, t
);
3149 t
= build_stmt (COND_EXPR
,
3150 lang_hooks
.truthvalue_conversion (rethrow_decl
),
3152 SET_EXPR_LOCATION (t
, cur_try_context
->end_finally_locus
);
3153 append_to_statement_list (t
, &TREE_OPERAND (try_fin
, 1));
3158 /* Called just after parsing the @try and its associated BODY. We now
3159 must prepare for the tricky bits -- handling the catches and finally. */
3162 objc_begin_try_stmt (location_t try_locus
, tree body
)
3164 struct objc_try_context
*c
= xcalloc (1, sizeof (*c
));
3165 c
->outer
= cur_try_context
;
3167 c
->try_locus
= try_locus
;
3168 c
->end_try_locus
= input_location
;
3169 cur_try_context
= c
;
3171 objc_init_exceptions ();
3174 /* Called just after parsing "@catch (parm)". Open a binding level,
3175 enter DECL into the binding level, and initialize it. Leave the
3176 binding level open while the body of the compound statement is parsed. */
3179 objc_begin_catch_clause (tree decl
)
3181 tree compound
, type
, t
;
3183 /* Begin a new scope that the entire catch clause will live in. */
3184 compound
= c_begin_compound_stmt (true);
3186 /* The parser passed in a PARM_DECL, but what we really want is a VAR_DECL. */
3187 decl
= build_decl (VAR_DECL
, DECL_NAME (decl
), TREE_TYPE (decl
));
3188 lang_hooks
.decls
.pushdecl (decl
);
3190 /* Since a decl is required here by syntax, don't warn if its unused. */
3191 /* ??? As opposed to __attribute__((unused))? Anyway, this appears to
3192 be what the previous objc implementation did. */
3193 TREE_USED (decl
) = 1;
3195 /* Verify that the type of the catch is valid. It must be a pointer
3196 to an Objective-C class, or "id" (which is catch-all). */
3197 type
= TREE_TYPE (decl
);
3199 if (POINTER_TYPE_P (type
) && objc_is_object_id (TREE_TYPE (type
)))
3201 else if (!POINTER_TYPE_P (type
) || !TYPED_OBJECT (TREE_TYPE (type
)))
3203 error ("@catch parameter is not a known Objective-C class type");
3204 type
= error_mark_node
;
3206 else if (cur_try_context
->catch_list
)
3208 /* Examine previous @catch clauses and see if we've already
3209 caught the type in question. */
3210 tree_stmt_iterator i
= tsi_start (cur_try_context
->catch_list
);
3211 for (; !tsi_end_p (i
); tsi_next (&i
))
3213 tree stmt
= tsi_stmt (i
);
3214 t
= CATCH_TYPES (stmt
);
3215 if (t
== error_mark_node
)
3217 if (!t
|| objc_comptypes (TREE_TYPE (t
), TREE_TYPE (type
), 0) == 1)
3219 warning ("exception of type %<%T%> will be caught",
3221 warning ("%H by earlier handler for %<%T%>",
3222 EXPR_LOCUS (stmt
), TREE_TYPE (t
? t
: objc_object_type
));
3228 /* Record the data for the catch in the try context so that we can
3229 finalize it later. */
3230 t
= build_stmt (CATCH_EXPR
, type
, compound
);
3231 cur_try_context
->current_catch
= t
;
3233 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
3234 t
= objc_build_exc_ptr ();
3235 t
= convert (TREE_TYPE (decl
), t
);
3236 t
= build (MODIFY_EXPR
, void_type_node
, decl
, t
);
3240 /* Called just after parsing the closing brace of a @catch clause. Close
3241 the open binding level, and record a CATCH_EXPR for it. */
3244 objc_finish_catch_clause (void)
3246 tree c
= cur_try_context
->current_catch
;
3247 cur_try_context
->current_catch
= NULL
;
3248 cur_try_context
->end_catch_locus
= input_location
;
3250 CATCH_BODY (c
) = c_end_compound_stmt (CATCH_BODY (c
), 1);
3251 append_to_statement_list (c
, &cur_try_context
->catch_list
);
3254 /* Called after parsing a @finally clause and its associated BODY.
3255 Record the body for later placement. */
3258 objc_build_finally_clause (location_t finally_locus
, tree body
)
3260 cur_try_context
->finally_body
= body
;
3261 cur_try_context
->finally_locus
= finally_locus
;
3262 cur_try_context
->end_finally_locus
= input_location
;
3265 /* Called to finalize a @try construct. */
3268 objc_finish_try_stmt (void)
3270 struct objc_try_context
*c
= cur_try_context
;
3273 if (c
->catch_list
== NULL
&& c
->finally_body
== NULL
)
3274 error ("`@try' without `@catch' or `@finally'");
3276 /* If we're doing Darwin setjmp exceptions, build the big nasty. */
3277 if (flag_objc_sjlj_exceptions
)
3279 if (!cur_try_context
->finally_body
)
3281 cur_try_context
->finally_locus
= input_location
;
3282 cur_try_context
->end_finally_locus
= input_location
;
3284 stmt
= next_sjlj_build_try_catch_finally ();
3288 /* Otherwise, nest the CATCH inside a FINALLY. */
3292 stmt
= build_stmt (TRY_CATCH_EXPR
, stmt
, c
->catch_list
);
3293 SET_EXPR_LOCATION (stmt
, cur_try_context
->try_locus
);
3295 if (c
->finally_body
)
3297 stmt
= build_stmt (TRY_FINALLY_EXPR
, stmt
, c
->finally_body
);
3298 SET_EXPR_LOCATION (stmt
, cur_try_context
->try_locus
);
3303 cur_try_context
= c
->outer
;
3308 objc_build_throw_stmt (tree throw_expr
)
3312 objc_init_exceptions ();
3314 if (throw_expr
== NULL
)
3316 /* If we're not inside a @catch block, there is no "current
3317 exception" to be rethrown. */
3318 if (cur_try_context
== NULL
3319 || cur_try_context
->current_catch
== NULL
)
3321 error ("%<@throw%> (rethrow) used outside of a @catch block");
3325 /* Otherwise the object is still sitting in the EXC_PTR_EXPR
3326 value that we get from the runtime. */
3327 throw_expr
= objc_build_exc_ptr ();
3330 /* A throw is just a call to the runtime throw function with the
3331 object as a parameter. */
3332 args
= tree_cons (NULL
, throw_expr
, NULL
);
3333 return add_stmt (build_function_call (objc_exception_throw_decl
, args
));
3337 objc_build_synchronized (location_t start_locus
, tree mutex
, tree body
)
3341 /* First lock the mutex. */
3342 mutex
= save_expr (mutex
);
3343 args
= tree_cons (NULL
, mutex
, NULL
);
3344 call
= build_function_call (objc_sync_enter_decl
, args
);
3345 SET_EXPR_LOCATION (call
, start_locus
);
3348 /* Build the mutex unlock. */
3349 args
= tree_cons (NULL
, mutex
, NULL
);
3350 call
= build_function_call (objc_sync_exit_decl
, args
);
3351 SET_EXPR_LOCATION (call
, input_location
);
3353 /* Put the that and the body in a TRY_FINALLY. */
3354 objc_begin_try_stmt (start_locus
, body
);
3355 objc_build_finally_clause (input_location
, call
);
3356 objc_finish_try_stmt ();
3360 /* Predefine the following data type:
3362 struct _objc_exception_data
3368 /* The following yuckiness should prevent users from having to #include
3369 <setjmp.h> in their code... */
3371 #ifdef TARGET_POWERPC
3372 /* snarfed from /usr/include/ppc/setjmp.h */
3373 #define _JBLEN (26 + 36 + 129 + 1)
3375 /* snarfed from /usr/include/i386/{setjmp,signal}.h */
3380 build_next_objc_exception_stuff (void)
3382 tree field_decl
, field_decl_chain
, index
, temp_type
;
3384 objc_exception_data_template
3385 = start_struct (RECORD_TYPE
, get_identifier (UTAG_EXCDATA
));
3387 /* int buf[_JBLEN]; */
3389 index
= build_index_type (build_int_cst (NULL_TREE
, _JBLEN
- 1));
3390 field_decl
= create_field_decl (build_array_type (integer_type_node
, index
),
3392 field_decl_chain
= field_decl
;
3394 /* void *pointers[4]; */
3396 index
= build_index_type (build_int_cst (NULL_TREE
, 4 - 1));
3397 field_decl
= create_field_decl (build_array_type (ptr_type_node
, index
),
3399 chainon (field_decl_chain
, field_decl
);
3401 finish_struct (objc_exception_data_template
, field_decl_chain
, NULL_TREE
);
3403 /* int _setjmp(...); */
3404 /* If the user includes <setjmp.h>, this shall be superseded by
3405 'int _setjmp(jmp_buf);' */
3406 temp_type
= build_function_type (integer_type_node
, NULL_TREE
);
3408 = builtin_function (TAG_SETJMP
, temp_type
, 0, NOT_BUILT_IN
, NULL
, NULL_TREE
);
3410 /* id objc_exception_extract(struct _objc_exception_data *); */
3412 = build_function_type (objc_object_type
,
3413 tree_cons (NULL_TREE
,
3414 build_pointer_type (objc_exception_data_template
),
3416 objc_exception_extract_decl
3417 = builtin_function (TAG_EXCEPTIONEXTRACT
, temp_type
, 0, NOT_BUILT_IN
, NULL
, NULL_TREE
);
3418 /* void objc_exception_try_enter(struct _objc_exception_data *); */
3419 /* void objc_exception_try_exit(struct _objc_exception_data *); */
3421 = build_function_type (void_type_node
,
3422 tree_cons (NULL_TREE
,
3423 build_pointer_type (objc_exception_data_template
),
3425 objc_exception_try_enter_decl
3426 = builtin_function (TAG_EXCEPTIONTRYENTER
, temp_type
, 0, NOT_BUILT_IN
, NULL
, NULL_TREE
);
3427 objc_exception_try_exit_decl
3428 = builtin_function (TAG_EXCEPTIONTRYEXIT
, temp_type
, 0, NOT_BUILT_IN
, NULL
, NULL_TREE
);
3430 /* int objc_exception_match(id, id); */
3432 = build_function_type (integer_type_node
,
3433 tree_cons (NULL_TREE
, objc_object_type
,
3434 tree_cons (NULL_TREE
, objc_object_type
,
3435 OBJC_VOID_AT_END
)));
3436 objc_exception_match_decl
3437 = builtin_function (TAG_EXCEPTIONMATCH
, temp_type
, 0, NOT_BUILT_IN
, NULL
, NULL_TREE
);
3441 build_objc_exception_stuff (void)
3443 tree noreturn_list
, nothrow_list
, temp_type
;
3445 noreturn_list
= tree_cons (get_identifier ("noreturn"), NULL
, NULL
);
3446 nothrow_list
= tree_cons (get_identifier ("nothrow"), NULL
, NULL
);
3448 /* void objc_exception_throw(id) __attribute__((noreturn)); */
3449 /* void objc_sync_enter(id); */
3450 /* void objc_sync_exit(id); */
3451 temp_type
= build_function_type (void_type_node
,
3452 tree_cons (NULL_TREE
, objc_object_type
,
3454 objc_exception_throw_decl
3455 = builtin_function (TAG_EXCEPTIONTHROW
, temp_type
, 0, NOT_BUILT_IN
, NULL
,
3457 objc_sync_enter_decl
3458 = builtin_function (TAG_SYNCENTER
, temp_type
, 0, NOT_BUILT_IN
,
3459 NULL
, nothrow_list
);
3461 = builtin_function (TAG_SYNCEXIT
, temp_type
, 0, NOT_BUILT_IN
,
3462 NULL
, nothrow_list
);
3466 /* struct <classname> {
3467 struct _objc_class *isa;
3472 build_private_template (tree
class)
3476 if (CLASS_STATIC_TEMPLATE (class))
3478 uprivate_record
= CLASS_STATIC_TEMPLATE (class);
3479 ivar_context
= TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
3483 uprivate_record
= start_struct (RECORD_TYPE
, CLASS_NAME (class));
3484 ivar_context
= get_class_ivars (class);
3486 finish_struct (uprivate_record
, ivar_context
, NULL_TREE
);
3488 CLASS_STATIC_TEMPLATE (class) = uprivate_record
;
3490 /* mark this record as class template - for class type checking */
3491 TREE_STATIC_TEMPLATE (uprivate_record
) = 1;
3494 objc_instance_type
= build_pointer_type (uprivate_record
);
3496 return ivar_context
;
3499 /* Begin code generation for protocols... */
3501 /* struct _objc_protocol {
3502 struct _objc_class *isa;
3503 char *protocol_name;
3504 struct _objc_protocol **protocol_list;
3505 struct _objc__method_prototype_list *instance_methods;
3506 struct _objc__method_prototype_list *class_methods;
3510 build_protocol_template (void)
3512 tree field_decl
, field_decl_chain
;
3514 objc_protocol_template
= start_struct (RECORD_TYPE
,
3515 get_identifier (UTAG_PROTOCOL
));
3517 /* struct _objc_class *isa; */
3518 field_decl
= create_field_decl (build_pointer_type
3519 (xref_tag (RECORD_TYPE
,
3520 get_identifier (UTAG_CLASS
))),
3522 field_decl_chain
= field_decl
;
3524 /* char *protocol_name; */
3525 field_decl
= create_field_decl (string_type_node
, "protocol_name");
3526 chainon (field_decl_chain
, field_decl
);
3528 /* struct _objc_protocol **protocol_list; */
3529 field_decl
= create_field_decl (build_pointer_type
3531 (objc_protocol_template
)),
3533 chainon (field_decl_chain
, field_decl
);
3535 /* struct objc_method_list *instance_methods; */
3536 field_decl
= create_field_decl (build_pointer_type
3537 (xref_tag (RECORD_TYPE
,
3539 (UTAG_METHOD_PROTOTYPE_LIST
))),
3540 "instance_methods");
3541 chainon (field_decl_chain
, field_decl
);
3543 /* struct objc_method_list *class_methods; */
3544 field_decl
= create_field_decl (build_pointer_type
3545 (xref_tag (RECORD_TYPE
,
3547 (UTAG_METHOD_PROTOTYPE_LIST
))),
3549 chainon (field_decl_chain
, field_decl
);
3551 finish_struct (objc_protocol_template
, field_decl_chain
, NULL_TREE
);
3555 build_descriptor_table_initializer (tree type
, tree entries
)
3557 tree initlist
= NULL_TREE
;
3561 tree eltlist
= NULL_TREE
;
3564 = tree_cons (NULL_TREE
,
3565 build_selector (METHOD_SEL_NAME (entries
)), NULL_TREE
);
3567 = tree_cons (NULL_TREE
,
3568 add_objc_string (METHOD_ENCODING (entries
),
3573 = tree_cons (NULL_TREE
,
3574 objc_build_constructor (type
, nreverse (eltlist
)),
3577 entries
= TREE_CHAIN (entries
);
3581 return objc_build_constructor (build_array_type (type
, 0),
3582 nreverse (initlist
));
3585 /* struct objc_method_prototype_list {
3587 struct objc_method_prototype {
3594 build_method_prototype_list_template (tree list_type
, int size
)
3596 tree objc_ivar_list_record
;
3597 tree field_decl
, field_decl_chain
;
3599 /* Generate an unnamed struct definition. */
3601 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3603 /* int method_count; */
3604 field_decl
= create_field_decl (integer_type_node
, "method_count");
3605 field_decl_chain
= field_decl
;
3607 /* struct objc_method method_list[]; */
3608 field_decl
= create_field_decl (build_array_type
3611 (build_int_cst (NULL_TREE
, size
- 1))),
3613 chainon (field_decl_chain
, field_decl
);
3615 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3617 return objc_ivar_list_record
;
3621 build_method_prototype_template (void)
3624 tree field_decl
, field_decl_chain
;
3627 = start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD_PROTOTYPE
));
3630 field_decl
= create_field_decl (objc_selector_type
, "_cmd");
3631 field_decl_chain
= field_decl
;
3633 /* char *method_types; */
3634 field_decl
= create_field_decl (string_type_node
, "method_types");
3635 chainon (field_decl_chain
, field_decl
);
3637 finish_struct (proto_record
, field_decl_chain
, NULL_TREE
);
3639 return proto_record
;
3643 objc_method_parm_type (tree type
)
3645 type
= TREE_VALUE (TREE_TYPE (type
));
3646 if (TREE_CODE (type
) == TYPE_DECL
)
3647 type
= TREE_TYPE (type
);
3648 return TYPE_MAIN_VARIANT (type
);
3652 objc_encoded_type_size (tree type
)
3654 int sz
= int_size_in_bytes (type
);
3656 /* Make all integer and enum types at least as large
3658 if (sz
> 0 && INTEGRAL_TYPE_P (type
))
3659 sz
= MAX (sz
, int_size_in_bytes (integer_type_node
));
3660 /* Treat arrays as pointers, since that's how they're
3662 else if (TREE_CODE (type
) == ARRAY_TYPE
)
3663 sz
= int_size_in_bytes (ptr_type_node
);
3668 encode_method_prototype (tree method_decl
)
3675 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
3676 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl
)));
3678 /* Encode return type. */
3679 encode_type (objc_method_parm_type (method_decl
),
3680 obstack_object_size (&util_obstack
),
3681 OBJC_ENCODE_INLINE_DEFS
);
3684 /* The first two arguments (self and _cmd) are pointers; account for
3686 i
= int_size_in_bytes (ptr_type_node
);
3687 parm_offset
= 2 * i
;
3688 for (parms
= METHOD_SEL_ARGS (method_decl
); parms
;
3689 parms
= TREE_CHAIN (parms
))
3691 tree type
= objc_method_parm_type (parms
);
3692 int sz
= objc_encoded_type_size (type
);
3694 /* If a type size is not known, bail out. */
3697 error ("%Jtype '%D' does not have a known size",
3699 /* Pretend that the encoding succeeded; the compilation will
3700 fail nevertheless. */
3701 goto finish_encoding
;
3706 sprintf (buf
, "%d@0:%d", parm_offset
, i
);
3707 obstack_grow (&util_obstack
, buf
, strlen (buf
));
3709 /* Argument types. */
3710 parm_offset
= 2 * i
;
3711 for (parms
= METHOD_SEL_ARGS (method_decl
); parms
;
3712 parms
= TREE_CHAIN (parms
))
3714 tree type
= objc_method_parm_type (parms
);
3716 /* Process argument qualifiers for user supplied arguments. */
3717 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (parms
)));
3720 encode_type (type
, obstack_object_size (&util_obstack
),
3721 OBJC_ENCODE_INLINE_DEFS
);
3723 /* Compute offset. */
3724 sprintf (buf
, "%d", parm_offset
);
3725 parm_offset
+= objc_encoded_type_size (type
);
3727 obstack_grow (&util_obstack
, buf
, strlen (buf
));
3731 obstack_1grow (&util_obstack
, '\0');
3732 result
= get_identifier (obstack_finish (&util_obstack
));
3733 obstack_free (&util_obstack
, util_firstobj
);
3738 generate_descriptor_table (tree type
, const char *name
, int size
, tree list
,
3741 tree decl
, initlist
;
3743 decl
= start_var_decl (type
, synth_id_with_class_suffix (name
, proto
));
3745 initlist
= build_tree_list (NULL_TREE
, build_int_cst (NULL_TREE
, size
));
3746 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3748 finish_var_decl (decl
, objc_build_constructor (type
, nreverse (initlist
)));
3754 generate_method_descriptors (tree protocol
)
3756 tree initlist
, chain
, method_list_template
;
3757 tree variable_length_type
3758 = xref_tag (RECORD_TYPE
,
3759 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
));
3762 if (!objc_method_prototype_template
)
3763 objc_method_prototype_template
= build_method_prototype_template ();
3765 chain
= PROTOCOL_CLS_METHODS (protocol
);
3768 size
= list_length (chain
);
3770 method_list_template
3771 = build_method_prototype_list_template (objc_method_prototype_template
,
3775 = build_descriptor_table_initializer (objc_method_prototype_template
,
3778 UOBJC_CLASS_METHODS_decl
3779 = generate_descriptor_table (method_list_template
,
3780 "_OBJC_PROTOCOL_CLASS_METHODS",
3781 size
, initlist
, protocol
);
3782 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
3785 UOBJC_CLASS_METHODS_decl
= 0;
3787 chain
= PROTOCOL_NST_METHODS (protocol
);
3790 size
= list_length (chain
);
3792 method_list_template
3793 = build_method_prototype_list_template (objc_method_prototype_template
,
3796 = build_descriptor_table_initializer (objc_method_prototype_template
,
3799 UOBJC_INSTANCE_METHODS_decl
3800 = generate_descriptor_table (method_list_template
,
3801 "_OBJC_PROTOCOL_INSTANCE_METHODS",
3802 size
, initlist
, protocol
);
3803 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
3806 UOBJC_INSTANCE_METHODS_decl
= 0;
3810 generate_protocol_references (tree plist
)
3814 /* Forward declare protocols referenced. */
3815 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
3817 tree proto
= TREE_VALUE (lproto
);
3819 if (TREE_CODE (proto
) == PROTOCOL_INTERFACE_TYPE
3820 && PROTOCOL_NAME (proto
))
3822 if (! PROTOCOL_FORWARD_DECL (proto
))
3823 build_protocol_reference (proto
);
3825 if (PROTOCOL_LIST (proto
))
3826 generate_protocol_references (PROTOCOL_LIST (proto
));
3831 /* For each protocol which was referenced either from a @protocol()
3832 expression, or because a class/category implements it (then a
3833 pointer to the protocol is stored in the struct describing the
3834 class/category), we create a statically allocated instance of the
3835 Protocol class. The code is written in such a way as to generate
3836 as few Protocol objects as possible; we generate a unique Protocol
3837 instance for each protocol, and we don't generate a Protocol
3838 instance if the protocol is never referenced (either from a
3839 @protocol() or from a class/category implementation). These
3840 statically allocated objects can be referred to via the static
3841 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
3843 The statically allocated Protocol objects that we generate here
3844 need to be fixed up at runtime in order to be used: the 'isa'
3845 pointer of the objects need to be set up to point to the 'Protocol'
3846 class, as known at runtime.
3848 The NeXT runtime fixes up all protocols at program startup time,
3849 before main() is entered. It uses a low-level trick to look up all
3850 those symbols, then loops on them and fixes them up.
3852 The GNU runtime as well fixes up all protocols before user code
3853 from the module is executed; it requires pointers to those symbols
3854 to be put in the objc_symtab (which is then passed as argument to
3855 the function __objc_exec_class() which the compiler sets up to be
3856 executed automatically when the module is loaded); setup of those
3857 Protocol objects happen in two ways in the GNU runtime: all
3858 Protocol objects referred to by a class or category implementation
3859 are fixed up when the class/category is loaded; all Protocol
3860 objects referred to by a @protocol() expression are added by the
3861 compiler to the list of statically allocated instances to fixup
3862 (the same list holding the statically allocated constant string
3863 objects). Because, as explained above, the compiler generates as
3864 few Protocol objects as possible, some Protocol object might end up
3865 being referenced multiple times when compiled with the GNU runtime,
3866 and end up being fixed up multiple times at runtime inizialization.
3867 But that doesn't hurt, it's just a little inefficient. */
3870 generate_protocols (void)
3874 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
3876 /* If a protocol was directly referenced, pull in indirect references. */
3877 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3878 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
3879 generate_protocol_references (PROTOCOL_LIST (p
));
3881 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3883 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
3884 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
3886 /* If protocol wasn't referenced, don't generate any code. */
3887 decl
= PROTOCOL_FORWARD_DECL (p
);
3892 /* Make sure we link in the Protocol class. */
3893 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
3897 if (! METHOD_ENCODING (nst_methods
))
3899 encoding
= encode_method_prototype (nst_methods
);
3900 METHOD_ENCODING (nst_methods
) = encoding
;
3902 nst_methods
= TREE_CHAIN (nst_methods
);
3907 if (! METHOD_ENCODING (cls_methods
))
3909 encoding
= encode_method_prototype (cls_methods
);
3910 METHOD_ENCODING (cls_methods
) = encoding
;
3913 cls_methods
= TREE_CHAIN (cls_methods
);
3915 generate_method_descriptors (p
);
3917 if (PROTOCOL_LIST (p
))
3918 refs_decl
= generate_protocol_list (p
);
3922 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3923 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
3926 refs_expr
= convert (build_pointer_type (build_pointer_type
3927 (objc_protocol_template
)),
3928 build_unary_op (ADDR_EXPR
, refs_decl
, 0));
3930 refs_expr
= build_int_cst (NULL_TREE
, 0);
3932 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3933 by generate_method_descriptors, which is called above. */
3934 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
3935 protocol_name_expr
, refs_expr
,
3936 UOBJC_INSTANCE_METHODS_decl
,
3937 UOBJC_CLASS_METHODS_decl
);
3938 finish_var_decl (decl
, initlist
);
3943 build_protocol_initializer (tree type
, tree protocol_name
,
3944 tree protocol_list
, tree instance_methods
,
3947 tree initlist
= NULL_TREE
, expr
;
3948 tree cast_type
= build_pointer_type
3949 (xref_tag (RECORD_TYPE
,
3950 get_identifier (UTAG_CLASS
)));
3952 /* Filling the "isa" in with one allows the runtime system to
3953 detect that the version change...should remove before final release. */
3955 expr
= build_int_cst (cast_type
, PROTOCOL_VERSION
);
3956 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3957 initlist
= tree_cons (NULL_TREE
, protocol_name
, initlist
);
3958 initlist
= tree_cons (NULL_TREE
, protocol_list
, initlist
);
3960 if (!instance_methods
)
3961 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
3964 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
3965 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3969 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
3972 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
3973 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3976 return objc_build_constructor (type
, nreverse (initlist
));
3979 /* struct _objc_category {
3980 char *category_name;
3982 struct _objc_method_list *instance_methods;
3983 struct _objc_method_list *class_methods;
3984 struct _objc_protocol_list *protocols;
3988 build_category_template (void)
3990 tree field_decl
, field_decl_chain
;
3992 objc_category_template
= start_struct (RECORD_TYPE
,
3993 get_identifier (UTAG_CATEGORY
));
3995 /* char *category_name; */
3996 field_decl
= create_field_decl (string_type_node
, "category_name");
3997 field_decl_chain
= field_decl
;
3999 /* char *class_name; */
4000 field_decl
= create_field_decl (string_type_node
, "class_name");
4001 chainon (field_decl_chain
, field_decl
);
4003 /* struct _objc_method_list *instance_methods; */
4004 field_decl
= create_field_decl (build_pointer_type
4005 (xref_tag (RECORD_TYPE
,
4007 (UTAG_METHOD_LIST
))),
4008 "instance_methods");
4009 chainon (field_decl_chain
, field_decl
);
4011 /* struct _objc_method_list *class_methods; */
4012 field_decl
= create_field_decl (build_pointer_type
4013 (xref_tag (RECORD_TYPE
,
4015 (UTAG_METHOD_LIST
))),
4017 chainon (field_decl_chain
, field_decl
);
4019 /* struct _objc_protocol **protocol_list; */
4020 field_decl
= create_field_decl (build_pointer_type
4022 (objc_protocol_template
)),
4024 chainon (field_decl_chain
, field_decl
);
4026 finish_struct (objc_category_template
, field_decl_chain
, NULL_TREE
);
4029 /* struct _objc_selector {
4035 build_selector_template (void)
4038 tree field_decl
, field_decl_chain
;
4040 objc_selector_template
4041 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SELECTOR
));
4044 field_decl
= create_field_decl (objc_selector_type
, "sel_id");
4045 field_decl_chain
= field_decl
;
4047 /* char *sel_type; */
4048 field_decl
= create_field_decl (string_type_node
, "sel_type");
4049 chainon (field_decl_chain
, field_decl
);
4051 finish_struct (objc_selector_template
, field_decl_chain
, NULL_TREE
);
4054 /* struct _objc_class {
4055 struct _objc_class *isa;
4056 struct _objc_class *super_class;
4061 struct _objc_ivar_list *ivars;
4062 struct _objc_method_list *methods;
4063 #ifdef __NEXT_RUNTIME__
4064 struct objc_cache *cache;
4066 struct sarray *dtable;
4067 struct _objc_class *subclass_list;
4068 struct _objc_class *sibling_class;
4070 struct _objc_protocol_list *protocols;
4071 #ifdef __NEXT_RUNTIME__
4074 void *gc_object_type;
4077 /* NB: The 'sel_id' and 'gc_object_type' fields are not being used by
4078 the NeXT/Apple runtime; still, the compiler must generate them to
4079 maintain backward binary compatibility (and to allow for future
4083 build_class_template (void)
4085 tree field_decl
, field_decl_chain
;
4088 = start_struct (RECORD_TYPE
, get_identifier (UTAG_CLASS
));
4090 /* struct _objc_class *isa; */
4091 field_decl
= create_field_decl (build_pointer_type (objc_class_template
),
4093 field_decl_chain
= field_decl
;
4095 /* struct _objc_class *super_class; */
4096 field_decl
= create_field_decl (build_pointer_type (objc_class_template
),
4098 chainon (field_decl_chain
, field_decl
);
4101 field_decl
= create_field_decl (string_type_node
, "name");
4102 chainon (field_decl_chain
, field_decl
);
4105 field_decl
= create_field_decl (long_integer_type_node
, "version");
4106 chainon (field_decl_chain
, field_decl
);
4109 field_decl
= create_field_decl (long_integer_type_node
, "info");
4110 chainon (field_decl_chain
, field_decl
);
4112 /* long instance_size; */
4113 field_decl
= create_field_decl (long_integer_type_node
, "instance_size");
4114 chainon (field_decl_chain
, field_decl
);
4116 /* struct _objc_ivar_list *ivars; */
4117 field_decl
= create_field_decl (build_pointer_type
4118 (xref_tag (RECORD_TYPE
,
4122 chainon (field_decl_chain
, field_decl
);
4124 /* struct _objc_method_list *methods; */
4125 field_decl
= create_field_decl (build_pointer_type
4126 (xref_tag (RECORD_TYPE
,
4128 (UTAG_METHOD_LIST
))),
4130 chainon (field_decl_chain
, field_decl
);
4132 if (flag_next_runtime
)
4134 /* struct objc_cache *cache; */
4135 field_decl
= create_field_decl (build_pointer_type
4136 (xref_tag (RECORD_TYPE
,
4140 chainon (field_decl_chain
, field_decl
);
4144 /* struct sarray *dtable; */
4145 field_decl
= create_field_decl (build_pointer_type
4146 (xref_tag (RECORD_TYPE
,
4150 chainon (field_decl_chain
, field_decl
);
4152 /* struct objc_class *subclass_list; */
4153 field_decl
= create_field_decl (build_pointer_type
4154 (objc_class_template
),
4156 chainon (field_decl_chain
, field_decl
);
4158 /* struct objc_class *sibling_class; */
4159 field_decl
= create_field_decl (build_pointer_type
4160 (objc_class_template
),
4162 chainon (field_decl_chain
, field_decl
);
4165 /* struct _objc_protocol **protocol_list; */
4166 field_decl
= create_field_decl (build_pointer_type
4168 (xref_tag (RECORD_TYPE
,
4172 chainon (field_decl_chain
, field_decl
);
4174 if (flag_next_runtime
)
4177 field_decl
= create_field_decl (build_pointer_type (void_type_node
),
4179 chainon (field_decl_chain
, field_decl
);
4182 /* void *gc_object_type; */
4183 field_decl
= create_field_decl (build_pointer_type (void_type_node
),
4185 chainon (field_decl_chain
, field_decl
);
4187 finish_struct (objc_class_template
, field_decl_chain
, NULL_TREE
);
4190 /* Generate appropriate forward declarations for an implementation. */
4193 synth_forward_declarations (void)
4197 /* static struct objc_class _OBJC_CLASS_<my_name>; */
4198 UOBJC_CLASS_decl
= build_metadata_decl ("_OBJC_CLASS",
4199 objc_class_template
);
4201 /* static struct objc_class _OBJC_METACLASS_<my_name>; */
4202 UOBJC_METACLASS_decl
= build_metadata_decl ("_OBJC_METACLASS",
4203 objc_class_template
);
4205 /* Pre-build the following entities - for speed/convenience. */
4207 an_id
= get_identifier ("super_class");
4208 ucls_super_ref
= build_component_ref (UOBJC_CLASS_decl
, an_id
);
4209 uucls_super_ref
= build_component_ref (UOBJC_METACLASS_decl
, an_id
);
4213 error_with_ivar (const char *message
, tree decl
)
4215 error ("%J%s `%s'", decl
,
4216 message
, gen_declaration (decl
));
4221 check_ivars (tree inter
, tree imp
)
4223 tree intdecls
= CLASS_RAW_IVARS (inter
);
4224 tree impdecls
= CLASS_RAW_IVARS (imp
);
4231 if (intdecls
&& TREE_CODE (intdecls
) == TYPE_DECL
)
4232 intdecls
= TREE_CHAIN (intdecls
);
4234 if (intdecls
== 0 && impdecls
== 0)
4236 if (intdecls
== 0 || impdecls
== 0)
4238 error ("inconsistent instance variable specification");
4242 t1
= TREE_TYPE (intdecls
); t2
= TREE_TYPE (impdecls
);
4244 if (!comptypes (t1
, t2
)
4245 || !tree_int_cst_equal (DECL_INITIAL (intdecls
),
4246 DECL_INITIAL (impdecls
)))
4248 if (DECL_NAME (intdecls
) == DECL_NAME (impdecls
))
4250 error_with_ivar ("conflicting instance variable type",
4252 error_with_ivar ("previous declaration of",
4255 else /* both the type and the name don't match */
4257 error ("inconsistent instance variable specification");
4262 else if (DECL_NAME (intdecls
) != DECL_NAME (impdecls
))
4264 error_with_ivar ("conflicting instance variable name",
4266 error_with_ivar ("previous declaration of",
4270 intdecls
= TREE_CHAIN (intdecls
);
4271 impdecls
= TREE_CHAIN (impdecls
);
4275 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
4276 This needs to be done just once per compilation. */
4278 /* struct _objc_super {
4279 struct _objc_object *self;
4280 struct _objc_class *super_class;
4284 build_super_template (void)
4286 tree field_decl
, field_decl_chain
;
4288 objc_super_template
= start_struct (RECORD_TYPE
, get_identifier (UTAG_SUPER
));
4290 /* struct _objc_object *self; */
4291 field_decl
= create_field_decl (objc_object_type
, "self");
4292 field_decl_chain
= field_decl
;
4294 /* struct _objc_class *super_class; */
4295 field_decl
= create_field_decl (build_pointer_type (objc_class_template
),
4297 chainon (field_decl_chain
, field_decl
);
4299 finish_struct (objc_super_template
, field_decl_chain
, NULL_TREE
);
4302 /* struct _objc_ivar {
4309 build_ivar_template (void)
4311 tree objc_ivar_id
, objc_ivar_record
;
4312 tree field_decl
, field_decl_chain
;
4314 objc_ivar_id
= get_identifier (UTAG_IVAR
);
4315 objc_ivar_record
= start_struct (RECORD_TYPE
, objc_ivar_id
);
4317 /* char *ivar_name; */
4318 field_decl
= create_field_decl (string_type_node
, "ivar_name");
4319 field_decl_chain
= field_decl
;
4321 /* char *ivar_type; */
4322 field_decl
= create_field_decl (string_type_node
, "ivar_type");
4323 chainon (field_decl_chain
, field_decl
);
4325 /* int ivar_offset; */
4326 field_decl
= create_field_decl (integer_type_node
, "ivar_offset");
4327 chainon (field_decl_chain
, field_decl
);
4329 finish_struct (objc_ivar_record
, field_decl_chain
, NULL_TREE
);
4331 return objc_ivar_record
;
4336 struct objc_ivar ivar_list[ivar_count];
4340 build_ivar_list_template (tree list_type
, int size
)
4342 tree objc_ivar_list_record
;
4343 tree field_decl
, field_decl_chain
;
4345 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
4347 /* int ivar_count; */
4348 field_decl
= create_field_decl (integer_type_node
, "ivar_count");
4349 field_decl_chain
= field_decl
;
4351 /* struct objc_ivar ivar_list[]; */
4352 field_decl
= create_field_decl (build_array_type
4355 (build_int_cst (NULL_TREE
, size
- 1))),
4357 chainon (field_decl_chain
, field_decl
);
4359 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
4361 return objc_ivar_list_record
;
4365 struct _objc__method_prototype_list *method_next;
4367 struct objc_method method_list[method_count];
4371 build_method_list_template (tree list_type
, int size
)
4373 tree objc_ivar_list_record
;
4374 tree field_decl
, field_decl_chain
;
4376 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
4378 /* struct _objc__method_prototype_list *method_next; */
4379 field_decl
= create_field_decl (build_pointer_type
4380 (xref_tag (RECORD_TYPE
,
4382 (UTAG_METHOD_PROTOTYPE_LIST
))),
4384 field_decl_chain
= field_decl
;
4386 /* int method_count; */
4387 field_decl
= create_field_decl (integer_type_node
, "method_count");
4388 chainon (field_decl_chain
, field_decl
);
4390 /* struct objc_method method_list[]; */
4391 field_decl
= create_field_decl (build_array_type
4394 (build_int_cst (NULL_TREE
, size
- 1))),
4396 chainon (field_decl_chain
, field_decl
);
4398 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
4400 return objc_ivar_list_record
;
4404 build_ivar_list_initializer (tree type
, tree field_decl
)
4406 tree initlist
= NULL_TREE
;
4410 tree ivar
= NULL_TREE
;
4413 if (DECL_NAME (field_decl
))
4414 ivar
= tree_cons (NULL_TREE
,
4415 add_objc_string (DECL_NAME (field_decl
),
4419 /* Unnamed bit-field ivar (yuck). */
4420 ivar
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), ivar
);
4423 encode_field_decl (field_decl
,
4424 obstack_object_size (&util_obstack
),
4425 OBJC_ENCODE_DONT_INLINE_DEFS
);
4427 /* Null terminate string. */
4428 obstack_1grow (&util_obstack
, 0);
4432 add_objc_string (get_identifier (obstack_finish (&util_obstack
)),
4435 obstack_free (&util_obstack
, util_firstobj
);
4438 ivar
= tree_cons (NULL_TREE
, byte_position (field_decl
), ivar
);
4439 initlist
= tree_cons (NULL_TREE
,
4440 objc_build_constructor (type
, nreverse (ivar
)),
4443 field_decl
= TREE_CHAIN (field_decl
);
4444 while (field_decl
&& TREE_CODE (field_decl
) != FIELD_DECL
);
4448 return objc_build_constructor (build_array_type (type
, 0),
4449 nreverse (initlist
));
4453 generate_ivars_list (tree type
, const char *name
, int size
, tree list
)
4455 tree decl
, initlist
;
4457 decl
= start_var_decl (type
, synth_id_with_class_suffix
4458 (name
, objc_implementation_context
));
4460 initlist
= build_tree_list (NULL_TREE
, build_int_cst (NULL_TREE
, size
));
4461 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
4463 finish_var_decl (decl
,
4464 objc_build_constructor (TREE_TYPE (decl
),
4465 nreverse (initlist
)));
4470 /* Count only the fields occurring in T. */
4472 ivar_list_length (tree t
)
4476 for (; t
; t
= TREE_CHAIN (t
))
4477 if (TREE_CODE (t
) == FIELD_DECL
)
4484 generate_ivar_lists (void)
4486 tree initlist
, ivar_list_template
, chain
;
4487 tree variable_length_type
4488 = xref_tag (RECORD_TYPE
, get_identifier (UTAG_IVAR_LIST
));
4491 generating_instance_variables
= 1;
4493 if (!objc_ivar_template
)
4494 objc_ivar_template
= build_ivar_template ();
4496 /* Only generate class variables for the root of the inheritance
4497 hierarchy since these will be the same for every class. */
4499 if (CLASS_SUPER_NAME (implementation_template
) == NULL_TREE
4500 && (chain
= TYPE_FIELDS (objc_class_template
)))
4502 size
= ivar_list_length (chain
);
4504 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
4505 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
4507 UOBJC_CLASS_VARIABLES_decl
4508 = generate_ivars_list (ivar_list_template
, "_OBJC_CLASS_VARIABLES",
4510 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl
) = variable_length_type
;
4513 UOBJC_CLASS_VARIABLES_decl
= 0;
4515 chain
= CLASS_IVARS (implementation_template
);
4518 size
= ivar_list_length (chain
);
4519 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
4520 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
4522 UOBJC_INSTANCE_VARIABLES_decl
4523 = generate_ivars_list (ivar_list_template
, "_OBJC_INSTANCE_VARIABLES",
4525 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl
) = variable_length_type
;
4528 UOBJC_INSTANCE_VARIABLES_decl
= 0;
4530 generating_instance_variables
= 0;
4534 build_dispatch_table_initializer (tree type
, tree entries
)
4536 tree initlist
= NULL_TREE
;
4540 tree elemlist
= NULL_TREE
;
4542 elemlist
= tree_cons (NULL_TREE
,
4543 build_selector (METHOD_SEL_NAME (entries
)),
4546 /* Generate the method encoding if we don't have one already. */
4547 if (! METHOD_ENCODING (entries
))
4548 METHOD_ENCODING (entries
) =
4549 encode_method_prototype (entries
);
4551 elemlist
= tree_cons (NULL_TREE
,
4552 add_objc_string (METHOD_ENCODING (entries
),
4557 = tree_cons (NULL_TREE
,
4558 convert (ptr_type_node
,
4559 build_unary_op (ADDR_EXPR
,
4560 METHOD_DEFINITION (entries
), 1)),
4563 initlist
= tree_cons (NULL_TREE
,
4564 objc_build_constructor (type
, nreverse (elemlist
)),
4567 entries
= TREE_CHAIN (entries
);
4571 return objc_build_constructor (build_array_type (type
, 0),
4572 nreverse (initlist
));
4575 /* To accomplish method prototyping without generating all kinds of
4576 inane warnings, the definition of the dispatch table entries were
4579 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
4581 struct objc_method { SEL _cmd; ...; void *_imp; }; */
4584 build_method_template (void)
4587 tree field_decl
, field_decl_chain
;
4589 _SLT_record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD
));
4592 field_decl
= create_field_decl (objc_selector_type
, "_cmd");
4593 field_decl_chain
= field_decl
;
4595 /* char *method_types; */
4596 field_decl
= create_field_decl (string_type_node
, "method_types");
4597 chainon (field_decl_chain
, field_decl
);
4600 field_decl
= create_field_decl (build_pointer_type (void_type_node
),
4602 chainon (field_decl_chain
, field_decl
);
4604 finish_struct (_SLT_record
, field_decl_chain
, NULL_TREE
);
4611 generate_dispatch_table (tree type
, const char *name
, int size
, tree list
)
4613 tree decl
, initlist
;
4615 decl
= start_var_decl (type
, synth_id_with_class_suffix
4616 (name
, objc_implementation_context
));
4618 initlist
= build_tree_list (NULL_TREE
, build_int_cst (NULL_TREE
, 0));
4619 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, size
), initlist
);
4620 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
4622 finish_var_decl (decl
,
4623 objc_build_constructor (TREE_TYPE (decl
),
4624 nreverse (initlist
)));
4630 mark_referenced_methods (void)
4632 struct imp_entry
*impent
;
4635 for (impent
= imp_list
; impent
; impent
= impent
->next
)
4637 chain
= CLASS_CLS_METHODS (impent
->imp_context
);
4640 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain
)));
4641 chain
= TREE_CHAIN (chain
);
4644 chain
= CLASS_NST_METHODS (impent
->imp_context
);
4647 cgraph_mark_needed_node (cgraph_node (METHOD_DEFINITION (chain
)));
4648 chain
= TREE_CHAIN (chain
);
4654 generate_dispatch_tables (void)
4656 tree initlist
, chain
, method_list_template
;
4657 tree variable_length_type
4658 = xref_tag (RECORD_TYPE
, get_identifier (UTAG_METHOD_LIST
));
4661 if (!objc_method_template
)
4662 objc_method_template
= build_method_template ();
4664 chain
= CLASS_CLS_METHODS (objc_implementation_context
);
4667 size
= list_length (chain
);
4669 method_list_template
4670 = build_method_list_template (objc_method_template
, size
);
4672 = build_dispatch_table_initializer (objc_method_template
, chain
);
4674 UOBJC_CLASS_METHODS_decl
4675 = generate_dispatch_table (method_list_template
,
4676 ((TREE_CODE (objc_implementation_context
)
4677 == CLASS_IMPLEMENTATION_TYPE
)
4678 ? "_OBJC_CLASS_METHODS"
4679 : "_OBJC_CATEGORY_CLASS_METHODS"),
4681 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
4684 UOBJC_CLASS_METHODS_decl
= 0;
4686 chain
= CLASS_NST_METHODS (objc_implementation_context
);
4689 size
= list_length (chain
);
4691 method_list_template
4692 = build_method_list_template (objc_method_template
, size
);
4694 = build_dispatch_table_initializer (objc_method_template
, chain
);
4696 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
4697 UOBJC_INSTANCE_METHODS_decl
4698 = generate_dispatch_table (method_list_template
,
4699 "_OBJC_INSTANCE_METHODS",
4702 /* We have a category. */
4703 UOBJC_INSTANCE_METHODS_decl
4704 = generate_dispatch_table (method_list_template
,
4705 "_OBJC_CATEGORY_INSTANCE_METHODS",
4707 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
4710 UOBJC_INSTANCE_METHODS_decl
= 0;
4714 generate_protocol_list (tree i_or_p
)
4717 tree refs_decl
, lproto
, e
, plist
;
4719 const char *ref_name
;
4721 if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
4722 || TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4723 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
4724 else if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4725 plist
= PROTOCOL_LIST (i_or_p
);
4730 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4731 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
4732 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
4735 /* Build initializer. */
4736 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), NULL_TREE
);
4737 e
= build_int_cst (build_pointer_type (objc_protocol_template
), size
);
4738 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4740 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4742 tree pval
= TREE_VALUE (lproto
);
4744 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
4745 && PROTOCOL_FORWARD_DECL (pval
))
4747 e
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (pval
), 0);
4748 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4752 /* static struct objc_protocol *refs[n]; */
4754 if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4755 ref_name
= synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", i_or_p
);
4756 else if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
)
4757 ref_name
= synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", i_or_p
);
4758 else if (TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4759 ref_name
= synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", i_or_p
);
4763 refs_decl
= start_var_decl
4765 (build_pointer_type (objc_protocol_template
),
4766 build_index_type (build_int_cst (NULL_TREE
, size
+ 2))),
4769 finish_var_decl (refs_decl
, objc_build_constructor (TREE_TYPE (refs_decl
),
4770 nreverse (initlist
)));
4776 build_category_initializer (tree type
, tree cat_name
, tree class_name
,
4777 tree instance_methods
, tree class_methods
,
4780 tree initlist
= NULL_TREE
, expr
;
4782 initlist
= tree_cons (NULL_TREE
, cat_name
, initlist
);
4783 initlist
= tree_cons (NULL_TREE
, class_name
, initlist
);
4785 if (!instance_methods
)
4786 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4789 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
4790 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4793 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4796 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
4797 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4800 /* protocol_list = */
4802 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4805 expr
= convert (build_pointer_type
4807 (objc_protocol_template
)),
4808 build_unary_op (ADDR_EXPR
, protocol_list
, 0));
4809 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4812 return objc_build_constructor (type
, nreverse (initlist
));
4815 /* struct _objc_class {
4816 struct objc_class *isa;
4817 struct objc_class *super_class;
4822 struct objc_ivar_list *ivars;
4823 struct objc_method_list *methods;
4824 if (flag_next_runtime)
4825 struct objc_cache *cache;
4827 struct sarray *dtable;
4828 struct objc_class *subclass_list;
4829 struct objc_class *sibling_class;
4831 struct objc_protocol_list *protocols;
4832 if (flag_next_runtime)
4834 void *gc_object_type;
4838 build_shared_structure_initializer (tree type
, tree isa
, tree super
,
4839 tree name
, tree size
, int status
,
4840 tree dispatch_table
, tree ivar_list
,
4843 tree initlist
= NULL_TREE
, expr
;
4846 initlist
= tree_cons (NULL_TREE
, isa
, initlist
);
4849 initlist
= tree_cons (NULL_TREE
, super
, initlist
);
4852 initlist
= tree_cons (NULL_TREE
, default_conversion (name
), initlist
);
4855 initlist
= tree_cons (NULL_TREE
, build_int_cst (long_integer_type_node
, 0),
4859 initlist
= tree_cons (NULL_TREE
,
4860 build_int_cst (long_integer_type_node
, status
),
4863 /* instance_size = */
4864 initlist
= tree_cons (NULL_TREE
, convert (long_integer_type_node
, size
),
4867 /* objc_ivar_list = */
4869 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4872 expr
= build_unary_op (ADDR_EXPR
, ivar_list
, 0);
4873 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4876 /* objc_method_list = */
4877 if (!dispatch_table
)
4878 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4881 expr
= build_unary_op (ADDR_EXPR
, dispatch_table
, 0);
4882 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4885 if (flag_next_runtime
)
4886 /* method_cache = */
4887 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4891 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4893 /* subclass_list = */
4894 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4896 /* sibling_class = */
4897 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4900 /* protocol_list = */
4901 if (! protocol_list
)
4902 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4905 expr
= convert (build_pointer_type
4907 (objc_protocol_template
)),
4908 build_unary_op (ADDR_EXPR
, protocol_list
, 0));
4909 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4912 if (flag_next_runtime
)
4914 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4916 /* gc_object_type = NULL */
4917 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 0), initlist
);
4919 return objc_build_constructor (type
, nreverse (initlist
));
4922 /* Retrieve category interface CAT_NAME (if any) associated with CLASS. */
4925 lookup_category (tree
class, tree cat_name
)
4927 tree category
= CLASS_CATEGORY_LIST (class);
4929 while (category
&& CLASS_SUPER_NAME (category
) != cat_name
)
4930 category
= CLASS_CATEGORY_LIST (category
);
4934 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4937 generate_category (tree cat
)
4940 tree initlist
, cat_name_expr
, class_name_expr
;
4941 tree protocol_decl
, category
;
4943 add_class_reference (CLASS_NAME (cat
));
4944 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
4946 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
4948 category
= lookup_category (implementation_template
,
4949 CLASS_SUPER_NAME (cat
));
4951 if (category
&& CLASS_PROTOCOL_LIST (category
))
4953 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
4954 protocol_decl
= generate_protocol_list (category
);
4959 decl
= start_var_decl (objc_category_template
,
4960 synth_id_with_class_suffix
4961 ("_OBJC_CATEGORY", objc_implementation_context
));
4963 initlist
= build_category_initializer (TREE_TYPE (decl
),
4964 cat_name_expr
, class_name_expr
,
4965 UOBJC_INSTANCE_METHODS_decl
,
4966 UOBJC_CLASS_METHODS_decl
,
4969 finish_var_decl (decl
, initlist
);
4972 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4973 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4976 generate_shared_structures (void)
4978 tree sc_spec
, decl_specs
, decl
;
4979 tree name_expr
, super_expr
, root_expr
;
4980 tree my_root_id
= NULL_TREE
, my_super_id
= NULL_TREE
;
4981 tree cast_type
, initlist
, protocol_decl
;
4983 my_super_id
= CLASS_SUPER_NAME (implementation_template
);
4986 add_class_reference (my_super_id
);
4988 /* Compute "my_root_id" - this is required for code generation.
4989 the "isa" for all meta class structures points to the root of
4990 the inheritance hierarchy (e.g. "__Object")... */
4991 my_root_id
= my_super_id
;
4994 tree my_root_int
= lookup_interface (my_root_id
);
4996 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
4997 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
5004 /* No super class. */
5005 my_root_id
= CLASS_NAME (implementation_template
);
5007 cast_type
= build_pointer_type (objc_class_template
);
5008 name_expr
= add_objc_string (CLASS_NAME (implementation_template
),
5011 /* Install class `isa' and `super' pointers at runtime. */
5014 super_expr
= add_objc_string (my_super_id
, class_names
);
5015 super_expr
= build_c_cast (cast_type
, super_expr
); /* cast! */
5018 super_expr
= build_int_cst (NULL_TREE
, 0);
5020 root_expr
= add_objc_string (my_root_id
, class_names
);
5021 root_expr
= build_c_cast (cast_type
, root_expr
); /* cast! */
5023 if (CLASS_PROTOCOL_LIST (implementation_template
))
5025 generate_protocol_references
5026 (CLASS_PROTOCOL_LIST (implementation_template
));
5027 protocol_decl
= generate_protocol_list (implementation_template
);
5032 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
5034 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
5035 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
5037 decl
= start_var_decl (objc_class_template
,
5039 (DECL_NAME (UOBJC_METACLASS_decl
)));
5042 = build_shared_structure_initializer
5044 root_expr
, super_expr
, name_expr
,
5045 convert (integer_type_node
, TYPE_SIZE_UNIT (objc_class_template
)),
5047 UOBJC_CLASS_METHODS_decl
,
5048 UOBJC_CLASS_VARIABLES_decl
,
5051 finish_var_decl (decl
, initlist
);
5053 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
5055 decl
= start_var_decl (objc_class_template
,
5057 (DECL_NAME (UOBJC_CLASS_decl
)));
5060 = build_shared_structure_initializer
5062 build_unary_op (ADDR_EXPR
, UOBJC_METACLASS_decl
, 0),
5063 super_expr
, name_expr
,
5064 convert (integer_type_node
,
5065 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
5066 (implementation_template
))),
5068 UOBJC_INSTANCE_METHODS_decl
,
5069 UOBJC_INSTANCE_VARIABLES_decl
,
5072 finish_var_decl (decl
, initlist
);
5077 synth_id_with_class_suffix (const char *preamble
, tree ctxt
)
5079 static char string
[BUFSIZE
];
5081 if (TREE_CODE (ctxt
) == CLASS_IMPLEMENTATION_TYPE
5082 || TREE_CODE (ctxt
) == CLASS_INTERFACE_TYPE
)
5084 sprintf (string
, "%s_%s", preamble
,
5085 IDENTIFIER_POINTER (CLASS_NAME (ctxt
)));
5087 else if (TREE_CODE (ctxt
) == CATEGORY_IMPLEMENTATION_TYPE
5088 || TREE_CODE (ctxt
) == CATEGORY_INTERFACE_TYPE
)
5090 /* We have a category. */
5091 const char *const class_name
5092 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
5093 const char *const class_super_name
5094 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
));
5095 sprintf (string
, "%s_%s_%s", preamble
, class_name
, class_super_name
);
5097 else if (TREE_CODE (ctxt
) == PROTOCOL_INTERFACE_TYPE
)
5099 const char *protocol_name
= IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt
));
5100 sprintf (string
, "%s_%s", preamble
, protocol_name
);
5108 /* If type is empty or only type qualifiers are present, add default
5109 type of id (otherwise grokdeclarator will default to int). */
5112 adjust_type_for_id_default (tree type
)
5115 type
= make_node (TREE_LIST
);
5117 if (!TREE_VALUE (type
))
5118 TREE_VALUE (type
) = objc_object_type
;
5119 else if (TREE_CODE (TREE_VALUE (type
)) == RECORD_TYPE
5120 && TYPED_OBJECT (TREE_VALUE (type
)))
5121 error ("can not use an object as parameter to a method");
5128 selector ':' '(' typename ')' identifier
5131 Transform an Objective-C keyword argument into
5132 the C equivalent parameter declarator.
5134 In: key_name, an "identifier_node" (optional).
5135 arg_type, a "tree_list" (optional).
5136 arg_name, an "identifier_node".
5138 Note: It would be really nice to strongly type the preceding
5139 arguments in the function prototype; however, then I
5140 could not use the "accessor" macros defined in "tree.h".
5142 Out: an instance of "keyword_decl". */
5145 objc_build_keyword_decl (tree key_name
, tree arg_type
, tree arg_name
)
5149 /* If no type is specified, default to "id". */
5150 arg_type
= adjust_type_for_id_default (arg_type
);
5152 keyword_decl
= make_node (KEYWORD_DECL
);
5154 TREE_TYPE (keyword_decl
) = arg_type
;
5155 KEYWORD_ARG_NAME (keyword_decl
) = arg_name
;
5156 KEYWORD_KEY_NAME (keyword_decl
) = key_name
;
5158 return keyword_decl
;
5161 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
5164 build_keyword_selector (tree selector
)
5167 tree key_chain
, key_name
;
5170 /* Scan the selector to see how much space we'll need. */
5171 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
5173 if (TREE_CODE (selector
) == KEYWORD_DECL
)
5174 key_name
= KEYWORD_KEY_NAME (key_chain
);
5175 else if (TREE_CODE (selector
) == TREE_LIST
)
5176 key_name
= TREE_PURPOSE (key_chain
);
5181 len
+= IDENTIFIER_LENGTH (key_name
) + 1;
5183 /* Just a ':' arg. */
5187 buf
= (char *) alloca (len
+ 1);
5188 /* Start the buffer out as an empty string. */
5191 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
5193 if (TREE_CODE (selector
) == KEYWORD_DECL
)
5194 key_name
= KEYWORD_KEY_NAME (key_chain
);
5195 else if (TREE_CODE (selector
) == TREE_LIST
)
5197 key_name
= TREE_PURPOSE (key_chain
);
5198 /* The keyword decl chain will later be used as a function argument
5199 chain. Unhook the selector itself so as to not confuse other
5200 parts of the compiler. */
5201 TREE_PURPOSE (key_chain
) = NULL_TREE
;
5207 strcat (buf
, IDENTIFIER_POINTER (key_name
));
5211 return get_identifier (buf
);
5214 /* Used for declarations and definitions. */
5217 build_method_decl (enum tree_code code
, tree ret_type
, tree selector
,
5222 /* If no type is specified, default to "id". */
5223 ret_type
= adjust_type_for_id_default (ret_type
);
5225 method_decl
= make_node (code
);
5226 TREE_TYPE (method_decl
) = ret_type
;
5228 /* If we have a keyword selector, create an identifier_node that
5229 represents the full selector name (`:' included)... */
5230 if (TREE_CODE (selector
) == KEYWORD_DECL
)
5232 METHOD_SEL_NAME (method_decl
) = build_keyword_selector (selector
);
5233 METHOD_SEL_ARGS (method_decl
) = selector
;
5234 METHOD_ADD_ARGS (method_decl
) = add_args
;
5238 METHOD_SEL_NAME (method_decl
) = selector
;
5239 METHOD_SEL_ARGS (method_decl
) = NULL_TREE
;
5240 METHOD_ADD_ARGS (method_decl
) = NULL_TREE
;
5246 #define METHOD_DEF 0
5247 #define METHOD_REF 1
5249 /* Used by `build_objc_method_call' and `comp_proto_with_proto'. Return
5250 an argument list for method METH. CONTEXT is either METHOD_DEF or
5251 METHOD_REF, saying whether we are trying to define a method or call
5252 one. SUPERFLAG says this is for a send to super; this makes a
5253 difference for the NeXT calling sequence in which the lookup and
5254 the method call are done together. If METH is null, user-defined
5255 arguments (i.e., beyond self and _cmd) shall be represented by `...'. */
5258 get_arg_type_list (tree meth
, int context
, int superflag
)
5262 /* Receiver type. */
5263 if (flag_next_runtime
&& superflag
)
5264 arglist
= build_tree_list (NULL_TREE
, objc_super_type
);
5265 else if (context
== METHOD_DEF
&& TREE_CODE (meth
) == INSTANCE_METHOD_DECL
)
5266 arglist
= build_tree_list (NULL_TREE
, objc_instance_type
);
5268 arglist
= build_tree_list (NULL_TREE
, objc_object_type
);
5270 /* Selector type - will eventually change to `int'. */
5271 chainon (arglist
, build_tree_list (NULL_TREE
, objc_selector_type
));
5273 /* No actual method prototype given -- assume that remaining arguments
5278 /* Build a list of argument types. */
5279 for (akey
= METHOD_SEL_ARGS (meth
); akey
; akey
= TREE_CHAIN (akey
))
5281 tree arg_type
= TREE_VALUE (TREE_TYPE (akey
));
5283 chainon (arglist
, build_tree_list (NULL_TREE
, arg_type
));
5286 if (METHOD_ADD_ARGS (meth
))
5288 for (akey
= TREE_CHAIN (METHOD_ADD_ARGS (meth
));
5289 akey
; akey
= TREE_CHAIN (akey
))
5291 tree arg_type
= TREE_TYPE (TREE_VALUE (akey
));
5293 chainon (arglist
, build_tree_list (NULL_TREE
, arg_type
));
5296 if (!TREE_OVERFLOW (METHOD_ADD_ARGS (meth
)))
5297 goto lack_of_ellipsis
;
5302 chainon (arglist
, OBJC_VOID_AT_END
);
5309 check_duplicates (hash hsh
, int methods
, int is_class
)
5311 tree meth
= NULL_TREE
;
5319 /* We have two or more methods with the same name but
5323 warning ("multiple %s named `%c%s' found",
5324 methods
? "methods" : "selectors",
5325 (is_class
? '+' : '-'),
5326 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
5328 warn_with_method (methods
? "using" : "found",
5329 ((TREE_CODE (meth
) == INSTANCE_METHOD_DECL
)
5333 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
5334 warn_with_method ("also found",
5335 ((TREE_CODE (loop
->value
) == INSTANCE_METHOD_DECL
)
5344 /* If RECEIVER is a class reference, return the identifier node for
5345 the referenced class. RECEIVER is created by objc_get_class_reference,
5346 so we check the exact form created depending on which runtimes are
5350 receiver_is_class_object (tree receiver
, int self
, int super
)
5352 tree chain
, exp
, arg
;
5354 /* The receiver is 'self' or 'super' in the context of a class method. */
5355 if (objc_method_context
5356 && TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
5359 ? CLASS_SUPER_NAME (implementation_template
)
5360 : CLASS_NAME (implementation_template
));
5362 if (flag_next_runtime
)
5364 /* The receiver is a variable created by
5365 build_class_reference_decl. */
5366 if (TREE_CODE (receiver
) == VAR_DECL
&& IS_CLASS (TREE_TYPE (receiver
)))
5367 /* Look up the identifier. */
5368 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
5369 if (TREE_PURPOSE (chain
) == receiver
)
5370 return TREE_VALUE (chain
);
5373 /* The receiver is a function call that returns an id. Check if
5374 it is a call to objc_getClass, if so, pick up the class name. */
5375 if (TREE_CODE (receiver
) == CALL_EXPR
5376 && (exp
= TREE_OPERAND (receiver
, 0))
5377 && TREE_CODE (exp
) == ADDR_EXPR
5378 && (exp
= TREE_OPERAND (exp
, 0))
5379 && TREE_CODE (exp
) == FUNCTION_DECL
5380 /* For some reason, we sometimes wind up with multiple FUNCTION_DECL
5381 prototypes for objc_get_class(). Thankfully, they seem to share the
5382 same function type. */
5383 && TREE_TYPE (exp
) == TREE_TYPE (objc_get_class_decl
)
5384 && !strcmp (IDENTIFIER_POINTER (DECL_NAME (exp
)), TAG_GETCLASS
)
5385 /* We have a call to objc_get_class/objc_getClass! */
5386 && (arg
= TREE_OPERAND (receiver
, 1))
5387 && TREE_CODE (arg
) == TREE_LIST
5388 && (arg
= TREE_VALUE (arg
)))
5391 if (TREE_CODE (arg
) == ADDR_EXPR
5392 && (arg
= TREE_OPERAND (arg
, 0))
5393 && TREE_CODE (arg
) == STRING_CST
)
5394 /* Finally, we have the class name. */
5395 return get_identifier (TREE_STRING_POINTER (arg
));
5400 /* If we are currently building a message expr, this holds
5401 the identifier of the selector of the message. This is
5402 used when printing warnings about argument mismatches. */
5404 static tree current_objc_message_selector
= 0;
5407 objc_message_selector (void)
5409 return current_objc_message_selector
;
5412 /* Construct an expression for sending a message.
5413 MESS has the object to send to in TREE_PURPOSE
5414 and the argument list (including selector) in TREE_VALUE.
5416 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
5417 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
5420 objc_build_message_expr (tree mess
)
5422 tree receiver
= TREE_PURPOSE (mess
);
5425 tree args
= TREE_PURPOSE (TREE_VALUE (mess
));
5427 tree args
= TREE_VALUE (mess
);
5429 tree method_params
= NULL_TREE
;
5431 if (TREE_CODE (receiver
) == ERROR_MARK
)
5432 return error_mark_node
;
5434 /* Obtain the full selector name. */
5435 if (TREE_CODE (args
) == IDENTIFIER_NODE
)
5436 /* A unary selector. */
5438 else if (TREE_CODE (args
) == TREE_LIST
)
5439 sel_name
= build_keyword_selector (args
);
5443 /* Build the parameter list to give to the method. */
5444 if (TREE_CODE (args
) == TREE_LIST
)
5446 method_params
= chainon (args
, TREE_VALUE (TREE_VALUE (mess
)));
5449 tree chain
= args
, prev
= NULL_TREE
;
5451 /* We have a keyword selector--check for comma expressions. */
5454 tree element
= TREE_VALUE (chain
);
5456 /* We have a comma expression, must collapse... */
5457 if (TREE_CODE (element
) == TREE_LIST
)
5460 TREE_CHAIN (prev
) = element
;
5465 chain
= TREE_CHAIN (chain
);
5467 method_params
= args
;
5472 if (processing_template_decl
)
5473 /* Must wait until template instantiation time. */
5474 return build_min_nt (MESSAGE_SEND_EXPR
, receiver
, sel_name
,
5478 return objc_finish_message_expr (receiver
, sel_name
, method_params
);
5481 /* Look up method SEL_NAME that would be suitable for receiver
5482 of type 'id' (if IS_CLASS is zero) or 'Class' (if IS_CLASS is
5483 nonzero), and report on any duplicates. */
5486 lookup_method_in_hash_lists (tree sel_name
, int is_class
)
5488 hash method_prototype
= NULL
;
5491 method_prototype
= hash_lookup (nst_method_hash_list
,
5494 if (!method_prototype
)
5496 method_prototype
= hash_lookup (cls_method_hash_list
,
5501 return check_duplicates (method_prototype
, 1, is_class
);
5504 /* The 'objc_finish_message_expr' routine is called from within
5505 'objc_build_message_expr' for non-template functions. In the case of
5506 C++ template functions, it is called from 'build_expr_from_tree'
5507 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
5510 objc_finish_message_expr (tree receiver
, tree sel_name
, tree method_params
)
5512 tree method_prototype
= NULL_TREE
, rprotos
= NULL_TREE
, rtype
;
5513 tree selector
, retval
, class_tree
;
5514 int self
, super
, have_cast
;
5516 /* Extract the receiver of the message, as well as its type
5517 (where the latter may take the form of a cast or be inferred
5518 from the implementation context). */
5520 while (TREE_CODE (rtype
) == COMPOUND_EXPR
5521 || TREE_CODE (rtype
) == MODIFY_EXPR
5522 || TREE_CODE (rtype
) == NOP_EXPR
5523 || TREE_CODE (rtype
) == CONVERT_EXPR
5524 || TREE_CODE (rtype
) == COMPONENT_REF
)
5525 rtype
= TREE_OPERAND (rtype
, 0);
5526 self
= (rtype
== self_decl
);
5527 super
= (rtype
== UOBJC_SUPER_decl
);
5528 rtype
= TREE_TYPE (receiver
);
5529 have_cast
= (TREE_CODE (receiver
) == NOP_EXPR
5530 || (TREE_CODE (receiver
) == COMPOUND_EXPR
5531 && !IS_SUPER (rtype
)));
5533 /* If the receiver is a class object, retrieve the corresponding
5534 @interface, if one exists. */
5535 class_tree
= receiver_is_class_object (receiver
, self
, super
);
5537 /* Now determine the receiver type (if an explicit cast has not been
5542 rtype
= lookup_interface (class_tree
);
5543 /* Handle `self' and `super'. */
5546 if (!CLASS_SUPER_NAME (implementation_template
))
5548 error ("no super class declared in @interface for `%s'",
5549 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
5550 return error_mark_node
;
5552 rtype
= lookup_interface (CLASS_SUPER_NAME (implementation_template
));
5555 rtype
= lookup_interface (CLASS_NAME (implementation_template
));
5558 /* If receiver is of type `id' or `Class' (or if the @interface for a
5559 class is not visible), we shall be satisfied with the existence of
5560 any instance or class method. */
5561 if (!rtype
|| objc_is_id (rtype
))
5564 rtype
= xref_tag (RECORD_TYPE
, class_tree
);
5565 else if (IS_ID (rtype
))
5567 rprotos
= TYPE_PROTOCOL_LIST (rtype
);
5572 class_tree
= objc_class_name
;
5573 OBJC_SET_TYPE_NAME (rtype
, class_tree
);
5578 = lookup_method_in_protocol_list (rprotos
, sel_name
,
5579 class_tree
!= NULL_TREE
);
5580 if (!method_prototype
&& !rprotos
)
5582 = lookup_method_in_hash_lists (sel_name
,
5583 class_tree
!= NULL_TREE
);
5587 tree orig_rtype
= rtype
, saved_rtype
;
5589 if (TREE_CODE (rtype
) == POINTER_TYPE
)
5590 rtype
= TREE_TYPE (rtype
);
5591 /* Traverse typedef aliases */
5592 while (TREE_CODE (rtype
) == RECORD_TYPE
&& OBJC_TYPE_NAME (rtype
)
5593 && TREE_CODE (OBJC_TYPE_NAME (rtype
)) == TYPE_DECL
5594 && DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype
)))
5595 rtype
= DECL_ORIGINAL_TYPE (OBJC_TYPE_NAME (rtype
));
5596 saved_rtype
= rtype
;
5597 if (TYPED_OBJECT (rtype
))
5599 rprotos
= TYPE_PROTOCOL_LIST (rtype
);
5600 rtype
= lookup_interface (OBJC_TYPE_NAME (rtype
));
5602 /* If we could not find an @interface declaration, we must have
5603 only seen a @class declaration; so, we cannot say anything
5604 more intelligent about which methods the receiver will
5607 rtype
= saved_rtype
;
5608 else if (TREE_CODE (rtype
) == CLASS_INTERFACE_TYPE
5609 || TREE_CODE (rtype
) == CLASS_IMPLEMENTATION_TYPE
)
5611 /* We have a valid ObjC class name. Look up the method name
5612 in the published @interface for the class (and its
5615 = lookup_method_static (rtype
, sel_name
, class_tree
!= NULL_TREE
);
5617 /* If the method was not found in the @interface, it may still
5618 exist locally as part of the @implementation. */
5619 if (!method_prototype
&& objc_implementation_context
5620 && CLASS_NAME (objc_implementation_context
)
5621 == OBJC_TYPE_NAME (rtype
))
5625 ? CLASS_CLS_METHODS (objc_implementation_context
)
5626 : CLASS_NST_METHODS (objc_implementation_context
)),
5629 /* If we haven't found a candidate method by now, try looking for
5630 it in the protocol list. */
5631 if (!method_prototype
&& rprotos
)
5633 = lookup_method_in_protocol_list (rprotos
, sel_name
,
5634 class_tree
!= NULL_TREE
);
5638 warning ("invalid receiver type `%s'",
5639 gen_type_name (orig_rtype
));
5640 rtype
= rprotos
= NULL_TREE
;
5644 if (!method_prototype
)
5646 static bool warn_missing_methods
= false;
5649 warning ("`%s' may not respond to `%c%s'",
5650 IDENTIFIER_POINTER (OBJC_TYPE_NAME (rtype
)),
5651 (class_tree
? '+' : '-'),
5652 IDENTIFIER_POINTER (sel_name
));
5654 warning ("`%c%s' not implemented by protocol(s)",
5655 (class_tree
? '+' : '-'),
5656 IDENTIFIER_POINTER (sel_name
));
5657 if (!warn_missing_methods
)
5659 warning ("(Messages without a matching method signature");
5660 warning ("will be assumed to return `id' and accept");
5661 warning ("`...' as arguments.)");
5662 warn_missing_methods
= true;
5666 /* Save the selector name for printing error messages. */
5667 current_objc_message_selector
= sel_name
;
5669 /* Build the parameters list for looking up the method.
5670 These are the object itself and the selector. */
5672 if (flag_typed_selectors
)
5673 selector
= build_typed_selector_reference (sel_name
, method_prototype
);
5675 selector
= build_selector_reference (sel_name
);
5677 retval
= build_objc_method_call (super
, method_prototype
,
5679 selector
, method_params
);
5681 current_objc_message_selector
= 0;
5686 /* Build a tree expression to send OBJECT the operation SELECTOR,
5687 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5688 assuming the method has prototype METHOD_PROTOTYPE.
5689 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5690 Use METHOD_PARAMS as list of args to pass to the method.
5691 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5694 build_objc_method_call (int super_flag
, tree method_prototype
,
5695 tree lookup_object
, tree selector
,
5698 tree sender
= (super_flag
? umsg_super_decl
:
5699 (!flag_next_runtime
|| flag_nil_receivers
5701 : umsg_nonnil_decl
));
5702 tree rcv_p
= (super_flag
? objc_super_type
: objc_object_type
);
5704 /* If a prototype for the method to be called exists, then cast
5705 the sender's return type and arguments to match that of the method.
5706 Otherwise, leave sender as is. */
5709 ? TREE_VALUE (TREE_TYPE (method_prototype
))
5710 : objc_object_type
);
5712 = build_pointer_type
5713 (build_function_type
5716 (method_prototype
, METHOD_REF
, super_flag
)));
5719 lookup_object
= build_c_cast (rcv_p
, lookup_object
);
5721 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
5722 lookup_object
= save_expr (lookup_object
);
5724 if (flag_next_runtime
)
5726 /* If we are returning a struct in memory, and the address
5727 of that memory location is passed as a hidden first
5728 argument, then change which messenger entry point this
5729 expr will call. NB: Note that sender_cast remains
5730 unchanged (it already has a struct return type). */
5731 if (!targetm
.calls
.struct_value_rtx (0, 0)
5732 && (TREE_CODE (ret_type
) == RECORD_TYPE
5733 || TREE_CODE (ret_type
) == UNION_TYPE
)
5734 && targetm
.calls
.return_in_memory (ret_type
, 0))
5735 sender
= (super_flag
? umsg_super_stret_decl
:
5736 flag_nil_receivers
? umsg_stret_decl
: umsg_nonnil_stret_decl
);
5738 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5739 tree_cons (NULL_TREE
, selector
,
5741 method
= build_fold_addr_expr (sender
);
5745 /* This is the portable (GNU) way. */
5748 /* First, call the lookup function to get a pointer to the method,
5749 then cast the pointer, then call it with the method arguments. */
5751 object
= (super_flag
? self_decl
: lookup_object
);
5753 t
= tree_cons (NULL_TREE
, selector
, NULL_TREE
);
5754 t
= tree_cons (NULL_TREE
, lookup_object
, t
);
5755 method
= build_function_call (sender
, t
);
5757 /* Pass the object to the method. */
5758 method_params
= tree_cons (NULL_TREE
, object
,
5759 tree_cons (NULL_TREE
, selector
,
5763 /* ??? Selector is not at this point something we can use inside
5764 the compiler itself. Set it to garbage for the nonce. */
5765 t
= build (OBJ_TYPE_REF
, sender_cast
, method
, lookup_object
, size_zero_node
);
5766 return build_function_call (t
, method_params
);
5770 build_protocol_reference (tree p
)
5773 const char *proto_name
;
5775 /* static struct _objc_protocol _OBJC_PROTOCOL_<mumble>; */
5777 proto_name
= synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
);
5778 decl
= start_var_decl (objc_protocol_template
, proto_name
);
5780 PROTOCOL_FORWARD_DECL (p
) = decl
;
5783 /* This function is called by the parser when (and only when) a
5784 @protocol() expression is found, in order to compile it. */
5786 objc_build_protocol_expr (tree protoname
)
5789 tree p
= lookup_protocol (protoname
);
5793 error ("cannot find protocol declaration for `%s'",
5794 IDENTIFIER_POINTER (protoname
));
5795 return error_mark_node
;
5798 if (!PROTOCOL_FORWARD_DECL (p
))
5799 build_protocol_reference (p
);
5801 expr
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
5803 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
5804 if we have it, rather than converting it here. */
5805 expr
= convert (objc_protocol_type
, expr
);
5807 /* The @protocol() expression is being compiled into a pointer to a
5808 statically allocated instance of the Protocol class. To become
5809 usable at runtime, the 'isa' pointer of the instance need to be
5810 fixed up at runtime by the runtime library, to point to the
5811 actual 'Protocol' class. */
5813 /* For the GNU runtime, put the static Protocol instance in the list
5814 of statically allocated instances, so that we make sure that its
5815 'isa' pointer is fixed up at runtime by the GNU runtime library
5816 to point to the Protocol class (at runtime, when loading the
5817 module, the GNU runtime library loops on the statically allocated
5818 instances (as found in the defs field in objc_symtab) and fixups
5819 all the 'isa' pointers of those objects). */
5820 if (! flag_next_runtime
)
5822 /* This type is a struct containing the fields of a Protocol
5823 object. (Cfr. objc_protocol_type instead is the type of a pointer
5824 to such a struct). */
5825 tree protocol_struct_type
= xref_tag
5826 (RECORD_TYPE
, get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
5829 /* Look for the list of Protocol statically allocated instances
5830 to fixup at runtime. Create a new list to hold Protocol
5831 statically allocated instances, if the list is not found. At
5832 present there is only another list, holding NSConstantString
5833 static instances to be fixed up at runtime. */
5834 for (chain
= &objc_static_instances
;
5835 *chain
&& TREE_VALUE (*chain
) != protocol_struct_type
;
5836 chain
= &TREE_CHAIN (*chain
));
5839 *chain
= tree_cons (NULL_TREE
, protocol_struct_type
, NULL_TREE
);
5840 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type
),
5844 /* Add this statically allocated instance to the Protocol list. */
5845 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
,
5846 PROTOCOL_FORWARD_DECL (p
),
5847 TREE_PURPOSE (*chain
));
5854 /* This function is called by the parser when a @selector() expression
5855 is found, in order to compile it. It is only called by the parser
5856 and only to compile a @selector(). */
5858 objc_build_selector_expr (tree selnamelist
)
5862 /* Obtain the full selector name. */
5863 if (TREE_CODE (selnamelist
) == IDENTIFIER_NODE
)
5864 /* A unary selector. */
5865 selname
= selnamelist
;
5866 else if (TREE_CODE (selnamelist
) == TREE_LIST
)
5867 selname
= build_keyword_selector (selnamelist
);
5871 /* If we are required to check @selector() expressions as they
5872 are found, check that the selector has been declared. */
5873 if (warn_undeclared_selector
)
5875 /* Look the selector up in the list of all known class and
5876 instance methods (up to this line) to check that the selector
5880 /* First try with instance methods. */
5881 hsh
= hash_lookup (nst_method_hash_list
, selname
);
5883 /* If not found, try with class methods. */
5886 hsh
= hash_lookup (cls_method_hash_list
, selname
);
5889 /* If still not found, print out a warning. */
5892 warning ("undeclared selector `%s'", IDENTIFIER_POINTER (selname
));
5897 if (flag_typed_selectors
)
5898 return build_typed_selector_reference (selname
, 0);
5900 return build_selector_reference (selname
);
5904 objc_build_encode_expr (tree type
)
5909 encode_type (type
, obstack_object_size (&util_obstack
),
5910 OBJC_ENCODE_INLINE_DEFS
);
5911 obstack_1grow (&util_obstack
, 0); /* null terminate string */
5912 string
= obstack_finish (&util_obstack
);
5914 /* Synthesize a string that represents the encoded struct/union. */
5915 result
= my_build_string (strlen (string
) + 1, string
);
5916 obstack_free (&util_obstack
, util_firstobj
);
5921 build_ivar_reference (tree id
)
5923 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
5925 /* Historically, a class method that produced objects (factory
5926 method) would assign `self' to the instance that it
5927 allocated. This would effectively turn the class method into
5928 an instance method. Following this assignment, the instance
5929 variables could be accessed. That practice, while safe,
5930 violates the simple rule that a class method should not refer
5931 to an instance variable. It's better to catch the cases
5932 where this is done unknowingly than to support the above
5934 warning ("instance variable `%s' accessed in class method",
5935 IDENTIFIER_POINTER (id
));
5936 self_decl
= convert (objc_instance_type
, self_decl
); /* cast */
5939 return build_component_ref (build_indirect_ref (self_decl
, "->"), id
);
5942 /* Compute a hash value for a given method SEL_NAME. */
5945 hash_func (tree sel_name
)
5947 const unsigned char *s
5948 = (const unsigned char *)IDENTIFIER_POINTER (sel_name
);
5952 h
= h
* 67 + *s
++ - 113;
5959 nst_method_hash_list
5960 = (hash
*) ggc_alloc_cleared (SIZEHASHTABLE
* sizeof (hash
));
5961 cls_method_hash_list
5962 = (hash
*) ggc_alloc_cleared (SIZEHASHTABLE
* sizeof (hash
));
5964 /* Initialize the hash table used to hold the constant string objects. */
5965 string_htab
= htab_create_ggc (31, string_hash
,
5969 /* WARNING!!!! hash_enter is called with a method, and will peek
5970 inside to find its selector! But hash_lookup is given a selector
5971 directly, and looks for the selector that's inside the found
5972 entry's key (method) for comparison. */
5975 hash_enter (hash
*hashlist
, tree method
)
5978 int slot
= hash_func (METHOD_SEL_NAME (method
)) % SIZEHASHTABLE
;
5980 obj
= (hash
) ggc_alloc (sizeof (struct hashed_entry
));
5982 obj
->next
= hashlist
[slot
];
5985 hashlist
[slot
] = obj
; /* append to front */
5989 hash_lookup (hash
*hashlist
, tree sel_name
)
5993 target
= hashlist
[hash_func (sel_name
) % SIZEHASHTABLE
];
5997 if (sel_name
== METHOD_SEL_NAME (target
->key
))
6000 target
= target
->next
;
6006 hash_add_attr (hash entry
, tree value
)
6010 obj
= (attr
) ggc_alloc (sizeof (struct hashed_attribute
));
6011 obj
->next
= entry
->list
;
6014 entry
->list
= obj
; /* append to front */
6018 lookup_method (tree mchain
, tree method
)
6022 if (TREE_CODE (method
) == IDENTIFIER_NODE
)
6025 key
= METHOD_SEL_NAME (method
);
6029 if (METHOD_SEL_NAME (mchain
) == key
)
6032 mchain
= TREE_CHAIN (mchain
);
6038 lookup_method_static (tree interface
, tree ident
, int is_class
)
6040 tree meth
= NULL_TREE
, root_inter
= NULL_TREE
;
6041 tree inter
= interface
;
6045 tree chain
= is_class
? CLASS_CLS_METHODS (inter
) : CLASS_NST_METHODS (inter
);
6046 tree category
= inter
;
6048 /* First, look up the method in the class itself. */
6049 if ((meth
= lookup_method (chain
, ident
)))
6052 /* Failing that, look for the method in each category of the class. */
6053 while ((category
= CLASS_CATEGORY_LIST (category
)))
6055 chain
= is_class
? CLASS_CLS_METHODS (category
) : CLASS_NST_METHODS (category
);
6057 /* Check directly in each category. */
6058 if ((meth
= lookup_method (chain
, ident
)))
6061 /* Failing that, check in each category's protocols. */
6062 if (CLASS_PROTOCOL_LIST (category
))
6064 if ((meth
= (lookup_method_in_protocol_list
6065 (CLASS_PROTOCOL_LIST (category
), ident
, is_class
))))
6070 /* If not found in categories, check in protocols of the main class. */
6071 if (CLASS_PROTOCOL_LIST (inter
))
6073 if ((meth
= (lookup_method_in_protocol_list
6074 (CLASS_PROTOCOL_LIST (inter
), ident
, is_class
))))
6078 /* Failing that, climb up the inheritance hierarchy. */
6080 inter
= lookup_interface (CLASS_SUPER_NAME (inter
));
6084 /* If no class (factory) method was found, check if an _instance_
6085 method of the same name exists in the root class. This is what
6086 the Objective-C runtime will do. If an instance method was not
6088 return is_class
? lookup_method_static (root_inter
, ident
, 0): NULL_TREE
;
6091 /* Add the method to the hash list if it doesn't contain an identical
6094 add_method_to_hash_list (hash
*hash_list
, tree method
)
6098 if (!(hsh
= hash_lookup (hash_list
, METHOD_SEL_NAME (method
))))
6100 /* Install on a global chain. */
6101 hash_enter (hash_list
, method
);
6105 /* Check types against those; if different, add to a list. */
6107 int already_there
= comp_proto_with_proto (method
, hsh
->key
);
6108 for (loop
= hsh
->list
; !already_there
&& loop
; loop
= loop
->next
)
6109 already_there
|= comp_proto_with_proto (method
, loop
->value
);
6111 hash_add_attr (hsh
, method
);
6116 objc_add_method (tree
class, tree method
, int is_class
)
6120 if (!(mth
= lookup_method (is_class
6121 ? CLASS_CLS_METHODS (class)
6122 : CLASS_NST_METHODS (class), method
)))
6124 /* put method on list in reverse order */
6127 TREE_CHAIN (method
) = CLASS_CLS_METHODS (class);
6128 CLASS_CLS_METHODS (class) = method
;
6132 TREE_CHAIN (method
) = CLASS_NST_METHODS (class);
6133 CLASS_NST_METHODS (class) = method
;
6138 /* When processing an @interface for a class or category, give hard
6139 errors on methods with identical selectors but differing argument
6140 and/or return types. We do not do this for @implementations, because
6141 C/C++ will do it for us (i.e., there will be duplicate function
6142 definition errors). */
6143 if ((TREE_CODE (class) == CLASS_INTERFACE_TYPE
6144 || TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
)
6145 && !comp_proto_with_proto (method
, mth
))
6146 error ("duplicate declaration of method `%c%s'",
6147 is_class
? '+' : '-',
6148 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
6152 add_method_to_hash_list (cls_method_hash_list
, method
);
6155 add_method_to_hash_list (nst_method_hash_list
, method
);
6157 /* Instance methods in root classes (and categories thereof)
6158 may acts as class methods as a last resort. */
6159 if (TREE_CODE (class) == CATEGORY_INTERFACE_TYPE
6160 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6161 class = lookup_interface (CLASS_NAME (class));
6163 if (TREE_CODE (class) != PROTOCOL_INTERFACE_TYPE
6164 && !CLASS_SUPER_NAME (class))
6165 add_method_to_hash_list (cls_method_hash_list
, method
);
6172 add_class (tree
class)
6174 /* Put interfaces on list in reverse order. */
6175 TREE_CHAIN (class) = interface_chain
;
6176 interface_chain
= class;
6177 return interface_chain
;
6181 add_category (tree
class, tree category
)
6183 /* Put categories on list in reverse order. */
6184 tree cat
= lookup_category (class, CLASS_SUPER_NAME (category
));
6188 warning ("duplicate interface declaration for category `%s(%s)'",
6189 IDENTIFIER_POINTER (CLASS_NAME (class)),
6190 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category
)));
6194 CLASS_CATEGORY_LIST (category
) = CLASS_CATEGORY_LIST (class);
6195 CLASS_CATEGORY_LIST (class) = category
;
6199 /* Called after parsing each instance variable declaration. Necessary to
6200 preserve typedefs and implement public/private...
6202 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
6205 add_instance_variable (tree
class, int public, tree field_decl
)
6207 tree field_type
= TREE_TYPE (field_decl
);
6208 const char *ivar_name
= DECL_NAME (field_decl
)
6209 ? IDENTIFIER_POINTER (DECL_NAME (field_decl
))
6213 if (TREE_CODE (field_type
) == REFERENCE_TYPE
)
6215 error ("illegal reference type specified for instance variable `%s'",
6217 /* Return class as is without adding this ivar. */
6222 if (field_type
== error_mark_node
|| !TYPE_SIZE (field_type
)
6223 || TYPE_SIZE (field_type
) == error_mark_node
)
6224 /* 'type[0]' is allowed, but 'type[]' is not! */
6226 error ("instance variable `%s' has unknown size", ivar_name
);
6227 /* Return class as is without adding this ivar. */
6232 /* zlaski 2001-Apr-24: C++ classes with non-trivial constructors and/or destructors
6233 cannot be ivars; ditto for classes with vtables. */
6234 if(IS_AGGR_TYPE (field_type
) && (TYPE_NEEDS_CONSTRUCTING (field_type
)
6235 || TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type
) || TYPE_POLYMORPHIC_P (field_type
)))
6237 const char *type_name
= IDENTIFIER_POINTER (OBJC_TYPE_NAME (field_type
));
6238 if(TYPE_POLYMORPHIC_P (field_type
)) {
6239 /* vtable pointers are Real Bad(tm), since Obj-C cannot initialize them */
6240 error ("type `%s' has virtual member functions", type_name
);
6241 error ("illegal aggregate type `%s' specified for instance variable `%s'",
6242 type_name
, ivar_name
);
6243 /* Return class as is without adding this ivar. */
6246 /* user-defined constructors and destructors are not known to Obj-C and
6247 hence will not be called. This may or may not be a problem. */
6248 if (TYPE_NEEDS_CONSTRUCTING (field_type
))
6249 warning ("type `%s' has a user-defined constructor", type_name
);
6250 if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (field_type
))
6251 warning ("type `%s' has a user-defined destructor", type_name
);
6252 warning ("C++ constructors and destructors will not be invoked for Objective-C fields");
6256 /* Overload the public attribute, it is not used for FIELD_DECLs. */
6260 TREE_PUBLIC (field_decl
) = 0;
6261 TREE_PRIVATE (field_decl
) = 0;
6262 TREE_PROTECTED (field_decl
) = 1;
6266 TREE_PUBLIC (field_decl
) = 1;
6267 TREE_PRIVATE (field_decl
) = 0;
6268 TREE_PROTECTED (field_decl
) = 0;
6272 TREE_PUBLIC (field_decl
) = 0;
6273 TREE_PRIVATE (field_decl
) = 1;
6274 TREE_PROTECTED (field_decl
) = 0;
6279 CLASS_RAW_IVARS (class) = chainon (CLASS_RAW_IVARS (class), field_decl
);
6285 is_ivar (tree decl_chain
, tree ident
)
6287 for ( ; decl_chain
; decl_chain
= TREE_CHAIN (decl_chain
))
6288 if (DECL_NAME (decl_chain
) == ident
)
6293 /* True if the ivar is private and we are not in its implementation. */
6296 is_private (tree decl
)
6298 return (TREE_PRIVATE (decl
)
6299 && ! is_ivar (CLASS_IVARS (implementation_template
),
6303 /* We have an instance variable reference;, check to see if it is public. */
6306 objc_is_public (tree expr
, tree identifier
)
6308 tree basetype
= TREE_TYPE (expr
);
6309 enum tree_code code
= TREE_CODE (basetype
);
6312 if (code
== RECORD_TYPE
)
6314 if (TREE_STATIC_TEMPLATE (basetype
))
6316 if (!lookup_interface (OBJC_TYPE_NAME (basetype
)))
6318 error ("cannot find interface declaration for `%s'",
6319 IDENTIFIER_POINTER (OBJC_TYPE_NAME (basetype
)));
6323 if ((decl
= is_ivar (TYPE_FIELDS (basetype
), identifier
)))
6325 if (TREE_PUBLIC (decl
))
6328 /* Important difference between the Stepstone translator:
6329 all instance variables should be public within the context
6330 of the implementation. */
6331 if (objc_implementation_context
6332 && (((TREE_CODE (objc_implementation_context
)
6333 == CLASS_IMPLEMENTATION_TYPE
)
6334 || (TREE_CODE (objc_implementation_context
)
6335 == CATEGORY_IMPLEMENTATION_TYPE
))
6336 && (CLASS_NAME (objc_implementation_context
)
6337 == OBJC_TYPE_NAME (basetype
))))
6339 int private = is_private (decl
);
6342 error ("instance variable `%s' is declared private",
6343 IDENTIFIER_POINTER (DECL_NAME (decl
)));
6347 /* The 2.95.2 compiler sometimes allowed C functions to access
6348 non-@public ivars. We will let this slide for now... */
6349 if (!objc_method_context
)
6351 warning ("instance variable `%s' is %s; "
6352 "this will be a hard error in the future",
6353 IDENTIFIER_POINTER (identifier
),
6354 TREE_PRIVATE (decl
) ? "@private" : "@protected");
6358 error ("instance variable `%s' is declared %s",
6359 IDENTIFIER_POINTER (identifier
),
6360 TREE_PRIVATE (decl
) ? "private" : "protected");
6365 else if (objc_implementation_context
&& (basetype
== objc_object_reference
))
6367 expr
= convert (uprivate_record
, expr
);
6368 warning ("static access to object of type `id'");
6375 /* Make sure all entries in CHAIN are also in LIST. */
6378 check_methods (tree chain
, tree list
, int mtype
)
6384 if (!lookup_method (list
, chain
))
6388 if (TREE_CODE (objc_implementation_context
)
6389 == CLASS_IMPLEMENTATION_TYPE
)
6390 warning ("incomplete implementation of class `%s'",
6391 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
)));
6392 else if (TREE_CODE (objc_implementation_context
)
6393 == CATEGORY_IMPLEMENTATION_TYPE
)
6394 warning ("incomplete implementation of category `%s'",
6395 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
6399 warning ("method definition for `%c%s' not found",
6400 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
6403 chain
= TREE_CHAIN (chain
);
6409 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
6412 conforms_to_protocol (tree
class, tree protocol
)
6414 if (TREE_CODE (protocol
) == PROTOCOL_INTERFACE_TYPE
)
6416 tree p
= CLASS_PROTOCOL_LIST (class);
6417 while (p
&& TREE_VALUE (p
) != protocol
)
6422 tree super
= (CLASS_SUPER_NAME (class)
6423 ? lookup_interface (CLASS_SUPER_NAME (class))
6425 int tmp
= super
? conforms_to_protocol (super
, protocol
) : 0;
6434 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
6435 CONTEXT. This is one of two mechanisms to check protocol integrity. */
6438 check_methods_accessible (tree chain
, tree context
, int mtype
)
6442 tree base_context
= context
;
6446 context
= base_context
;
6450 list
= CLASS_CLS_METHODS (context
);
6452 list
= CLASS_NST_METHODS (context
);
6454 if (lookup_method (list
, chain
))
6457 else if (TREE_CODE (context
) == CLASS_IMPLEMENTATION_TYPE
6458 || TREE_CODE (context
) == CLASS_INTERFACE_TYPE
)
6459 context
= (CLASS_SUPER_NAME (context
)
6460 ? lookup_interface (CLASS_SUPER_NAME (context
))
6463 else if (TREE_CODE (context
) == CATEGORY_IMPLEMENTATION_TYPE
6464 || TREE_CODE (context
) == CATEGORY_INTERFACE_TYPE
)
6465 context
= (CLASS_NAME (context
)
6466 ? lookup_interface (CLASS_NAME (context
))
6472 if (context
== NULL_TREE
)
6476 if (TREE_CODE (objc_implementation_context
)
6477 == CLASS_IMPLEMENTATION_TYPE
)
6478 warning ("incomplete implementation of class `%s'",
6480 (CLASS_NAME (objc_implementation_context
)));
6481 else if (TREE_CODE (objc_implementation_context
)
6482 == CATEGORY_IMPLEMENTATION_TYPE
)
6483 warning ("incomplete implementation of category `%s'",
6485 (CLASS_SUPER_NAME (objc_implementation_context
)));
6488 warning ("method definition for `%c%s' not found",
6489 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
6492 chain
= TREE_CHAIN (chain
); /* next method... */
6497 /* Check whether the current interface (accessible via
6498 'objc_implementation_context') actually implements protocol P, along
6499 with any protocols that P inherits. */
6502 check_protocol (tree p
, const char *type
, const char *name
)
6504 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
6508 /* Ensure that all protocols have bodies! */
6511 f1
= check_methods (PROTOCOL_CLS_METHODS (p
),
6512 CLASS_CLS_METHODS (objc_implementation_context
),
6514 f2
= check_methods (PROTOCOL_NST_METHODS (p
),
6515 CLASS_NST_METHODS (objc_implementation_context
),
6520 f1
= check_methods_accessible (PROTOCOL_CLS_METHODS (p
),
6521 objc_implementation_context
,
6523 f2
= check_methods_accessible (PROTOCOL_NST_METHODS (p
),
6524 objc_implementation_context
,
6529 warning ("%s `%s' does not fully implement the `%s' protocol",
6530 type
, name
, IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
6533 /* Check protocols recursively. */
6534 if (PROTOCOL_LIST (p
))
6536 tree subs
= PROTOCOL_LIST (p
);
6538 lookup_interface (CLASS_SUPER_NAME (implementation_template
));
6542 tree sub
= TREE_VALUE (subs
);
6544 /* If the superclass does not conform to the protocols
6545 inherited by P, then we must! */
6546 if (!super_class
|| !conforms_to_protocol (super_class
, sub
))
6547 check_protocol (sub
, type
, name
);
6548 subs
= TREE_CHAIN (subs
);
6553 /* Check whether the current interface (accessible via
6554 'objc_implementation_context') actually implements the protocols listed
6558 check_protocols (tree proto_list
, const char *type
, const char *name
)
6560 for ( ; proto_list
; proto_list
= TREE_CHAIN (proto_list
))
6562 tree p
= TREE_VALUE (proto_list
);
6564 check_protocol (p
, type
, name
);
6568 /* Make sure that the class CLASS_NAME is defined
6569 CODE says which kind of thing CLASS_NAME ought to be.
6570 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6571 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6574 start_class (enum tree_code code
, tree class_name
, tree super_name
,
6580 if (current_namespace
!= global_namespace
) {
6581 error ("Objective-C declarations may only appear in global scope");
6583 #endif /* OBJCPLUS */
6585 if (objc_implementation_context
)
6587 warning ("`@end' missing in implementation context");
6588 finish_class (objc_implementation_context
);
6589 objc_ivar_chain
= NULL_TREE
;
6590 objc_implementation_context
= NULL_TREE
;
6593 class = make_node (code
);
6594 TYPE_LANG_SLOT_1 (class) = make_tree_vec (CLASS_LANG_SLOT_ELTS
);
6596 /* Check for existence of the super class, if one was specified. */
6597 if ((code
== CLASS_INTERFACE_TYPE
|| code
== CLASS_IMPLEMENTATION_TYPE
)
6598 && super_name
&& !objc_is_class_name (super_name
))
6600 error ("cannot find interface declaration for `%s', superclass of `%s'",
6601 IDENTIFIER_POINTER (super_name
),
6602 IDENTIFIER_POINTER (class_name
));
6603 super_name
= NULL_TREE
;
6606 CLASS_NAME (class) = class_name
;
6607 CLASS_SUPER_NAME (class) = super_name
;
6608 CLASS_CLS_METHODS (class) = NULL_TREE
;
6610 if (! objc_is_class_name (class_name
)
6611 && (decl
= lookup_name (class_name
)))
6613 error ("`%s' redeclared as different kind of symbol",
6614 IDENTIFIER_POINTER (class_name
));
6615 error ("%Jprevious declaration of '%D'",
6619 if (code
== CLASS_IMPLEMENTATION_TYPE
)
6624 for (chain
= implemented_classes
; chain
; chain
= TREE_CHAIN (chain
))
6625 if (TREE_VALUE (chain
) == class_name
)
6627 error ("reimplementation of class `%s'",
6628 IDENTIFIER_POINTER (class_name
));
6629 return error_mark_node
;
6631 implemented_classes
= tree_cons (NULL_TREE
, class_name
,
6632 implemented_classes
);
6635 /* Reset for multiple classes per file. */
6638 objc_implementation_context
= class;
6640 /* Lookup the interface for this implementation. */
6642 if (!(implementation_template
= lookup_interface (class_name
)))
6644 warning ("cannot find interface declaration for `%s'",
6645 IDENTIFIER_POINTER (class_name
));
6646 add_class (implementation_template
= objc_implementation_context
);
6649 /* If a super class has been specified in the implementation,
6650 insure it conforms to the one specified in the interface. */
6653 && (super_name
!= CLASS_SUPER_NAME (implementation_template
)))
6655 tree previous_name
= CLASS_SUPER_NAME (implementation_template
);
6656 const char *const name
=
6657 previous_name
? IDENTIFIER_POINTER (previous_name
) : "";
6658 error ("conflicting super class name `%s'",
6659 IDENTIFIER_POINTER (super_name
));
6660 error ("previous declaration of `%s'", name
);
6663 else if (! super_name
)
6665 CLASS_SUPER_NAME (objc_implementation_context
)
6666 = CLASS_SUPER_NAME (implementation_template
);
6670 else if (code
== CLASS_INTERFACE_TYPE
)
6672 if (lookup_interface (class_name
))
6674 error ("duplicate interface declaration for class `%s'",
6676 warning ("duplicate interface declaration for class `%s'",
6678 IDENTIFIER_POINTER (class_name
));
6683 CLASS_PROTOCOL_LIST (class)
6684 = lookup_and_install_protocols (protocol_list
);
6687 else if (code
== CATEGORY_INTERFACE_TYPE
)
6689 tree class_category_is_assoc_with
;
6691 /* For a category, class_name is really the name of the class that
6692 the following set of methods will be associated with. We must
6693 find the interface so that can derive the objects template. */
6695 if (!(class_category_is_assoc_with
= lookup_interface (class_name
)))
6697 error ("cannot find interface declaration for `%s'",
6698 IDENTIFIER_POINTER (class_name
));
6699 exit (FATAL_EXIT_CODE
);
6702 add_category (class_category_is_assoc_with
, class);
6705 CLASS_PROTOCOL_LIST (class)
6706 = lookup_and_install_protocols (protocol_list
);
6709 else if (code
== CATEGORY_IMPLEMENTATION_TYPE
)
6711 /* Reset for multiple classes per file. */
6714 objc_implementation_context
= class;
6716 /* For a category, class_name is really the name of the class that
6717 the following set of methods will be associated with. We must
6718 find the interface so that can derive the objects template. */
6720 if (!(implementation_template
= lookup_interface (class_name
)))
6722 error ("cannot find interface declaration for `%s'",
6723 IDENTIFIER_POINTER (class_name
));
6724 exit (FATAL_EXIT_CODE
);
6731 continue_class (tree
class)
6733 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6734 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6736 struct imp_entry
*imp_entry
;
6739 /* Check consistency of the instance variables. */
6741 if (CLASS_RAW_IVARS (class))
6742 check_ivars (implementation_template
, class);
6744 /* code generation */
6747 push_lang_context (lang_name_c
);
6750 ivar_context
= build_private_template (implementation_template
);
6752 imp_entry
= (struct imp_entry
*) ggc_alloc (sizeof (struct imp_entry
));
6754 imp_entry
->next
= imp_list
;
6755 imp_entry
->imp_context
= class;
6756 imp_entry
->imp_template
= implementation_template
;
6758 synth_forward_declarations ();
6759 imp_entry
->class_decl
= UOBJC_CLASS_decl
;
6760 imp_entry
->meta_decl
= UOBJC_METACLASS_decl
;
6762 /* Append to front and increment count. */
6763 imp_list
= imp_entry
;
6764 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6770 pop_lang_context ();
6771 #endif /* OBJCPLUS */
6773 return ivar_context
;
6776 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6779 push_lang_context (lang_name_c
);
6780 #endif /* OBJCPLUS */
6782 if (!CLASS_STATIC_TEMPLATE (class))
6784 tree record
= start_struct (RECORD_TYPE
, CLASS_NAME (class));
6785 finish_struct (record
, get_class_ivars (class), NULL_TREE
);
6786 CLASS_STATIC_TEMPLATE (class) = record
;
6788 /* Mark this record as a class template for static typing. */
6789 TREE_STATIC_TEMPLATE (record
) = 1;
6793 pop_lang_context ();
6794 #endif /* OBJCPLUS */
6800 return error_mark_node
;
6803 /* This is called once we see the "@end" in an interface/implementation. */
6806 finish_class (tree
class)
6808 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6810 /* All code generation is done in finish_objc. */
6812 if (implementation_template
!= objc_implementation_context
)
6814 /* Ensure that all method listed in the interface contain bodies. */
6815 check_methods (CLASS_CLS_METHODS (implementation_template
),
6816 CLASS_CLS_METHODS (objc_implementation_context
), '+');
6817 check_methods (CLASS_NST_METHODS (implementation_template
),
6818 CLASS_NST_METHODS (objc_implementation_context
), '-');
6820 if (CLASS_PROTOCOL_LIST (implementation_template
))
6821 check_protocols (CLASS_PROTOCOL_LIST (implementation_template
),
6823 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
)));
6827 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6829 tree category
= lookup_category (implementation_template
, CLASS_SUPER_NAME (class));
6833 /* Ensure all method listed in the interface contain bodies. */
6834 check_methods (CLASS_CLS_METHODS (category
),
6835 CLASS_CLS_METHODS (objc_implementation_context
), '+');
6836 check_methods (CLASS_NST_METHODS (category
),
6837 CLASS_NST_METHODS (objc_implementation_context
), '-');
6839 if (CLASS_PROTOCOL_LIST (category
))
6840 check_protocols (CLASS_PROTOCOL_LIST (category
),
6842 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
6846 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6849 const char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (class));
6850 char *string
= (char *) alloca (strlen (class_name
) + 3);
6852 /* extern struct objc_object *_<my_name>; */
6854 sprintf (string
, "_%s", class_name
);
6856 decl
= build_decl (VAR_DECL
, get_identifier (string
),
6857 build_pointer_type (objc_object_reference
));
6858 DECL_EXTERNAL (decl
) = 1;
6859 lang_hooks
.decls
.pushdecl (decl
);
6860 finish_decl (decl
, NULL_TREE
, NULL_TREE
);
6865 add_protocol (tree protocol
)
6867 /* Put protocol on list in reverse order. */
6868 TREE_CHAIN (protocol
) = protocol_chain
;
6869 protocol_chain
= protocol
;
6870 return protocol_chain
;
6874 lookup_protocol (tree ident
)
6878 for (chain
= protocol_chain
; chain
; chain
= TREE_CHAIN (chain
))
6879 if (ident
== PROTOCOL_NAME (chain
))
6885 /* This function forward declares the protocols named by NAMES. If
6886 they are already declared or defined, the function has no effect. */
6889 objc_declare_protocols (tree names
)
6894 if (current_namespace
!= global_namespace
) {
6895 error ("Objective-C declarations may only appear in global scope");
6897 #endif /* OBJCPLUS */
6899 for (list
= names
; list
; list
= TREE_CHAIN (list
))
6901 tree name
= TREE_VALUE (list
);
6903 if (lookup_protocol (name
) == NULL_TREE
)
6905 tree protocol
= make_node (PROTOCOL_INTERFACE_TYPE
);
6907 TYPE_LANG_SLOT_1 (protocol
)
6908 = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS
);
6909 PROTOCOL_NAME (protocol
) = name
;
6910 PROTOCOL_LIST (protocol
) = NULL_TREE
;
6911 add_protocol (protocol
);
6912 PROTOCOL_DEFINED (protocol
) = 0;
6913 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6919 start_protocol (enum tree_code code
, tree name
, tree list
)
6924 if (current_namespace
!= global_namespace
) {
6925 error ("Objective-C declarations may only appear in global scope");
6927 #endif /* OBJCPLUS */
6929 protocol
= lookup_protocol (name
);
6933 protocol
= make_node (code
);
6934 TYPE_LANG_SLOT_1 (protocol
) = make_tree_vec (PROTOCOL_LANG_SLOT_ELTS
);
6936 PROTOCOL_NAME (protocol
) = name
;
6937 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
6938 add_protocol (protocol
);
6939 PROTOCOL_DEFINED (protocol
) = 1;
6940 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6942 check_protocol_recursively (protocol
, list
);
6944 else if (! PROTOCOL_DEFINED (protocol
))
6946 PROTOCOL_DEFINED (protocol
) = 1;
6947 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
6949 check_protocol_recursively (protocol
, list
);
6953 warning ("duplicate declaration for protocol `%s'",
6954 IDENTIFIER_POINTER (name
));
6960 /* "Encode" a data type into a string, which grows in util_obstack.
6961 ??? What is the FORMAT? Someone please document this! */
6964 encode_type_qualifiers (tree declspecs
)
6968 for (spec
= declspecs
; spec
; spec
= TREE_CHAIN (spec
))
6970 if (ridpointers
[(int) RID_IN
] == TREE_VALUE (spec
))
6971 obstack_1grow (&util_obstack
, 'n');
6972 else if (ridpointers
[(int) RID_INOUT
] == TREE_VALUE (spec
))
6973 obstack_1grow (&util_obstack
, 'N');
6974 else if (ridpointers
[(int) RID_OUT
] == TREE_VALUE (spec
))
6975 obstack_1grow (&util_obstack
, 'o');
6976 else if (ridpointers
[(int) RID_BYCOPY
] == TREE_VALUE (spec
))
6977 obstack_1grow (&util_obstack
, 'O');
6978 else if (ridpointers
[(int) RID_BYREF
] == TREE_VALUE (spec
))
6979 obstack_1grow (&util_obstack
, 'R');
6980 else if (ridpointers
[(int) RID_ONEWAY
] == TREE_VALUE (spec
))
6981 obstack_1grow (&util_obstack
, 'V');
6985 /* Encode a pointer type. */
6988 encode_pointer (tree type
, int curtype
, int format
)
6990 tree pointer_to
= TREE_TYPE (type
);
6992 if (TREE_CODE (pointer_to
) == RECORD_TYPE
)
6994 if (OBJC_TYPE_NAME (pointer_to
)
6995 && TREE_CODE (OBJC_TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
)
6997 const char *name
= IDENTIFIER_POINTER (OBJC_TYPE_NAME (pointer_to
));
6999 if (strcmp (name
, TAG_OBJECT
) == 0) /* '@' */
7001 obstack_1grow (&util_obstack
, '@');
7004 else if (TREE_STATIC_TEMPLATE (pointer_to
))
7006 if (generating_instance_variables
)
7008 obstack_1grow (&util_obstack
, '@');
7009 obstack_1grow (&util_obstack
, '"');
7010 obstack_grow (&util_obstack
, name
, strlen (name
));
7011 obstack_1grow (&util_obstack
, '"');
7016 obstack_1grow (&util_obstack
, '@');
7020 else if (strcmp (name
, TAG_CLASS
) == 0) /* '#' */
7022 obstack_1grow (&util_obstack
, '#');
7025 else if (strcmp (name
, TAG_SELECTOR
) == 0) /* ':' */
7027 obstack_1grow (&util_obstack
, ':');
7032 else if (TREE_CODE (pointer_to
) == INTEGER_TYPE
7033 && TYPE_MODE (pointer_to
) == QImode
)
7035 tree pname
= TREE_CODE (OBJC_TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
7036 ? OBJC_TYPE_NAME (pointer_to
)
7037 : DECL_NAME (OBJC_TYPE_NAME (pointer_to
));
7039 if (!flag_next_runtime
|| strcmp (IDENTIFIER_POINTER (pname
), "BOOL"))
7041 /* It appears that "r*" means "const char *" rather than
7043 if (TYPE_READONLY (pointer_to
))
7044 obstack_1grow (&util_obstack
, 'r');
7046 obstack_1grow (&util_obstack
, '*');
7051 /* We have a type that does not get special treatment. */
7053 /* NeXT extension */
7054 obstack_1grow (&util_obstack
, '^');
7055 encode_type (pointer_to
, curtype
, format
);
7059 encode_array (tree type
, int curtype
, int format
)
7061 tree an_int_cst
= TYPE_SIZE (type
);
7062 tree array_of
= TREE_TYPE (type
);
7065 /* An incomplete array is treated like a pointer. */
7066 if (an_int_cst
== NULL
)
7068 encode_pointer (type
, curtype
, format
);
7072 sprintf (buffer
, "[" HOST_WIDE_INT_PRINT_DEC
,
7073 (TREE_INT_CST_LOW (an_int_cst
)
7074 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
7076 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7077 encode_type (array_of
, curtype
, format
);
7078 obstack_1grow (&util_obstack
, ']');
7083 encode_aggregate_within (tree type
, int curtype
, int format
, int left
,
7087 /* NB: aggregates that are pointed to have slightly different encoding
7088 rules in that you never encode the names of instance variables. */
7090 = (obstack_object_size (&util_obstack
) > 0
7091 && *(obstack_next_free (&util_obstack
) - 1) == '^');
7093 = ((format
== OBJC_ENCODE_INLINE_DEFS
|| generating_instance_variables
)
7094 && (!pointed_to
|| obstack_object_size (&util_obstack
) - curtype
== 1));
7096 /* Traverse struct aliases; it is important to get the
7097 original struct and its tag name (if any). */
7098 type
= TYPE_MAIN_VARIANT (type
);
7099 name
= OBJC_TYPE_NAME (type
);
7100 /* Open parenth/bracket. */
7101 obstack_1grow (&util_obstack
, left
);
7103 /* Encode the struct/union tag name, or '?' if a tag was
7104 not provided. Typedef aliases do not qualify. */
7105 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
7107 /* Did this struct have a tag? */
7108 && !TYPE_WAS_ANONYMOUS (type
)
7111 obstack_grow (&util_obstack
,
7112 IDENTIFIER_POINTER (name
),
7113 strlen (IDENTIFIER_POINTER (name
)));
7115 obstack_1grow (&util_obstack
, '?');
7117 /* Encode the types (and possibly names) of the inner fields,
7119 if (inline_contents
)
7121 tree fields
= TYPE_FIELDS (type
);
7123 obstack_1grow (&util_obstack
, '=');
7124 for (; fields
; fields
= TREE_CHAIN (fields
))
7127 /* C++ static members, and things that are not fields at all,
7128 should not appear in the encoding. */
7129 if (TREE_CODE (fields
) != FIELD_DECL
|| TREE_STATIC (fields
))
7132 if (generating_instance_variables
&& !pointed_to
)
7134 tree fname
= DECL_NAME (fields
);
7136 obstack_1grow (&util_obstack
, '"');
7137 if (fname
&& TREE_CODE (fname
) == IDENTIFIER_NODE
)
7138 obstack_grow (&util_obstack
,
7139 IDENTIFIER_POINTER (fname
),
7140 strlen (IDENTIFIER_POINTER (fname
)));
7141 obstack_1grow (&util_obstack
, '"');
7143 encode_field_decl (fields
, curtype
, format
);
7146 /* Close parenth/bracket. */
7147 obstack_1grow (&util_obstack
, right
);
7151 encode_aggregate (tree type
, int curtype
, int format
)
7153 enum tree_code code
= TREE_CODE (type
);
7159 encode_aggregate_within (type
, curtype
, format
, '{', '}');
7164 encode_aggregate_within (type
, curtype
, format
, '(', ')');
7169 obstack_1grow (&util_obstack
, 'i');
7177 /* Encode a bitfield NeXT-style (i.e., without a bit offset or the underlying
7181 encode_next_bitfield (int width
)
7184 sprintf (buffer
, "b%d", width
);
7185 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7188 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
7190 encode_type (tree type
, int curtype
, int format
)
7192 enum tree_code code
= TREE_CODE (type
);
7195 if (TYPE_READONLY (type
))
7196 obstack_1grow (&util_obstack
, 'r');
7198 if (code
== INTEGER_TYPE
)
7200 switch (GET_MODE_BITSIZE (TYPE_MODE (type
)))
7202 case 8: c
= TYPE_UNSIGNED (type
) ? 'C' : 'c'; break;
7203 case 16: c
= TYPE_UNSIGNED (type
) ? 'S' : 's'; break;
7205 if (type
== long_unsigned_type_node
7206 || type
== long_integer_type_node
)
7207 c
= TYPE_UNSIGNED (type
) ? 'L' : 'l';
7209 c
= TYPE_UNSIGNED (type
) ? 'I' : 'i';
7211 case 64: c
= TYPE_UNSIGNED (type
) ? 'Q' : 'q'; break;
7214 obstack_1grow (&util_obstack
, c
);
7217 else if (code
== REAL_TYPE
)
7219 /* Floating point types. */
7220 switch (GET_MODE_BITSIZE (TYPE_MODE (type
)))
7222 case 32: c
= 'f'; break;
7224 case 128: c
= 'd'; break;
7227 obstack_1grow (&util_obstack
, c
);
7230 else if (code
== VOID_TYPE
)
7231 obstack_1grow (&util_obstack
, 'v');
7233 else if (code
== BOOLEAN_TYPE
)
7234 obstack_1grow (&util_obstack
, 'B');
7236 else if (code
== ARRAY_TYPE
)
7237 encode_array (type
, curtype
, format
);
7239 else if (code
== POINTER_TYPE
)
7240 encode_pointer (type
, curtype
, format
);
7242 else if (code
== RECORD_TYPE
|| code
== UNION_TYPE
|| code
== ENUMERAL_TYPE
)
7243 encode_aggregate (type
, curtype
, format
);
7245 else if (code
== FUNCTION_TYPE
) /* '?' */
7246 obstack_1grow (&util_obstack
, '?');
7250 encode_gnu_bitfield (int position
, tree type
, int size
)
7252 enum tree_code code
= TREE_CODE (type
);
7254 char charType
= '?';
7256 if (code
== INTEGER_TYPE
)
7258 if (integer_zerop (TYPE_MIN_VALUE (type
)))
7260 /* Unsigned integer types. */
7262 if (TYPE_MODE (type
) == QImode
)
7264 else if (TYPE_MODE (type
) == HImode
)
7266 else if (TYPE_MODE (type
) == SImode
)
7268 if (type
== long_unsigned_type_node
)
7273 else if (TYPE_MODE (type
) == DImode
)
7278 /* Signed integer types. */
7280 if (TYPE_MODE (type
) == QImode
)
7282 else if (TYPE_MODE (type
) == HImode
)
7284 else if (TYPE_MODE (type
) == SImode
)
7286 if (type
== long_integer_type_node
)
7292 else if (TYPE_MODE (type
) == DImode
)
7296 else if (code
== ENUMERAL_TYPE
)
7301 sprintf (buffer
, "b%d%c%d", position
, charType
, size
);
7302 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7306 encode_field_decl (tree field_decl
, int curtype
, int format
)
7311 /* C++ static members, and things that are not fields at all,
7312 should not appear in the encoding. */
7313 if (TREE_CODE (field_decl
) != FIELD_DECL
|| TREE_STATIC (field_decl
))
7317 type
= TREE_TYPE (field_decl
);
7319 /* Generate the bitfield typing information, if needed. Note the difference
7320 between GNU and NeXT runtimes. */
7321 if (DECL_BIT_FIELD_TYPE (field_decl
))
7323 int size
= tree_low_cst (DECL_SIZE (field_decl
), 1);
7325 if (flag_next_runtime
)
7326 encode_next_bitfield (size
);
7328 encode_gnu_bitfield (int_bit_position (field_decl
),
7329 DECL_BIT_FIELD_TYPE (field_decl
), size
);
7332 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
7335 static GTY(()) tree objc_parmlist
= NULL_TREE
;
7337 /* Append PARM to a list of formal parameters of a method, making a necessary
7338 array-to-pointer adjustment along the way. */
7341 objc_push_parm (tree parm
)
7343 /* Convert array parameters of unknown size into pointers. */
7344 if (TREE_CODE (TREE_TYPE (parm
)) == ARRAY_TYPE
7345 && !TYPE_SIZE (TREE_TYPE (parm
)))
7346 TREE_TYPE (parm
) = build_pointer_type (TREE_TYPE (TREE_TYPE (parm
)));
7348 objc_parmlist
= chainon (objc_parmlist
, parm
);
7351 /* Retrieve the formal paramter list constructed via preceding calls to
7352 objc_push_parm(). */
7356 objc_get_parm_info (int have_ellipsis ATTRIBUTE_UNUSED
)
7358 static struct c_arg_info
*
7359 objc_get_parm_info (int have_ellipsis
)
7363 tree parm_info
= objc_parmlist
;
7364 objc_parmlist
= NULL_TREE
;
7368 tree parm_info
= objc_parmlist
;
7369 struct c_arg_info
*arg_info
;
7370 /* The C front-end requires an elaborate song and dance at
7373 declare_parm_level ();
7376 tree next
= TREE_CHAIN (parm_info
);
7378 TREE_CHAIN (parm_info
) = NULL_TREE
;
7379 pushdecl (parm_info
);
7382 arg_info
= get_parm_info (have_ellipsis
);
7384 objc_parmlist
= NULL_TREE
;
7389 /* Synthesize the formal parameters 'id self' and 'SEL _cmd' needed for ObjC
7390 method definitions. In the case of instance methods, we can be more
7391 specific as to the type of 'self'. */
7394 synth_self_and_ucmd_args (void)
7398 if (objc_method_context
7399 && TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
)
7400 self_type
= objc_instance_type
;
7402 /* Really a `struct objc_class *'. However, we allow people to
7403 assign to self, which changes its type midstream. */
7404 self_type
= objc_object_type
;
7407 objc_push_parm (build_decl (PARM_DECL
, self_id
, self_type
));
7410 objc_push_parm (build_decl (PARM_DECL
, ucmd_id
, objc_selector_type
));
7413 /* Transform an Objective-C method definition into a static C function
7414 definition, synthesizing the first two arguments, "self" and "_cmd",
7418 start_method_def (tree method
)
7424 struct c_arg_info
*parm_info
;
7426 int have_ellipsis
= 0;
7428 /* Required to implement _msgSuper. */
7429 objc_method_context
= method
;
7430 UOBJC_SUPER_decl
= NULL_TREE
;
7432 /* Generate prototype declarations for arguments..."new-style". */
7433 synth_self_and_ucmd_args ();
7435 /* Generate argument declarations if a keyword_decl. */
7436 parmlist
= METHOD_SEL_ARGS (method
);
7439 tree parm
= build_decl (PARM_DECL
, KEYWORD_ARG_NAME (parmlist
),
7440 TREE_VALUE (TREE_TYPE (parmlist
)));
7442 objc_push_parm (parm
);
7443 parmlist
= TREE_CHAIN (parmlist
);
7446 if (METHOD_ADD_ARGS (method
))
7450 for (akey
= TREE_CHAIN (METHOD_ADD_ARGS (method
));
7451 akey
; akey
= TREE_CHAIN (akey
))
7453 objc_push_parm (TREE_VALUE (akey
));
7456 if (TREE_OVERFLOW (METHOD_ADD_ARGS (method
)))
7460 parm_info
= objc_get_parm_info (have_ellipsis
);
7462 really_start_method (objc_method_context
, parm_info
);
7466 warn_with_method (const char *message
, int mtype
, tree method
)
7468 /* Add a readable method name to the warning. */
7469 warning ("%J%s `%c%s'", method
,
7470 message
, mtype
, gen_method_decl (method
));
7473 /* Return 1 if TYPE1 is equivalent to TYPE2
7474 for purposes of method overloading. */
7477 objc_types_are_equivalent (tree type1
, tree type2
)
7482 /* Strip away indirections. */
7483 while ((TREE_CODE (type1
) == ARRAY_TYPE
|| TREE_CODE (type1
) == POINTER_TYPE
)
7484 && (TREE_CODE (type1
) == TREE_CODE (type2
)))
7485 type1
= TREE_TYPE (type1
), type2
= TREE_TYPE (type2
);
7486 if (TYPE_MAIN_VARIANT (type1
) != TYPE_MAIN_VARIANT (type2
))
7489 type1
= TYPE_PROTOCOL_LIST (type1
);
7490 type2
= TYPE_PROTOCOL_LIST (type2
);
7491 if (list_length (type1
) == list_length (type2
))
7493 for (; type2
; type2
= TREE_CHAIN (type2
))
7494 if (!lookup_protocol_in_reflist (type1
, TREE_VALUE (type2
)))
7501 /* Return 1 if PROTO1 is equivalent to PROTO2
7502 for purposes of method overloading. */
7505 comp_proto_with_proto (tree proto1
, tree proto2
)
7509 /* The following test is needed in case there are hashing
7511 if (METHOD_SEL_NAME (proto1
) != METHOD_SEL_NAME (proto2
))
7514 /* Compare return types. */
7515 type1
= TREE_VALUE (TREE_TYPE (proto1
));
7516 type2
= TREE_VALUE (TREE_TYPE (proto2
));
7518 if (!objc_types_are_equivalent (type1
, type2
))
7521 /* Compare argument types. */
7522 for (type1
= get_arg_type_list (proto1
, METHOD_REF
, 0),
7523 type2
= get_arg_type_list (proto2
, METHOD_REF
, 0);
7525 type1
= TREE_CHAIN (type1
), type2
= TREE_CHAIN (type2
))
7527 if (!objc_types_are_equivalent (TREE_VALUE (type1
), TREE_VALUE (type2
)))
7531 return (!type1
&& !type2
);
7534 /* Fold an OBJ_TYPE_REF expression for ObjC method dispatches, where
7535 this occurs. ObjC method dispatches are _not_ like C++ virtual
7536 member function dispatches, and we account for the difference here. */
7539 objc_fold_obj_type_ref (tree ref
, tree known_type
)
7541 objc_fold_obj_type_ref (tree ref ATTRIBUTE_UNUSED
,
7542 tree known_type ATTRIBUTE_UNUSED
)
7546 tree v
= BINFO_VIRTUALS (TYPE_BINFO (known_type
));
7548 /* If the receiver does not have virtual member functions, there
7549 is nothing we can (or need to) do here. */
7553 /* Let C++ handle C++ virtual functions. */
7554 return cp_fold_obj_type_ref (ref
, known_type
);
7556 /* For plain ObjC, we currently do not need to do anything. */
7562 objc_start_function (tree name
, tree type
, tree attrs
,
7566 struct c_arg_info
*params
7570 tree fndecl
= build_decl (FUNCTION_DECL
, name
, type
);
7573 DECL_ARGUMENTS (fndecl
) = params
;
7575 DECL_INITIAL (fndecl
) = error_mark_node
;
7576 DECL_EXTERNAL (fndecl
) = 0;
7577 TREE_STATIC (fndecl
) = 1;
7580 retrofit_lang_decl (fndecl
);
7581 cplus_decl_attributes (&fndecl
, attrs
, 0);
7582 start_preparsed_function (fndecl
, attrs
, /*flags=*/SF_DEFAULT
);
7584 decl_attributes (&fndecl
, attrs
, 0);
7585 announce_function (fndecl
);
7586 current_function_decl
= pushdecl (fndecl
);
7588 declare_parm_level ();
7589 DECL_RESULT (current_function_decl
)
7590 = build_decl (RESULT_DECL
, NULL_TREE
,
7591 TREE_TYPE (TREE_TYPE (current_function_decl
)));
7592 start_fname_decls ();
7593 store_parm_decls_from (params
);
7596 TREE_USED (current_function_decl
) = 1;
7599 /* - Generate an identifier for the function. the format is "_n_cls",
7600 where 1 <= n <= nMethods, and cls is the name the implementation we
7602 - Install the return type from the method declaration.
7603 - If we have a prototype, check for type consistency. */
7606 really_start_method (tree method
,
7610 struct c_arg_info
*parmlist
7614 tree ret_type
, meth_type
;
7616 const char *sel_name
, *class_name
, *cat_name
;
7619 /* Synth the storage class & assemble the return type. */
7620 ret_type
= TREE_VALUE (TREE_TYPE (method
));
7622 sel_name
= IDENTIFIER_POINTER (METHOD_SEL_NAME (method
));
7623 class_name
= IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
7624 cat_name
= ((TREE_CODE (objc_implementation_context
)
7625 == CLASS_IMPLEMENTATION_TYPE
)
7627 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
7630 /* Make sure this is big enough for any plausible method label. */
7631 buf
= (char *) alloca (50 + strlen (sel_name
) + strlen (class_name
)
7632 + (cat_name
? strlen (cat_name
) : 0));
7634 OBJC_GEN_METHOD_LABEL (buf
, TREE_CODE (method
) == INSTANCE_METHOD_DECL
,
7635 class_name
, cat_name
, sel_name
, method_slot
);
7637 method_id
= get_identifier (buf
);
7640 /* Objective-C methods cannot be overloaded, so we don't need
7641 the type encoding appended. It looks bad anyway... */
7642 push_lang_context (lang_name_c
);
7646 = build_function_type (ret_type
,
7647 get_arg_type_list (method
, METHOD_DEF
, 0));
7648 objc_start_function (method_id
, meth_type
, NULL_TREE
, parmlist
);
7650 /* Set self_decl from the first argument. */
7651 self_decl
= DECL_ARGUMENTS (current_function_decl
);
7653 /* Suppress unused warnings. */
7654 TREE_USED (self_decl
) = 1;
7655 TREE_USED (TREE_CHAIN (self_decl
)) = 1;
7657 pop_lang_context ();
7660 METHOD_DEFINITION (method
) = current_function_decl
;
7662 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7664 if (implementation_template
!= objc_implementation_context
)
7667 = lookup_method_static (implementation_template
,
7668 METHOD_SEL_NAME (method
),
7669 TREE_CODE (method
) == CLASS_METHOD_DECL
);
7673 if (!comp_proto_with_proto (method
, proto
))
7675 char type
= (TREE_CODE (method
) == INSTANCE_METHOD_DECL
? '-' : '+');
7677 warn_with_method ("conflicting types for", type
, method
);
7678 warn_with_method ("previous declaration of", type
, proto
);
7683 /* We have a method @implementation even though we did not
7684 see a corresponding @interface declaration (which is allowed
7685 by Objective-C rules). Go ahead and place the method in
7686 the @interface anyway, so that message dispatch lookups
7688 tree interface
= implementation_template
;
7690 if (TREE_CODE (objc_implementation_context
)
7691 == CATEGORY_IMPLEMENTATION_TYPE
)
7692 interface
= lookup_category
7694 CLASS_SUPER_NAME (objc_implementation_context
));
7697 objc_add_method (interface
, copy_node (method
),
7698 TREE_CODE (method
) == CLASS_METHOD_DECL
);
7703 static void *UOBJC_SUPER_scope
= 0;
7705 /* _n_Method (id self, SEL sel, ...)
7707 struct objc_super _S;
7708 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7712 get_super_receiver (void)
7714 if (objc_method_context
)
7716 tree super_expr
, super_expr_list
;
7718 if (!UOBJC_SUPER_decl
)
7720 UOBJC_SUPER_decl
= build_decl (VAR_DECL
, get_identifier (TAG_SUPER
),
7721 objc_super_template
);
7722 /* This prevents `unused variable' warnings when compiling with -Wall. */
7723 TREE_USED (UOBJC_SUPER_decl
) = 1;
7724 lang_hooks
.decls
.pushdecl (UOBJC_SUPER_decl
);
7725 finish_decl (UOBJC_SUPER_decl
, NULL_TREE
, NULL_TREE
);
7726 UOBJC_SUPER_scope
= objc_get_current_scope ();
7729 /* Set receiver to self. */
7730 super_expr
= build_component_ref (UOBJC_SUPER_decl
, self_id
);
7731 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, self_decl
);
7732 super_expr_list
= super_expr
;
7734 /* Set class to begin searching. */
7735 super_expr
= build_component_ref (UOBJC_SUPER_decl
,
7736 get_identifier ("super_class"));
7738 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
7740 /* [_cls, __cls]Super are "pre-built" in
7741 synth_forward_declarations. */
7743 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
,
7744 ((TREE_CODE (objc_method_context
)
7745 == INSTANCE_METHOD_DECL
)
7747 : uucls_super_ref
));
7751 /* We have a category. */
7753 tree super_name
= CLASS_SUPER_NAME (implementation_template
);
7756 /* Barf if super used in a category of Object. */
7759 error ("no super class declared in interface for `%s'",
7760 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
7761 return error_mark_node
;
7764 if (flag_next_runtime
&& !flag_zero_link
)
7766 super_class
= objc_get_class_reference (super_name
);
7767 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
7768 /* If we are in a class method, we must retrieve the
7769 _metaclass_ for the current class, pointed at by
7770 the class's "isa" pointer. The following assumes that
7771 "isa" is the first ivar in a class (which it must be). */
7773 = build_indirect_ref
7774 (build_c_cast (build_pointer_type (objc_class_type
),
7775 super_class
), "unary *");
7779 add_class_reference (super_name
);
7780 super_class
= (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
7781 ? objc_get_class_decl
: objc_get_meta_class_decl
);
7782 assemble_external (super_class
);
7784 = build_function_call
7788 my_build_string (IDENTIFIER_LENGTH (super_name
) + 1,
7789 IDENTIFIER_POINTER (super_name
))));
7793 = build_modify_expr (super_expr
, NOP_EXPR
,
7794 build_c_cast (TREE_TYPE (super_expr
),
7798 super_expr_list
= build_compound_expr (super_expr_list
, super_expr
);
7800 super_expr
= build_unary_op (ADDR_EXPR
, UOBJC_SUPER_decl
, 0);
7801 super_expr_list
= build_compound_expr (super_expr_list
, super_expr
);
7803 return super_expr_list
;
7807 error ("[super ...] must appear in a method context");
7808 return error_mark_node
;
7812 /* When exiting a scope, sever links to a 'super' declaration (if any)
7813 therein contained. */
7816 objc_clear_super_receiver (void)
7818 if (objc_method_context
7819 && UOBJC_SUPER_scope
== objc_get_current_scope ()) {
7820 UOBJC_SUPER_decl
= 0;
7821 UOBJC_SUPER_scope
= 0;
7826 objc_finish_method_definition (tree fndecl
)
7828 /* We cannot validly inline ObjC methods, at least not without a language
7829 extension to declare that a method need not be dynamically
7830 dispatched, so suppress all thoughts of doing so. */
7831 DECL_INLINE (fndecl
) = 0;
7832 DECL_UNINLINABLE (fndecl
) = 1;
7835 /* The C++ front-end will have called finish_function() for us. */
7839 METHOD_ENCODING (objc_method_context
)
7840 = encode_method_prototype (objc_method_context
);
7842 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7843 since the optimizer may find "may be used before set" errors. */
7844 objc_method_context
= NULL_TREE
;
7849 lang_report_error_function (tree decl
)
7851 if (objc_method_context
)
7853 fprintf (stderr
, "In method `%s'\n",
7854 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context
)));
7863 /* Given a tree DECL node, produce a printable description of it in the given
7864 buffer, overwriting the buffer. */
7867 gen_declaration (tree decl
)
7873 gen_type_name_0 (TREE_TYPE (decl
));
7875 if (DECL_NAME (decl
))
7877 if (!POINTER_TYPE_P (TREE_TYPE (decl
)))
7878 strcat (errbuf
, " ");
7880 strcat (errbuf
, IDENTIFIER_POINTER (DECL_NAME (decl
)));
7883 if (DECL_INITIAL (decl
)
7884 && TREE_CODE (DECL_INITIAL (decl
)) == INTEGER_CST
)
7885 sprintf (errbuf
+ strlen (errbuf
), ": " HOST_WIDE_INT_PRINT_DEC
,
7886 TREE_INT_CST_LOW (DECL_INITIAL (decl
)));
7892 /* Given a tree TYPE node, produce a printable description of it in the given
7893 buffer, overwriting the buffer. */
7896 gen_type_name_0 (tree type
)
7898 tree orig
= type
, proto
;
7900 if (TYPE_P (type
) && TYPE_NAME (type
))
7901 type
= TYPE_NAME (type
);
7902 else if (POINTER_TYPE_P (type
))
7904 gen_type_name_0 (TREE_TYPE (type
));
7906 if (!POINTER_TYPE_P (TREE_TYPE (type
)))
7907 strcat (errbuf
, " ");
7909 strcat (errbuf
, "*");
7913 if (TREE_CODE (type
) == TYPE_DECL
&& DECL_NAME (type
))
7914 type
= DECL_NAME (type
);
7916 strcat (errbuf
, IDENTIFIER_POINTER (type
));
7917 proto
= TYPE_PROTOCOL_LIST (orig
);
7921 strcat (errbuf
, " <");
7925 IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (proto
))));
7926 proto
= TREE_CHAIN (proto
);
7927 strcat (errbuf
, proto
? ", " : ">");
7936 gen_type_name (tree type
)
7940 return gen_type_name_0 (type
);
7943 /* Given a method tree, put a printable description into the given
7944 buffer (overwriting) and return a pointer to the buffer. */
7947 gen_method_decl (tree method
)
7951 strcpy (errbuf
, "("); /* NB: Do _not_ call strcat() here. */
7952 gen_type_name_0 (TREE_VALUE (TREE_TYPE (method
)));
7953 strcat (errbuf
, ")");
7954 chain
= METHOD_SEL_ARGS (method
);
7958 /* We have a chain of keyword_decls. */
7961 if (KEYWORD_KEY_NAME (chain
))
7962 strcat (errbuf
, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain
)));
7964 strcat (errbuf
, ":(");
7965 gen_type_name_0 (TREE_VALUE (TREE_TYPE (chain
)));
7966 strcat (errbuf
, ")");
7968 strcat (errbuf
, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain
)));
7969 if ((chain
= TREE_CHAIN (chain
)))
7970 strcat (errbuf
, " ");
7974 if (METHOD_ADD_ARGS (method
))
7976 chain
= TREE_CHAIN (METHOD_ADD_ARGS (method
));
7978 /* Know we have a chain of parm_decls. */
7981 strcat (errbuf
, ", ");
7982 gen_type_name_0 (TREE_TYPE (TREE_VALUE (chain
)));
7983 chain
= TREE_CHAIN (chain
);
7986 if (TREE_OVERFLOW (METHOD_ADD_ARGS (method
)))
7987 strcat (errbuf
, ", ...");
7992 /* We have a unary selector. */
7993 strcat (errbuf
, IDENTIFIER_POINTER (METHOD_SEL_NAME (method
)));
8001 /* Dump an @interface declaration of the supplied class CHAIN to the
8002 supplied file FP. Used to implement the -gen-decls option (which
8003 prints out an @interface declaration of all classes compiled in
8004 this run); potentially useful for debugging the compiler too. */
8006 dump_interface (FILE *fp
, tree chain
)
8008 /* FIXME: A heap overflow here whenever a method (or ivar)
8009 declaration is so long that it doesn't fit in the buffer. The
8010 code and all the related functions should be rewritten to avoid
8011 using fixed size buffers. */
8012 const char *my_name
= IDENTIFIER_POINTER (CLASS_NAME (chain
));
8013 tree ivar_decls
= CLASS_RAW_IVARS (chain
);
8014 tree nst_methods
= CLASS_NST_METHODS (chain
);
8015 tree cls_methods
= CLASS_CLS_METHODS (chain
);
8017 fprintf (fp
, "\n@interface %s", my_name
);
8019 /* CLASS_SUPER_NAME is used to store the superclass name for
8020 classes, and the category name for categories. */
8021 if (CLASS_SUPER_NAME (chain
))
8023 const char *name
= IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain
));
8025 if (TREE_CODE (chain
) == CATEGORY_IMPLEMENTATION_TYPE
8026 || TREE_CODE (chain
) == CATEGORY_INTERFACE_TYPE
)
8028 fprintf (fp
, " (%s)\n", name
);
8032 fprintf (fp
, " : %s\n", name
);
8038 /* FIXME - the following doesn't seem to work at the moment. */
8041 fprintf (fp
, "{\n");
8044 fprintf (fp
, "\t%s;\n", gen_declaration (ivar_decls
));
8045 ivar_decls
= TREE_CHAIN (ivar_decls
);
8048 fprintf (fp
, "}\n");
8053 fprintf (fp
, "- %s;\n", gen_method_decl (nst_methods
));
8054 nst_methods
= TREE_CHAIN (nst_methods
);
8059 fprintf (fp
, "+ %s;\n", gen_method_decl (cls_methods
));
8060 cls_methods
= TREE_CHAIN (cls_methods
);
8063 fprintf (fp
, "@end\n");
8066 /* Demangle function for Objective-C */
8068 objc_demangle (const char *mangled
)
8070 char *demangled
, *cp
;
8072 if (mangled
[0] == '_' &&
8073 (mangled
[1] == 'i' || mangled
[1] == 'c') &&
8076 cp
= demangled
= xmalloc(strlen(mangled
) + 2);
8077 if (mangled
[1] == 'i')
8078 *cp
++ = '-'; /* for instance method */
8080 *cp
++ = '+'; /* for class method */
8081 *cp
++ = '['; /* opening left brace */
8082 strcpy(cp
, mangled
+3); /* tack on the rest of the mangled name */
8083 while (*cp
&& *cp
== '_')
8084 cp
++; /* skip any initial underbars in class name */
8085 cp
= strchr(cp
, '_'); /* find first non-initial underbar */
8088 free(demangled
); /* not mangled name */
8091 if (cp
[1] == '_') /* easy case: no category name */
8093 *cp
++ = ' '; /* replace two '_' with one ' ' */
8094 strcpy(cp
, mangled
+ (cp
- demangled
) + 2);
8098 *cp
++ = '('; /* less easy case: category name */
8099 cp
= strchr(cp
, '_');
8102 free(demangled
); /* not mangled name */
8106 *cp
++ = ' '; /* overwriting 1st char of method name... */
8107 strcpy(cp
, mangled
+ (cp
- demangled
)); /* get it back */
8109 while (*cp
&& *cp
== '_')
8110 cp
++; /* skip any initial underbars in method name */
8113 *cp
= ':'; /* replace remaining '_' with ':' */
8114 *cp
++ = ']'; /* closing right brace */
8115 *cp
++ = 0; /* string terminator */
8119 return mangled
; /* not an objc mangled name */
8123 objc_printable_name (tree decl
, int kind ATTRIBUTE_UNUSED
)
8125 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl
)));
8131 gcc_obstack_init (&util_obstack
);
8132 util_firstobj
= (char *) obstack_finish (&util_obstack
);
8134 errbuf
= (char *) xmalloc (1024 * 10);
8136 synth_module_prologue ();
8142 struct imp_entry
*impent
;
8144 /* The internally generated initializers appear to have missing braces.
8145 Don't warn about this. */
8146 int save_warn_missing_braces
= warn_missing_braces
;
8147 warn_missing_braces
= 0;
8149 /* A missing @end may not be detected by the parser. */
8150 if (objc_implementation_context
)
8152 warning ("`@end' missing in implementation context");
8153 finish_class (objc_implementation_context
);
8154 objc_ivar_chain
= NULL_TREE
;
8155 objc_implementation_context
= NULL_TREE
;
8158 /* Process the static instances here because initialization of objc_symtab
8160 if (objc_static_instances
)
8161 generate_static_references ();
8163 if (imp_list
|| class_names_chain
8164 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8165 generate_objc_symtab_decl ();
8167 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8169 objc_implementation_context
= impent
->imp_context
;
8170 implementation_template
= impent
->imp_template
;
8172 UOBJC_CLASS_decl
= impent
->class_decl
;
8173 UOBJC_METACLASS_decl
= impent
->meta_decl
;
8175 /* Dump the @interface of each class as we compile it, if the
8176 -gen-decls option is in use. TODO: Dump the classes in the
8177 order they were found, rather than in reverse order as we
8179 if (flag_gen_declaration
)
8181 dump_interface (gen_declaration_file
, objc_implementation_context
);
8184 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
8186 /* all of the following reference the string pool... */
8187 generate_ivar_lists ();
8188 generate_dispatch_tables ();
8189 generate_shared_structures ();
8193 generate_dispatch_tables ();
8194 generate_category (objc_implementation_context
);
8198 /* If we are using an array of selectors, we must always
8199 finish up the array decl even if no selectors were used. */
8200 if (! flag_next_runtime
|| sel_ref_chain
)
8201 build_selector_translation_table ();
8204 generate_protocols ();
8206 if (flag_replace_objc_classes
&& imp_list
)
8207 generate_objc_image_info ();
8209 /* Arrange for ObjC data structures to be initialized at run time. */
8210 if (objc_implementation_context
|| class_names_chain
|| objc_static_instances
8211 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8213 build_module_descriptor ();
8215 if (!flag_next_runtime
)
8216 build_module_initializer_routine ();
8219 /* Dump the class references. This forces the appropriate classes
8220 to be linked into the executable image, preserving unix archive
8221 semantics. This can be removed when we move to a more dynamically
8222 linked environment. */
8224 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
8226 handle_class_ref (chain
);
8227 if (TREE_PURPOSE (chain
))
8228 generate_classref_translation_entry (chain
);
8231 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8232 handle_impent (impent
);
8234 /* Dump the string table last. */
8236 generate_strings ();
8243 /* Run through the selector hash tables and print a warning for any
8244 selector which has multiple methods. */
8246 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8248 for (hsh
= cls_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8249 check_duplicates (hsh
, 0, 1);
8250 for (hsh
= nst_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8251 check_duplicates (hsh
, 0, 1);
8255 warn_missing_braces
= save_warn_missing_braces
;
8258 /* Subroutines of finish_objc. */
8261 generate_classref_translation_entry (tree chain
)
8263 tree expr
, decl
, type
;
8265 decl
= TREE_PURPOSE (chain
);
8266 type
= TREE_TYPE (decl
);
8268 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
8269 expr
= convert (type
, expr
); /* cast! */
8271 /* The decl that is the one that we
8272 forward declared in build_class_reference. */
8273 finish_var_decl (decl
, expr
);
8278 handle_class_ref (tree chain
)
8280 const char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
8281 char *string
= (char *) alloca (strlen (name
) + 30);
8285 sprintf (string
, "%sobjc_class_name_%s",
8286 (flag_next_runtime
? "." : "__"), name
);
8288 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8289 if (flag_next_runtime
)
8291 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file
, string
);
8296 /* Make a decl for this name, so we can use its address in a tree. */
8297 decl
= build_decl (VAR_DECL
, get_identifier (string
), char_type_node
);
8298 DECL_EXTERNAL (decl
) = 1;
8299 TREE_PUBLIC (decl
) = 1;
8302 rest_of_decl_compilation (decl
, 0, 0);
8304 /* Make a decl for the address. */
8305 sprintf (string
, "%sobjc_class_ref_%s",
8306 (flag_next_runtime
? "." : "__"), name
);
8307 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
8308 decl
= build_decl (VAR_DECL
, get_identifier (string
), string_type_node
);
8309 DECL_INITIAL (decl
) = exp
;
8310 TREE_STATIC (decl
) = 1;
8311 TREE_USED (decl
) = 1;
8314 rest_of_decl_compilation (decl
, 0, 0);
8318 handle_impent (struct imp_entry
*impent
)
8322 objc_implementation_context
= impent
->imp_context
;
8323 implementation_template
= impent
->imp_template
;
8325 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
8327 const char *const class_name
=
8328 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8330 string
= (char *) alloca (strlen (class_name
) + 30);
8332 sprintf (string
, "%sobjc_class_name_%s",
8333 (flag_next_runtime
? "." : "__"), class_name
);
8335 else if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
8337 const char *const class_name
=
8338 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8339 const char *const class_super_name
=
8340 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
8342 string
= (char *) alloca (strlen (class_name
)
8343 + strlen (class_super_name
) + 30);
8345 /* Do the same for categories. Even though no references to
8346 these symbols are generated automatically by the compiler, it
8347 gives you a handle to pull them into an archive by hand. */
8348 sprintf (string
, "*%sobjc_category_name_%s_%s",
8349 (flag_next_runtime
? "." : "__"), class_name
, class_super_name
);
8354 #ifdef ASM_DECLARE_CLASS_REFERENCE
8355 if (flag_next_runtime
)
8357 ASM_DECLARE_CLASS_REFERENCE (asm_out_file
, string
);
8365 init
= build_int_cst (c_common_type_for_size (BITS_PER_WORD
, 1), 0);
8366 decl
= build_decl (VAR_DECL
, get_identifier (string
), TREE_TYPE (init
));
8367 TREE_PUBLIC (decl
) = 1;
8368 TREE_READONLY (decl
) = 1;
8369 TREE_USED (decl
) = 1;
8370 TREE_CONSTANT (decl
) = 1;
8371 DECL_CONTEXT (decl
) = 0;
8372 DECL_ARTIFICIAL (decl
) = 1;
8373 DECL_INITIAL (decl
) = init
;
8374 assemble_variable (decl
, 1, 0, 0);
8378 /* The Fix-and-Continue functionality available in Mac OS X 10.3 and
8379 later requires that ObjC translation units participating in F&C be
8380 specially marked. The following routine accomplishes this. */
8382 /* static int _OBJC_IMAGE_INFO[2] = { 0, 1 }; */
8385 generate_objc_image_info (void)
8387 tree decl
, initlist
;
8389 decl
= start_var_decl (build_array_type
8391 build_index_type (build_int_cst (NULL_TREE
, 2 - 1))),
8392 "_OBJC_IMAGE_INFO");
8394 initlist
= build_tree_list (NULL_TREE
, build_int_cst (NULL_TREE
, 0));
8395 initlist
= tree_cons (NULL_TREE
, build_int_cst (NULL_TREE
, 1), initlist
);
8396 initlist
= objc_build_constructor (TREE_TYPE (decl
), nreverse (initlist
));
8398 finish_var_decl (decl
, initlist
);
8401 /* Look up ID as an instance variable. */
8404 objc_lookup_ivar (tree id
)
8408 if (objc_method_context
&& !strcmp (IDENTIFIER_POINTER (id
), "super"))
8409 /* We have a message to super. */
8410 return get_super_receiver ();
8411 else if (objc_method_context
&& (decl
= is_ivar (objc_ivar_chain
, id
)))
8413 if (is_private (decl
))
8416 return build_ivar_reference (id
);
8422 #include "gt-objc-objc-act.h"