1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002
3 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GNU CC.
8 GNU CC 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 GNU CC 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 GNU CC; 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':
59 #include "diagnostic.h"
61 /* This is the default way of generating a method name. */
62 /* I am not sure it is really correct.
63 Perhaps there's a danger that it will make name conflicts
64 if method names contain underscores. -- rms. */
65 #ifndef OBJC_GEN_METHOD_LABEL
66 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
69 sprintf ((BUF), "_%s_%s_%s_%s", \
70 ((IS_INST) ? "i" : "c"), \
72 ((CAT_NAME)? (CAT_NAME) : ""), \
74 for (temp = (BUF); *temp; temp++) \
75 if (*temp == ':') *temp = '_'; \
79 /* These need specifying. */
80 #ifndef OBJC_FORWARDING_STACK_OFFSET
81 #define OBJC_FORWARDING_STACK_OFFSET 0
84 #ifndef OBJC_FORWARDING_MIN_OFFSET
85 #define OBJC_FORWARDING_MIN_OFFSET 0
89 /* Set up for use of obstacks. */
93 #define obstack_chunk_alloc xmalloc
94 #define obstack_chunk_free free
96 /* This obstack is used to accumulate the encoding of a data type. */
97 static struct obstack util_obstack
;
98 /* This points to the beginning of obstack contents,
99 so we can free the whole contents. */
102 /* for encode_method_def */
105 /* The version identifies which language generation and runtime
106 the module (file) was compiled for, and is recorded in the
107 module descriptor. */
109 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
110 #define PROTOCOL_VERSION 2
112 /* (Decide if these can ever be validly changed.) */
113 #define OBJC_ENCODE_INLINE_DEFS 0
114 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
116 /*** Private Interface (procedures) ***/
118 /* Used by compile_file. */
120 static void init_objc
PARAMS ((void));
121 static void finish_objc
PARAMS ((void));
123 /* Code generation. */
125 static void synth_module_prologue
PARAMS ((void));
126 static tree build_constructor
PARAMS ((tree
, tree
));
127 static rtx build_module_descriptor
PARAMS ((void));
128 static tree init_module_descriptor
PARAMS ((tree
));
129 static tree build_objc_method_call
PARAMS ((int, tree
, tree
,
131 static void generate_strings
PARAMS ((void));
132 static tree get_proto_encoding
PARAMS ((tree
));
133 static void build_selector_translation_table
PARAMS ((void));
134 static tree build_ivar_chain
PARAMS ((tree
, int));
136 static tree objc_add_static_instance
PARAMS ((tree
, tree
));
138 static tree build_ivar_template
PARAMS ((void));
139 static tree build_method_template
PARAMS ((void));
140 static tree build_private_template
PARAMS ((tree
));
141 static void build_class_template
PARAMS ((void));
142 static void build_selector_template
PARAMS ((void));
143 static void build_category_template
PARAMS ((void));
144 static tree build_super_template
PARAMS ((void));
145 static tree build_category_initializer
PARAMS ((tree
, tree
, tree
,
147 static tree build_protocol_initializer
PARAMS ((tree
, tree
, tree
,
150 static void synth_forward_declarations
PARAMS ((void));
151 static void generate_ivar_lists
PARAMS ((void));
152 static void generate_dispatch_tables
PARAMS ((void));
153 static void generate_shared_structures
PARAMS ((void));
154 static tree generate_protocol_list
PARAMS ((tree
));
155 static void generate_forward_declaration_to_string_table
PARAMS ((void));
156 static void build_protocol_reference
PARAMS ((tree
));
158 static tree build_keyword_selector
PARAMS ((tree
));
159 static tree synth_id_with_class_suffix
PARAMS ((const char *, tree
));
161 static void generate_static_references
PARAMS ((void));
162 static int check_methods_accessible
PARAMS ((tree
, tree
,
164 static void encode_aggregate_within
PARAMS ((tree
, int, int,
166 static const char *objc_demangle
PARAMS ((const char *));
167 static void objc_expand_function_end
PARAMS ((void));
169 /* Hash tables to manage the global pool of method prototypes. */
171 hash
*nst_method_hash_list
= 0;
172 hash
*cls_method_hash_list
= 0;
174 static size_t hash_func
PARAMS ((tree
));
175 static void hash_init
PARAMS ((void));
176 static void hash_enter
PARAMS ((hash
*, tree
));
177 static hash hash_lookup
PARAMS ((hash
*, tree
));
178 static void hash_add_attr
PARAMS ((hash
, tree
));
179 static tree lookup_method
PARAMS ((tree
, tree
));
180 static tree lookup_instance_method_static
PARAMS ((tree
, tree
));
181 static tree lookup_class_method_static
PARAMS ((tree
, tree
));
182 static tree add_class
PARAMS ((tree
));
183 static void add_category
PARAMS ((tree
, tree
));
187 class_names
, /* class, category, protocol, module names */
188 meth_var_names
, /* method and variable names */
189 meth_var_types
/* method and variable type descriptors */
192 static tree add_objc_string
PARAMS ((tree
,
193 enum string_section
));
194 static tree get_objc_string_decl
PARAMS ((tree
,
195 enum string_section
));
196 static tree build_objc_string_decl
PARAMS ((enum string_section
));
197 static tree build_selector_reference_decl
PARAMS ((void));
199 /* Protocol additions. */
201 static tree add_protocol
PARAMS ((tree
));
202 static tree lookup_protocol
PARAMS ((tree
));
203 static void check_protocol_recursively
PARAMS ((tree
, tree
));
204 static tree lookup_and_install_protocols
PARAMS ((tree
));
208 static void encode_type_qualifiers
PARAMS ((tree
));
209 static void encode_pointer
PARAMS ((tree
, int, int));
210 static void encode_array
PARAMS ((tree
, int, int));
211 static void encode_aggregate
PARAMS ((tree
, int, int));
212 static void encode_bitfield
PARAMS ((int));
213 static void encode_type
PARAMS ((tree
, int, int));
214 static void encode_field_decl
PARAMS ((tree
, int, int));
216 static void really_start_method
PARAMS ((tree
, tree
));
217 static int comp_method_with_proto
PARAMS ((tree
, tree
));
218 static int comp_proto_with_proto
PARAMS ((tree
, tree
));
219 static tree get_arg_type_list
PARAMS ((tree
, int, int));
220 static tree expr_last
PARAMS ((tree
));
222 /* Utilities for debugging and error diagnostics. */
224 static void warn_with_method
PARAMS ((const char *, int, tree
));
225 static void error_with_ivar
PARAMS ((const char *, tree
, tree
));
226 static char *gen_method_decl
PARAMS ((tree
, char *));
227 static char *gen_declaration
PARAMS ((tree
, char *));
228 static void gen_declaration_1
PARAMS ((tree
, char *));
229 static char *gen_declarator
PARAMS ((tree
, char *,
231 static int is_complex_decl
PARAMS ((tree
));
232 static void adorn_decl
PARAMS ((tree
, char *));
233 static void dump_interface
PARAMS ((FILE *, tree
));
235 /* Everything else. */
237 static tree define_decl
PARAMS ((tree
, tree
));
238 static tree lookup_method_in_protocol_list
PARAMS ((tree
, tree
, int));
239 static tree lookup_protocol_in_reflist
PARAMS ((tree
, tree
));
240 static tree create_builtin_decl
PARAMS ((enum tree_code
,
241 tree
, const char *));
242 static void setup_string_decl
PARAMS ((void));
243 static void build_string_class_template
PARAMS ((void));
244 static tree my_build_string
PARAMS ((int, const char *));
245 static void build_objc_symtab_template
PARAMS ((void));
246 static tree init_def_list
PARAMS ((tree
));
247 static tree init_objc_symtab
PARAMS ((tree
));
248 static void forward_declare_categories
PARAMS ((void));
249 static void generate_objc_symtab_decl
PARAMS ((void));
250 static tree build_selector
PARAMS ((tree
));
251 static tree build_typed_selector_reference
PARAMS ((tree
, tree
));
252 static tree build_selector_reference
PARAMS ((tree
));
253 static tree build_class_reference_decl
PARAMS ((void));
254 static void add_class_reference
PARAMS ((tree
));
255 static tree objc_copy_list
PARAMS ((tree
, tree
*));
256 static tree build_protocol_template
PARAMS ((void));
257 static tree build_descriptor_table_initializer
PARAMS ((tree
, tree
));
258 static tree build_method_prototype_list_template
PARAMS ((tree
, int));
259 static tree build_method_prototype_template
PARAMS ((void));
260 static int forwarding_offset
PARAMS ((tree
));
261 static tree encode_method_prototype
PARAMS ((tree
, tree
));
262 static tree generate_descriptor_table
PARAMS ((tree
, const char *,
264 static void generate_method_descriptors
PARAMS ((tree
));
265 static tree build_tmp_function_decl
PARAMS ((void));
266 static void hack_method_prototype
PARAMS ((tree
, tree
));
267 static void generate_protocol_references
PARAMS ((tree
));
268 static void generate_protocols
PARAMS ((void));
269 static void check_ivars
PARAMS ((tree
, tree
));
270 static tree build_ivar_list_template
PARAMS ((tree
, int));
271 static tree build_method_list_template
PARAMS ((tree
, int));
272 static tree build_ivar_list_initializer
PARAMS ((tree
, tree
));
273 static tree generate_ivars_list
PARAMS ((tree
, const char *,
275 static tree build_dispatch_table_initializer
PARAMS ((tree
, tree
));
276 static tree generate_dispatch_table
PARAMS ((tree
, const char *,
278 static tree build_shared_structure_initializer
PARAMS ((tree
, tree
, tree
, tree
,
279 tree
, int, tree
, tree
,
281 static void generate_category
PARAMS ((tree
));
282 static int is_objc_type_qualifier
PARAMS ((tree
));
283 static tree adjust_type_for_id_default
PARAMS ((tree
));
284 static tree check_duplicates
PARAMS ((hash
));
285 static tree receiver_is_class_object
PARAMS ((tree
));
286 static int check_methods
PARAMS ((tree
, tree
, int));
287 static int conforms_to_protocol
PARAMS ((tree
, tree
));
288 static void check_protocol
PARAMS ((tree
, const char *,
290 static void check_protocols
PARAMS ((tree
, const char *,
292 static tree encode_method_def
PARAMS ((tree
));
293 static void gen_declspecs
PARAMS ((tree
, char *, int));
294 static void generate_classref_translation_entry
PARAMS ((tree
));
295 static void handle_class_ref
PARAMS ((tree
));
296 static void generate_struct_by_value_array
PARAMS ((void))
299 /*** Private Interface (data) ***/
301 /* Reserved tag definitions. */
304 #define TAG_OBJECT "objc_object"
305 #define TAG_CLASS "objc_class"
306 #define TAG_SUPER "objc_super"
307 #define TAG_SELECTOR "objc_selector"
309 #define UTAG_CLASS "_objc_class"
310 #define UTAG_IVAR "_objc_ivar"
311 #define UTAG_IVAR_LIST "_objc_ivar_list"
312 #define UTAG_METHOD "_objc_method"
313 #define UTAG_METHOD_LIST "_objc_method_list"
314 #define UTAG_CATEGORY "_objc_category"
315 #define UTAG_MODULE "_objc_module"
316 #define UTAG_STATICS "_objc_statics"
317 #define UTAG_SYMTAB "_objc_symtab"
318 #define UTAG_SUPER "_objc_super"
319 #define UTAG_SELECTOR "_objc_selector"
321 #define UTAG_PROTOCOL "_objc_protocol"
322 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
323 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
324 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
326 /* Note that the string object global name is only needed for the
328 #define STRING_OBJECT_GLOBAL_NAME "_NSConstantStringClassReference"
330 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
332 static const char *constant_string_class_name
= NULL
;
334 static const char *TAG_GETCLASS
;
335 static const char *TAG_GETMETACLASS
;
336 static const char *TAG_MSGSEND
;
337 static const char *TAG_MSGSENDSUPER
;
338 static const char *TAG_EXECCLASS
;
339 static const char *default_constant_string_class_name
;
341 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
342 tree objc_global_trees
[OCTI_MAX
];
344 static void handle_impent
PARAMS ((struct imp_entry
*));
346 struct imp_entry
*imp_list
= 0;
347 int imp_count
= 0; /* `@implementation' */
348 int cat_count
= 0; /* `@category' */
350 static int method_slot
= 0; /* Used by start_method_def, */
354 static char *errbuf
; /* Buffer for error diagnostics */
356 /* Data imported from tree.c. */
358 extern enum debug_info_type write_symbols
;
360 /* Data imported from toplev.c. */
362 extern const char *dump_base_name
;
364 /* Generate code for GNU or NeXT runtime environment. */
366 #ifdef NEXT_OBJC_RUNTIME
367 int flag_next_runtime
= 1;
369 int flag_next_runtime
= 0;
372 int flag_typed_selectors
;
374 /* Open and close the file for outputting class declarations, if requested. */
376 int flag_gen_declaration
= 0;
378 FILE *gen_declaration_file
;
380 /* Warn if multiple methods are seen for the same selector, but with
381 different argument types. */
383 int warn_selector
= 0;
385 /* Warn if methods required by a protocol are not implemented in the
386 class adopting it. When turned off, methods inherited to that
387 class are also considered implemented */
389 int flag_warn_protocol
= 1;
391 /* Tells "encode_pointer/encode_aggregate" whether we are generating
392 type descriptors for instance variables (as opposed to methods).
393 Type descriptors for instance variables contain more information
394 than methods (for static typing and embedded structures). */
396 static int generating_instance_variables
= 0;
398 /* Tells the compiler that this is a special run. Do not perform any
399 compiling, instead we are to test some platform dependent features
400 and output a C header file with appropriate definitions. */
402 static int print_struct_values
= 0;
404 /* Some platforms pass small structures through registers versus
405 through an invisible pointer. Determine at what size structure is
406 the transition point between the two possibilities. */
409 generate_struct_by_value_array ()
412 tree field_decl
, field_decl_chain
;
414 int aggregate_in_mem
[32];
417 /* Presumably no platform passes 32 byte structures in a register. */
418 for (i
= 1; i
< 32; i
++)
422 /* Create an unnamed struct that has `i' character components */
423 type
= start_struct (RECORD_TYPE
, NULL_TREE
);
425 strcpy (buffer
, "c1");
426 field_decl
= create_builtin_decl (FIELD_DECL
,
429 field_decl_chain
= field_decl
;
431 for (j
= 1; j
< i
; j
++)
433 sprintf (buffer
, "c%d", j
+ 1);
434 field_decl
= create_builtin_decl (FIELD_DECL
,
437 chainon (field_decl_chain
, field_decl
);
439 finish_struct (type
, field_decl_chain
, NULL_TREE
);
441 aggregate_in_mem
[i
] = aggregate_value_p (type
);
442 if (!aggregate_in_mem
[i
])
446 /* We found some structures that are returned in registers instead of memory
447 so output the necessary data. */
450 for (i
= 31; i
>= 0; i
--)
451 if (!aggregate_in_mem
[i
])
453 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i
);
455 /* The first member of the structure is always 0 because we don't handle
456 structures with 0 members */
457 printf ("static int struct_forward_array[] = {\n 0");
459 for (j
= 1; j
<= i
; j
++)
460 printf (", %d", aggregate_in_mem
[j
]);
469 const char *filename
;
471 filename
= c_objc_common_init (filename
);
473 /* Force the line number back to 0; check_newline will have
474 raised it to 1, which will make the builtin functions appear
475 not to be built in. */
478 /* If gen_declaration desired, open the output file. */
479 if (flag_gen_declaration
)
481 register char * const dumpname
= concat (dump_base_name
, ".decl", NULL
);
482 gen_declaration_file
= fopen (dumpname
, "w");
483 if (gen_declaration_file
== 0)
484 fatal_io_error ("can't open %s", dumpname
);
488 if (flag_next_runtime
)
490 TAG_GETCLASS
= "objc_getClass";
491 TAG_GETMETACLASS
= "objc_getMetaClass";
492 TAG_MSGSEND
= "objc_msgSend";
493 TAG_MSGSENDSUPER
= "objc_msgSendSuper";
494 TAG_EXECCLASS
= "__objc_execClass";
495 default_constant_string_class_name
= "NSConstantString";
499 TAG_GETCLASS
= "objc_get_class";
500 TAG_GETMETACLASS
= "objc_get_meta_class";
501 TAG_MSGSEND
= "objc_msg_lookup";
502 TAG_MSGSENDSUPER
= "objc_msg_lookup_super";
503 TAG_EXECCLASS
= "__objc_exec_class";
504 default_constant_string_class_name
= "NXConstantString";
505 flag_typed_selectors
= 1;
508 objc_ellipsis_node
= make_node (ERROR_MARK
);
512 if (print_struct_values
)
513 generate_struct_by_value_array ();
521 c_objc_common_finish_file ();
523 /* Finalize Objective-C runtime data. No need to generate tables
524 and code if only checking syntax. */
525 if (!flag_syntax_only
)
528 if (gen_declaration_file
)
529 fclose (gen_declaration_file
);
533 objc_decode_option (argc
, argv
)
537 const char *p
= argv
[0];
539 if (!strcmp (p
, "-gen-decls"))
540 flag_gen_declaration
= 1;
541 else if (!strcmp (p
, "-Wselector"))
543 else if (!strcmp (p
, "-Wno-selector"))
545 else if (!strcmp (p
, "-Wprotocol"))
546 flag_warn_protocol
= 1;
547 else if (!strcmp (p
, "-Wno-protocol"))
548 flag_warn_protocol
= 0;
549 else if (!strcmp (p
, "-fgnu-runtime"))
550 flag_next_runtime
= 0;
551 else if (!strcmp (p
, "-fno-next-runtime"))
552 flag_next_runtime
= 0;
553 else if (!strcmp (p
, "-fno-gnu-runtime"))
554 flag_next_runtime
= 1;
555 else if (!strcmp (p
, "-fnext-runtime"))
556 flag_next_runtime
= 1;
557 else if (!strcmp (p
, "-print-objc-runtime-info"))
558 print_struct_values
= 1;
559 #define CSTSTRCLASS "-fconstant-string-class="
560 else if (!strncmp (p
, CSTSTRCLASS
, sizeof(CSTSTRCLASS
) - 2)) {
561 if (strlen (argv
[0]) <= strlen (CSTSTRCLASS
))
562 error ("no class name specified as argument to -fconstant-string-class");
563 constant_string_class_name
= xstrdup(argv
[0] + sizeof(CSTSTRCLASS
) - 1);
567 return c_decode_option (argc
, argv
);
574 define_decl (declarator
, declspecs
)
578 tree decl
= start_decl (declarator
, declspecs
, 0, NULL_TREE
);
579 finish_decl (decl
, NULL_TREE
, NULL_TREE
);
583 /* Return 1 if LHS and RHS are compatible types for assignment or
584 various other operations. Return 0 if they are incompatible, and
585 return -1 if we choose to not decide. When the operation is
586 REFLEXIVE, check for compatibility in either direction.
588 For statically typed objects, an assignment of the form `a' = `b'
592 `a' and `b' are the same class type, or
593 `a' and `b' are of class types A and B such that B is a descendant of A. */
596 maybe_objc_comptypes (lhs
, rhs
, reflexive
)
600 return objc_comptypes (lhs
, rhs
, reflexive
);
604 lookup_method_in_protocol_list (rproto_list
, sel_name
, class_meth
)
612 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
614 p
= TREE_VALUE (rproto
);
616 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
618 if ((fnd
= lookup_method (class_meth
619 ? PROTOCOL_CLS_METHODS (p
)
620 : PROTOCOL_NST_METHODS (p
), sel_name
)))
622 else if (PROTOCOL_LIST (p
))
623 fnd
= lookup_method_in_protocol_list (PROTOCOL_LIST (p
),
624 sel_name
, class_meth
);
628 ; /* An identifier...if we could not find a protocol. */
639 lookup_protocol_in_reflist (rproto_list
, lproto
)
645 /* Make sure the protocol is supported by the object on the rhs. */
646 if (TREE_CODE (lproto
) == PROTOCOL_INTERFACE_TYPE
)
649 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
651 p
= TREE_VALUE (rproto
);
653 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
658 else if (PROTOCOL_LIST (p
))
659 fnd
= lookup_protocol_in_reflist (PROTOCOL_LIST (p
), lproto
);
668 ; /* An identifier...if we could not find a protocol. */
674 /* Return 1 if LHS and RHS are compatible types for assignment
675 or various other operations. Return 0 if they are incompatible,
676 and return -1 if we choose to not decide. When the operation
677 is REFLEXIVE, check for compatibility in either direction. */
680 objc_comptypes (lhs
, rhs
, reflexive
)
685 /* New clause for protocols. */
687 if (TREE_CODE (lhs
) == POINTER_TYPE
688 && TREE_CODE (TREE_TYPE (lhs
)) == RECORD_TYPE
689 && TREE_CODE (rhs
) == POINTER_TYPE
690 && TREE_CODE (TREE_TYPE (rhs
)) == RECORD_TYPE
)
692 int lhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (lhs
);
693 int rhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (rhs
);
697 tree lproto
, lproto_list
= TYPE_PROTOCOL_LIST (lhs
);
698 tree rproto
, rproto_list
;
703 rproto_list
= TYPE_PROTOCOL_LIST (rhs
);
705 /* Make sure the protocol is supported by the object
707 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
709 p
= TREE_VALUE (lproto
);
710 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
713 warning ("object does not conform to the `%s' protocol",
714 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
717 else if (TYPED_OBJECT (TREE_TYPE (rhs
)))
719 tree rname
= TYPE_NAME (TREE_TYPE (rhs
));
722 /* Make sure the protocol is supported by the object
724 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
726 p
= TREE_VALUE (lproto
);
728 rinter
= lookup_interface (rname
);
730 while (rinter
&& !rproto
)
734 rproto_list
= CLASS_PROTOCOL_LIST (rinter
);
735 /* If the underlying ObjC class does not have
736 protocols attached to it, perhaps there are
737 "one-off" protocols attached to the rhs?
738 E.g., 'id<MyProt> foo;'. */
740 rproto_list
= TYPE_PROTOCOL_LIST (TREE_TYPE (rhs
));
741 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
743 /* Check for protocols adopted by categories. */
744 cat
= CLASS_CATEGORY_LIST (rinter
);
745 while (cat
&& !rproto
)
747 rproto_list
= CLASS_PROTOCOL_LIST (cat
);
748 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
750 cat
= CLASS_CATEGORY_LIST (cat
);
753 rinter
= lookup_interface (CLASS_SUPER_NAME (rinter
));
757 warning ("class `%s' does not implement the `%s' protocol",
758 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs
))),
759 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
763 /* May change...based on whether there was any mismatch */
766 else if (rhs_is_proto
)
767 /* Lhs is not a protocol...warn if it is statically typed */
768 return (TYPED_OBJECT (TREE_TYPE (lhs
)) != 0);
771 /* Defer to comptypes. */
775 else if (TREE_CODE (lhs
) == RECORD_TYPE
&& TREE_CODE (rhs
) == RECORD_TYPE
)
776 ; /* Fall thru. This is the case we have been handling all along */
778 /* Defer to comptypes. */
781 /* `id' = `<class> *', `<class> *' = `id' */
783 if ((TYPE_NAME (lhs
) == objc_object_id
&& TYPED_OBJECT (rhs
))
784 || (TYPE_NAME (rhs
) == objc_object_id
&& TYPED_OBJECT (lhs
)))
787 /* `id' = `Class', `Class' = `id' */
789 else if ((TYPE_NAME (lhs
) == objc_object_id
790 && TYPE_NAME (rhs
) == objc_class_id
)
791 || (TYPE_NAME (lhs
) == objc_class_id
792 && TYPE_NAME (rhs
) == objc_object_id
))
795 /* `<class> *' = `<class> *' */
797 else if (TYPED_OBJECT (lhs
) && TYPED_OBJECT (rhs
))
799 tree lname
= TYPE_NAME (lhs
);
800 tree rname
= TYPE_NAME (rhs
);
806 /* If the left hand side is a super class of the right hand side,
808 for (inter
= lookup_interface (rname
); inter
;
809 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
810 if (lname
== CLASS_SUPER_NAME (inter
))
813 /* Allow the reverse when reflexive. */
815 for (inter
= lookup_interface (lname
); inter
;
816 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
817 if (rname
== CLASS_SUPER_NAME (inter
))
823 /* Defer to comptypes. */
827 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
830 objc_check_decl (decl
)
833 tree type
= TREE_TYPE (decl
);
835 if (TREE_CODE (type
) == RECORD_TYPE
836 && TREE_STATIC_TEMPLATE (type
)
837 && type
!= constant_string_type
)
838 error_with_decl (decl
, "`%s' cannot be statically allocated");
842 maybe_objc_check_decl (decl
)
845 objc_check_decl (decl
);
848 /* Implement static typing. At this point, we know we have an interface. */
851 get_static_reference (interface
, protocols
)
855 tree type
= xref_tag (RECORD_TYPE
, interface
);
859 tree t
, m
= TYPE_MAIN_VARIANT (type
);
861 t
= copy_node (type
);
862 TYPE_BINFO (t
) = make_tree_vec (2);
864 /* Add this type to the chain of variants of TYPE. */
865 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
866 TYPE_NEXT_VARIANT (m
) = t
;
868 /* Look up protocols and install in lang specific list. Note
869 that the protocol list can have a different lifetime than T! */
870 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
872 /* This forces a new pointer type to be created later
873 (in build_pointer_type)...so that the new template
874 we just created will actually be used...what a hack! */
875 if (TYPE_POINTER_TO (t
))
876 TYPE_POINTER_TO (t
) = NULL_TREE
;
885 get_object_reference (protocols
)
888 tree type_decl
= lookup_name (objc_id_id
);
891 if (type_decl
&& TREE_CODE (type_decl
) == TYPE_DECL
)
893 type
= TREE_TYPE (type_decl
);
894 if (TYPE_MAIN_VARIANT (type
) != id_type
)
895 warning ("unexpected type for `id' (%s)",
896 gen_declaration (type
, errbuf
));
900 error ("undefined type `id', please import <objc/objc.h>");
901 return error_mark_node
;
904 /* This clause creates a new pointer type that is qualified with
905 the protocol specification...this info is used later to do more
906 elaborate type checking. */
910 tree t
, m
= TYPE_MAIN_VARIANT (type
);
912 t
= copy_node (type
);
913 TYPE_BINFO (t
) = make_tree_vec (2);
915 /* Add this type to the chain of variants of TYPE. */
916 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
917 TYPE_NEXT_VARIANT (m
) = t
;
919 /* Look up protocols...and install in lang specific list */
920 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
922 /* This forces a new pointer type to be created later
923 (in build_pointer_type)...so that the new template
924 we just created will actually be used...what a hack! */
925 if (TYPE_POINTER_TO (t
))
926 TYPE_POINTER_TO (t
) = NULL_TREE
;
933 /* Check for circular dependencies in protocols. The arguments are
934 PROTO, the protocol to check, and LIST, a list of protocol it
938 check_protocol_recursively (proto
, list
)
944 for (p
= list
; p
; p
= TREE_CHAIN (p
))
946 tree pp
= TREE_VALUE (p
);
948 if (TREE_CODE (pp
) == IDENTIFIER_NODE
)
949 pp
= lookup_protocol (pp
);
952 fatal_error ("protocol `%s' has circular dependency",
953 IDENTIFIER_POINTER (PROTOCOL_NAME (pp
)));
955 check_protocol_recursively (proto
, PROTOCOL_LIST (pp
));
960 lookup_and_install_protocols (protocols
)
965 tree return_value
= protocols
;
967 for (proto
= protocols
; proto
; proto
= TREE_CHAIN (proto
))
969 tree ident
= TREE_VALUE (proto
);
970 tree p
= lookup_protocol (ident
);
974 error ("cannot find protocol declaration for `%s'",
975 IDENTIFIER_POINTER (ident
));
977 TREE_CHAIN (prev
) = TREE_CHAIN (proto
);
979 return_value
= TREE_CHAIN (proto
);
983 /* Replace identifier with actual protocol node. */
984 TREE_VALUE (proto
) = p
;
992 /* Create and push a decl for a built-in external variable or field NAME.
994 TYPE is its data type. */
997 create_builtin_decl (code
, type
, name
)
1002 tree decl
= build_decl (code
, get_identifier (name
), type
);
1004 if (code
== VAR_DECL
)
1006 TREE_STATIC (decl
) = 1;
1007 make_decl_rtl (decl
, 0);
1011 DECL_ARTIFICIAL (decl
) = 1;
1015 /* Find the decl for the constant string class. */
1018 setup_string_decl ()
1020 if (!string_class_decl
)
1022 if (!constant_string_global_id
)
1023 constant_string_global_id
= get_identifier (STRING_OBJECT_GLOBAL_NAME
);
1024 string_class_decl
= lookup_name (constant_string_global_id
);
1028 /* Purpose: "play" parser, creating/installing representations
1029 of the declarations that are required by Objective-C.
1033 type_spec--------->sc_spec
1034 (tree_list) (tree_list)
1037 identifier_node identifier_node */
1040 synth_module_prologue ()
1045 /* Defined in `objc.h' */
1046 objc_object_id
= get_identifier (TAG_OBJECT
);
1048 objc_object_reference
= xref_tag (RECORD_TYPE
, objc_object_id
);
1050 id_type
= build_pointer_type (objc_object_reference
);
1052 objc_id_id
= get_identifier (TYPE_ID
);
1053 objc_class_id
= get_identifier (TAG_CLASS
);
1055 objc_class_type
= build_pointer_type (xref_tag (RECORD_TYPE
, objc_class_id
));
1056 protocol_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
1057 get_identifier (PROTOCOL_OBJECT_CLASS_NAME
)));
1059 /* Declare type of selector-objects that represent an operation name. */
1061 /* `struct objc_selector *' */
1063 = build_pointer_type (xref_tag (RECORD_TYPE
,
1064 get_identifier (TAG_SELECTOR
)));
1066 /* Forward declare type, or else the prototype for msgSendSuper will
1069 super_p
= build_pointer_type (xref_tag (RECORD_TYPE
,
1070 get_identifier (TAG_SUPER
)));
1073 /* id objc_msgSend (id, SEL, ...); */
1076 = build_function_type (id_type
,
1077 tree_cons (NULL_TREE
, id_type
,
1078 tree_cons (NULL_TREE
, selector_type
,
1081 if (! flag_next_runtime
)
1083 umsg_decl
= build_decl (FUNCTION_DECL
,
1084 get_identifier (TAG_MSGSEND
), temp_type
);
1085 DECL_EXTERNAL (umsg_decl
) = 1;
1086 TREE_PUBLIC (umsg_decl
) = 1;
1087 DECL_INLINE (umsg_decl
) = 1;
1088 DECL_ARTIFICIAL (umsg_decl
) = 1;
1090 make_decl_rtl (umsg_decl
, NULL
);
1091 pushdecl (umsg_decl
);
1094 umsg_decl
= builtin_function (TAG_MSGSEND
, temp_type
, 0, NOT_BUILT_IN
,
1097 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1100 = build_function_type (id_type
,
1101 tree_cons (NULL_TREE
, super_p
,
1102 tree_cons (NULL_TREE
, selector_type
,
1105 umsg_super_decl
= builtin_function (TAG_MSGSENDSUPER
,
1106 temp_type
, 0, NOT_BUILT_IN
,
1109 /* id objc_getClass (const char *); */
1111 temp_type
= build_function_type (id_type
,
1112 tree_cons (NULL_TREE
,
1113 const_string_type_node
,
1114 tree_cons (NULL_TREE
, void_type_node
,
1118 = builtin_function (TAG_GETCLASS
, temp_type
, 0, NOT_BUILT_IN
,
1121 /* id objc_getMetaClass (const char *); */
1123 objc_get_meta_class_decl
1124 = builtin_function (TAG_GETMETACLASS
, temp_type
, 0, NOT_BUILT_IN
,
1127 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1129 if (! flag_next_runtime
)
1131 if (flag_typed_selectors
)
1133 /* Suppress outputting debug symbols, because
1134 dbxout_init hasn'r been called yet. */
1135 enum debug_info_type save_write_symbols
= write_symbols
;
1136 const struct gcc_debug_hooks
*const save_hooks
= debug_hooks
;
1137 write_symbols
= NO_DEBUG
;
1138 debug_hooks
= &do_nothing_debug_hooks
;
1140 build_selector_template ();
1141 temp_type
= build_array_type (objc_selector_template
, NULL_TREE
);
1143 write_symbols
= save_write_symbols
;
1144 debug_hooks
= save_hooks
;
1147 temp_type
= build_array_type (selector_type
, NULL_TREE
);
1149 layout_type (temp_type
);
1150 UOBJC_SELECTOR_TABLE_decl
1151 = create_builtin_decl (VAR_DECL
, temp_type
,
1152 "_OBJC_SELECTOR_TABLE");
1154 /* Avoid warning when not sending messages. */
1155 TREE_USED (UOBJC_SELECTOR_TABLE_decl
) = 1;
1158 generate_forward_declaration_to_string_table ();
1160 /* Forward declare constant_string_id and constant_string_type. */
1161 if (!constant_string_class_name
)
1162 constant_string_class_name
= default_constant_string_class_name
;
1164 constant_string_id
= get_identifier (constant_string_class_name
);
1165 constant_string_type
= xref_tag (RECORD_TYPE
, constant_string_id
);
1168 /* Predefine the following data type:
1170 struct STRING_OBJECT_CLASS_NAME
1174 unsigned int length;
1178 build_string_class_template ()
1180 tree field_decl
, field_decl_chain
;
1182 field_decl
= create_builtin_decl (FIELD_DECL
, id_type
, "isa");
1183 field_decl_chain
= field_decl
;
1185 field_decl
= create_builtin_decl (FIELD_DECL
,
1186 build_pointer_type (char_type_node
),
1188 chainon (field_decl_chain
, field_decl
);
1190 field_decl
= create_builtin_decl (FIELD_DECL
, unsigned_type_node
, "length");
1191 chainon (field_decl_chain
, field_decl
);
1193 finish_struct (constant_string_type
, field_decl_chain
, NULL_TREE
);
1196 /* Custom build_string which sets TREE_TYPE! */
1199 my_build_string (len
, str
)
1203 return fix_string_type (build_string (len
, str
));
1206 /* Given a chain of STRING_CST's, build a static instance of
1207 NXConstantString which points at the concatenation of those strings.
1208 We place the string object in the __string_objects section of the
1209 __OBJC segment. The Objective-C runtime will initialize the isa
1210 pointers of the string objects to point at the NXConstantString
1214 build_objc_string_object (strings
)
1217 tree string
, initlist
, constructor
;
1220 if (lookup_interface (constant_string_id
) == NULL_TREE
)
1222 error ("cannot find interface declaration for `%s'",
1223 IDENTIFIER_POINTER (constant_string_id
));
1224 return error_mark_node
;
1227 add_class_reference (constant_string_id
);
1229 if (TREE_CHAIN (strings
))
1231 varray_type vstrings
;
1232 VARRAY_TREE_INIT (vstrings
, 32, "strings");
1234 for (; strings
; strings
= TREE_CHAIN (strings
))
1235 VARRAY_PUSH_TREE (vstrings
, strings
);
1237 string
= combine_strings (vstrings
);
1242 string
= fix_string_type (string
);
1244 TREE_SET_CODE (string
, STRING_CST
);
1245 length
= TREE_STRING_LENGTH (string
) - 1;
1247 /* We could not properly create NXConstantString in synth_module_prologue,
1248 because that's called before debugging is initialized. Do it now. */
1249 if (TYPE_FIELDS (constant_string_type
) == NULL_TREE
)
1250 build_string_class_template ();
1252 /* & ((NXConstantString) { NULL, string, length }) */
1254 if (flag_next_runtime
)
1256 /* For the NeXT runtime, we can generate a literal reference
1257 to the string class, don't need to run a constructor. */
1258 setup_string_decl ();
1259 if (string_class_decl
== NULL_TREE
)
1261 error ("cannot find reference tag for class `%s'",
1262 IDENTIFIER_POINTER (constant_string_id
));
1263 return error_mark_node
;
1265 initlist
= build_tree_list
1267 copy_node (build_unary_op (ADDR_EXPR
, string_class_decl
, 0)));
1271 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1275 = tree_cons (NULL_TREE
, copy_node (build_unary_op (ADDR_EXPR
, string
, 1)),
1277 initlist
= tree_cons (NULL_TREE
, build_int_2 (length
, 0), initlist
);
1278 constructor
= build_constructor (constant_string_type
, nreverse (initlist
));
1280 if (!flag_next_runtime
)
1283 = objc_add_static_instance (constructor
, constant_string_type
);
1286 return (build_unary_op (ADDR_EXPR
, constructor
, 1));
1289 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1292 objc_add_static_instance (constructor
, class_decl
)
1293 tree constructor
, class_decl
;
1295 static int num_static_inst
;
1299 /* Find the list of static instances for the CLASS_DECL. Create one if
1301 for (chain
= &objc_static_instances
;
1302 *chain
&& TREE_VALUE (*chain
) != class_decl
;
1303 chain
= &TREE_CHAIN (*chain
));
1306 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
1307 add_objc_string (TYPE_NAME (class_decl
), class_names
);
1310 sprintf (buf
, "_OBJC_INSTANCE_%d", num_static_inst
++);
1311 decl
= build_decl (VAR_DECL
, get_identifier (buf
), class_decl
);
1312 DECL_COMMON (decl
) = 1;
1313 TREE_STATIC (decl
) = 1;
1314 DECL_ARTIFICIAL (decl
) = 1;
1315 DECL_INITIAL (decl
) = constructor
;
1317 /* We may be writing something else just now.
1318 Postpone till end of input. */
1319 DECL_DEFER_OUTPUT (decl
) = 1;
1320 pushdecl_top_level (decl
);
1321 rest_of_decl_compilation (decl
, 0, 1, 0);
1323 /* Add the DECL to the head of this CLASS' list. */
1324 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
1329 /* Build a static constant CONSTRUCTOR
1330 with type TYPE and elements ELTS. */
1333 build_constructor (type
, elts
)
1336 tree constructor
, f
, e
;
1338 /* ??? Most of the places that we build constructors, we don't fill in
1339 the type of integers properly. Convert them all en masse. */
1340 if (TREE_CODE (type
) == ARRAY_TYPE
)
1342 f
= TREE_TYPE (type
);
1343 if (TREE_CODE (f
) == POINTER_TYPE
|| TREE_CODE (f
) == INTEGER_TYPE
)
1344 for (e
= elts
; e
; e
= TREE_CHAIN (e
))
1345 TREE_VALUE (e
) = convert (f
, TREE_VALUE (e
));
1349 f
= TYPE_FIELDS (type
);
1350 for (e
= elts
; e
; e
= TREE_CHAIN (e
), f
= TREE_CHAIN (f
))
1351 if (TREE_CODE (TREE_TYPE (f
)) == POINTER_TYPE
1352 || TREE_CODE (TREE_TYPE (f
)) == INTEGER_TYPE
)
1353 TREE_VALUE (e
) = convert (TREE_TYPE (f
), TREE_VALUE (e
));
1356 constructor
= build (CONSTRUCTOR
, type
, NULL_TREE
, elts
);
1357 TREE_CONSTANT (constructor
) = 1;
1358 TREE_STATIC (constructor
) = 1;
1359 TREE_READONLY (constructor
) = 1;
1364 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1366 /* Predefine the following data type:
1374 void *defs[cls_def_cnt + cat_def_cnt];
1378 build_objc_symtab_template ()
1380 tree field_decl
, field_decl_chain
, index
;
1382 objc_symtab_template
1383 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SYMTAB
));
1385 /* long sel_ref_cnt; */
1387 field_decl
= create_builtin_decl (FIELD_DECL
,
1388 long_integer_type_node
,
1390 field_decl_chain
= field_decl
;
1394 field_decl
= create_builtin_decl (FIELD_DECL
,
1395 build_pointer_type (selector_type
),
1397 chainon (field_decl_chain
, field_decl
);
1399 /* short cls_def_cnt; */
1401 field_decl
= create_builtin_decl (FIELD_DECL
,
1402 short_integer_type_node
,
1404 chainon (field_decl_chain
, field_decl
);
1406 /* short cat_def_cnt; */
1408 field_decl
= create_builtin_decl (FIELD_DECL
,
1409 short_integer_type_node
,
1411 chainon (field_decl_chain
, field_decl
);
1413 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1415 if (!flag_next_runtime
)
1416 index
= build_index_type (build_int_2 (imp_count
+ cat_count
, 0));
1418 index
= build_index_type (build_int_2 (imp_count
+ cat_count
- 1,
1419 imp_count
== 0 && cat_count
== 0
1421 field_decl
= create_builtin_decl (FIELD_DECL
,
1422 build_array_type (ptr_type_node
, index
),
1424 chainon (field_decl_chain
, field_decl
);
1426 finish_struct (objc_symtab_template
, field_decl_chain
, NULL_TREE
);
1429 /* Create the initial value for the `defs' field of _objc_symtab.
1430 This is a CONSTRUCTOR. */
1433 init_def_list (type
)
1436 tree expr
, initlist
= NULL_TREE
;
1437 struct imp_entry
*impent
;
1440 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1442 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
1444 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1445 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1450 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1452 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1454 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1455 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1459 if (!flag_next_runtime
)
1461 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1464 if (static_instances_decl
)
1465 expr
= build_unary_op (ADDR_EXPR
, static_instances_decl
, 0);
1467 expr
= build_int_2 (0, 0);
1469 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1472 return build_constructor (type
, nreverse (initlist
));
1475 /* Construct the initial value for all of _objc_symtab. */
1478 init_objc_symtab (type
)
1483 /* sel_ref_cnt = { ..., 5, ... } */
1485 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1487 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1489 if (flag_next_runtime
|| ! sel_ref_chain
)
1490 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1492 initlist
= tree_cons (NULL_TREE
,
1493 build_unary_op (ADDR_EXPR
,
1494 UOBJC_SELECTOR_TABLE_decl
, 1),
1497 /* cls_def_cnt = { ..., 5, ... } */
1499 initlist
= tree_cons (NULL_TREE
, build_int_2 (imp_count
, 0), initlist
);
1501 /* cat_def_cnt = { ..., 5, ... } */
1503 initlist
= tree_cons (NULL_TREE
, build_int_2 (cat_count
, 0), initlist
);
1505 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1507 if (imp_count
|| cat_count
|| static_instances_decl
)
1510 tree field
= TYPE_FIELDS (type
);
1511 field
= TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field
))));
1513 initlist
= tree_cons (NULL_TREE
, init_def_list (TREE_TYPE (field
)),
1517 return build_constructor (type
, nreverse (initlist
));
1520 /* Push forward-declarations of all the categories so that
1521 init_def_list can use them in a CONSTRUCTOR. */
1524 forward_declare_categories ()
1526 struct imp_entry
*impent
;
1527 tree sav
= objc_implementation_context
;
1529 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1531 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1533 /* Set an invisible arg to synth_id_with_class_suffix. */
1534 objc_implementation_context
= impent
->imp_context
;
1536 = create_builtin_decl (VAR_DECL
, objc_category_template
,
1537 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", objc_implementation_context
)));
1540 objc_implementation_context
= sav
;
1543 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1544 and initialized appropriately. */
1547 generate_objc_symtab_decl ()
1551 if (!objc_category_template
)
1552 build_category_template ();
1554 /* forward declare categories */
1556 forward_declare_categories ();
1558 if (!objc_symtab_template
)
1559 build_objc_symtab_template ();
1561 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
1563 UOBJC_SYMBOLS_decl
= start_decl (get_identifier ("_OBJC_SYMBOLS"),
1564 tree_cons (NULL_TREE
,
1565 objc_symtab_template
, sc_spec
),
1569 TREE_USED (UOBJC_SYMBOLS_decl
) = 1;
1570 DECL_IGNORED_P (UOBJC_SYMBOLS_decl
) = 1;
1571 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl
) = 1;
1572 finish_decl (UOBJC_SYMBOLS_decl
,
1573 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)),
1578 init_module_descriptor (type
)
1581 tree initlist
, expr
;
1583 /* version = { 1, ... } */
1585 expr
= build_int_2 (OBJC_VERSION
, 0);
1586 initlist
= build_tree_list (NULL_TREE
, expr
);
1588 /* size = { ..., sizeof (struct objc_module), ... } */
1590 expr
= size_in_bytes (objc_module_template
);
1591 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1593 /* name = { ..., "foo.m", ... } */
1595 expr
= add_objc_string (get_identifier (input_filename
), class_names
);
1596 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1598 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1600 if (UOBJC_SYMBOLS_decl
)
1601 expr
= build_unary_op (ADDR_EXPR
, UOBJC_SYMBOLS_decl
, 0);
1603 expr
= build_int_2 (0, 0);
1604 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1606 return build_constructor (type
, nreverse (initlist
));
1609 /* Write out the data structures to describe Objective C classes defined.
1610 If appropriate, compile and output a setup function to initialize them.
1611 Return a symbol_ref to the function to call to initialize the Objective C
1612 data structures for this file (and perhaps for other files also).
1614 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1617 build_module_descriptor ()
1619 tree decl_specs
, field_decl
, field_decl_chain
;
1621 objc_module_template
1622 = start_struct (RECORD_TYPE
, get_identifier (UTAG_MODULE
));
1626 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1627 field_decl
= get_identifier ("version");
1629 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1630 field_decl_chain
= field_decl
;
1634 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1635 field_decl
= get_identifier ("size");
1637 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1638 chainon (field_decl_chain
, field_decl
);
1642 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
1643 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
1645 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1646 chainon (field_decl_chain
, field_decl
);
1648 /* struct objc_symtab *symtab; */
1650 decl_specs
= get_identifier (UTAG_SYMTAB
);
1651 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
1652 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("symtab"));
1654 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1655 chainon (field_decl_chain
, field_decl
);
1657 finish_struct (objc_module_template
, field_decl_chain
, NULL_TREE
);
1659 /* Create an instance of "objc_module". */
1661 decl_specs
= tree_cons (NULL_TREE
, objc_module_template
,
1662 build_tree_list (NULL_TREE
,
1663 ridpointers
[(int) RID_STATIC
]));
1665 UOBJC_MODULES_decl
= start_decl (get_identifier ("_OBJC_MODULES"),
1666 decl_specs
, 1, NULL_TREE
);
1668 DECL_ARTIFICIAL (UOBJC_MODULES_decl
) = 1;
1669 DECL_IGNORED_P (UOBJC_MODULES_decl
) = 1;
1670 DECL_CONTEXT (UOBJC_MODULES_decl
) = NULL_TREE
;
1672 finish_decl (UOBJC_MODULES_decl
,
1673 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl
)),
1676 /* Mark the decl to avoid "defined but not used" warning. */
1677 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl
) = 1;
1679 /* Generate a constructor call for the module descriptor.
1680 This code was generated by reading the grammar rules
1681 of c-parse.in; Therefore, it may not be the most efficient
1682 way of generating the requisite code. */
1684 if (flag_next_runtime
)
1688 tree parms
, execclass_decl
, decelerator
, void_list_node_1
;
1689 tree init_function_name
, init_function_decl
;
1691 /* Declare void __objc_execClass (void *); */
1693 void_list_node_1
= build_tree_list (NULL_TREE
, void_type_node
);
1694 execclass_decl
= build_decl (FUNCTION_DECL
,
1695 get_identifier (TAG_EXECCLASS
),
1696 build_function_type (void_type_node
,
1697 tree_cons (NULL_TREE
, ptr_type_node
,
1698 void_list_node_1
)));
1699 DECL_EXTERNAL (execclass_decl
) = 1;
1700 DECL_ARTIFICIAL (execclass_decl
) = 1;
1701 TREE_PUBLIC (execclass_decl
) = 1;
1702 pushdecl (execclass_decl
);
1703 rest_of_decl_compilation (execclass_decl
, 0, 0, 0);
1704 assemble_external (execclass_decl
);
1706 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1708 init_function_name
= get_file_function_name ('I');
1709 start_function (void_list_node_1
,
1710 build_nt (CALL_EXPR
, init_function_name
,
1711 tree_cons (NULL_TREE
, NULL_TREE
,
1715 store_parm_decls ();
1717 init_function_decl
= current_function_decl
;
1718 TREE_PUBLIC (init_function_decl
) = ! targetm
.have_ctors_dtors
;
1719 TREE_USED (init_function_decl
) = 1;
1720 /* Don't let this one be deferred. */
1721 DECL_INLINE (init_function_decl
) = 0;
1722 DECL_UNINLINABLE (init_function_decl
) = 1;
1723 current_function_cannot_inline
1724 = "static constructors and destructors cannot be inlined";
1727 = build_tree_list (NULL_TREE
,
1728 build_unary_op (ADDR_EXPR
, UOBJC_MODULES_decl
, 0));
1729 decelerator
= build_function_call (execclass_decl
, parms
);
1731 c_expand_expr_stmt (decelerator
);
1733 finish_function (0, 0);
1735 return XEXP (DECL_RTL (init_function_decl
), 0);
1739 /* extern const char _OBJC_STRINGS[]; */
1742 generate_forward_declaration_to_string_table ()
1744 tree sc_spec
, decl_specs
, expr_decl
;
1746 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_EXTERN
], NULL_TREE
);
1747 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1750 = build_nt (ARRAY_REF
, get_identifier ("_OBJC_STRINGS"), NULL_TREE
);
1752 UOBJC_STRINGS_decl
= define_decl (expr_decl
, decl_specs
);
1755 /* Return the DECL of the string IDENT in the SECTION. */
1758 get_objc_string_decl (ident
, section
)
1760 enum string_section section
;
1764 if (section
== class_names
)
1765 chain
= class_names_chain
;
1766 else if (section
== meth_var_names
)
1767 chain
= meth_var_names_chain
;
1768 else if (section
== meth_var_types
)
1769 chain
= meth_var_types_chain
;
1773 for (; chain
!= 0; chain
= TREE_VALUE (chain
))
1774 if (TREE_VALUE (chain
) == ident
)
1775 return (TREE_PURPOSE (chain
));
1781 /* Output references to all statically allocated objects. Return the DECL
1782 for the array built. */
1785 generate_static_references ()
1787 tree decls
= NULL_TREE
, ident
, decl_spec
, expr_decl
, expr
= NULL_TREE
;
1788 tree class_name
, class, decl
, initlist
;
1789 tree cl_chain
, in_chain
, type
;
1790 int num_inst
, num_class
;
1793 if (flag_next_runtime
)
1796 for (cl_chain
= objc_static_instances
, num_class
= 0;
1797 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
1799 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
1800 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
1802 sprintf (buf
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
1803 ident
= get_identifier (buf
);
1805 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1806 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1807 build_tree_list (NULL_TREE
,
1808 ridpointers
[(int) RID_STATIC
]));
1809 decl
= start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
);
1810 DECL_CONTEXT (decl
) = 0;
1811 DECL_ARTIFICIAL (decl
) = 1;
1813 /* Output {class_name, ...}. */
1814 class = TREE_VALUE (cl_chain
);
1815 class_name
= get_objc_string_decl (TYPE_NAME (class), class_names
);
1816 initlist
= build_tree_list (NULL_TREE
,
1817 build_unary_op (ADDR_EXPR
, class_name
, 1));
1819 /* Output {..., instance, ...}. */
1820 for (in_chain
= TREE_PURPOSE (cl_chain
);
1821 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
1823 expr
= build_unary_op (ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
1824 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1827 /* Output {..., NULL}. */
1828 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1830 expr
= build_constructor (TREE_TYPE (decl
), nreverse (initlist
));
1831 finish_decl (decl
, expr
, NULL_TREE
);
1832 TREE_USED (decl
) = 1;
1834 type
= build_array_type (build_pointer_type (void_type_node
), 0);
1835 decl
= build_decl (VAR_DECL
, ident
, type
);
1836 TREE_USED (decl
) = 1;
1837 TREE_STATIC (decl
) = 1;
1839 = tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, decl
, 1), decls
);
1842 decls
= tree_cons (NULL_TREE
, build_int_2 (0, 0), decls
);
1843 ident
= get_identifier ("_OBJC_STATIC_INSTANCES");
1844 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1845 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1846 build_tree_list (NULL_TREE
,
1847 ridpointers
[(int) RID_STATIC
]));
1848 static_instances_decl
1849 = start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
);
1850 TREE_USED (static_instances_decl
) = 1;
1851 DECL_CONTEXT (static_instances_decl
) = 0;
1852 DECL_ARTIFICIAL (static_instances_decl
) = 1;
1853 expr
= build_constructor (TREE_TYPE (static_instances_decl
),
1855 finish_decl (static_instances_decl
, expr
, NULL_TREE
);
1858 /* Output all strings. */
1863 tree sc_spec
, decl_specs
, expr_decl
;
1864 tree chain
, string_expr
;
1867 for (chain
= class_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1869 string
= TREE_VALUE (chain
);
1870 decl
= TREE_PURPOSE (chain
);
1872 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1873 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1874 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1875 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1876 DECL_CONTEXT (decl
) = NULL_TREE
;
1877 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1878 IDENTIFIER_POINTER (string
));
1879 finish_decl (decl
, string_expr
, NULL_TREE
);
1882 for (chain
= meth_var_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1884 string
= TREE_VALUE (chain
);
1885 decl
= TREE_PURPOSE (chain
);
1887 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1888 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1889 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1890 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1891 DECL_CONTEXT (decl
) = NULL_TREE
;
1892 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1893 IDENTIFIER_POINTER (string
));
1894 finish_decl (decl
, string_expr
, NULL_TREE
);
1897 for (chain
= meth_var_types_chain
; chain
; chain
= TREE_CHAIN (chain
))
1899 string
= TREE_VALUE (chain
);
1900 decl
= TREE_PURPOSE (chain
);
1902 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1903 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1904 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1905 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1906 DECL_CONTEXT (decl
) = NULL_TREE
;
1907 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1908 IDENTIFIER_POINTER (string
));
1909 finish_decl (decl
, string_expr
, NULL_TREE
);
1914 build_selector_reference_decl ()
1920 sprintf (buf
, "_OBJC_SELECTOR_REFERENCES_%d", idx
++);
1922 ident
= get_identifier (buf
);
1924 decl
= build_decl (VAR_DECL
, ident
, selector_type
);
1925 DECL_EXTERNAL (decl
) = 1;
1926 TREE_PUBLIC (decl
) = 1;
1927 TREE_USED (decl
) = 1;
1928 TREE_READONLY (decl
) = 1;
1929 DECL_ARTIFICIAL (decl
) = 1;
1930 DECL_CONTEXT (decl
) = 0;
1932 make_decl_rtl (decl
, 0);
1933 pushdecl_top_level (decl
);
1938 /* Just a handy wrapper for add_objc_string. */
1941 build_selector (ident
)
1944 tree expr
= add_objc_string (ident
, meth_var_names
);
1945 if (flag_typed_selectors
)
1948 return build_c_cast (selector_type
, expr
); /* cast! */
1952 build_selector_translation_table ()
1954 tree sc_spec
, decl_specs
;
1955 tree chain
, initlist
= NULL_TREE
;
1957 tree decl
= NULL_TREE
, var_decl
, name
;
1959 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
1963 expr
= build_selector (TREE_VALUE (chain
));
1965 if (flag_next_runtime
)
1967 name
= DECL_NAME (TREE_PURPOSE (chain
));
1969 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
1971 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
1972 decl_specs
= tree_cons (NULL_TREE
, selector_type
, sc_spec
);
1976 /* The `decl' that is returned from start_decl is the one that we
1977 forward declared in `build_selector_reference' */
1978 decl
= start_decl (var_decl
, decl_specs
, 1, NULL_TREE
);
1981 /* add one for the '\0' character */
1982 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (chain
)) + 1;
1984 if (flag_next_runtime
)
1985 finish_decl (decl
, expr
, NULL_TREE
);
1988 if (flag_typed_selectors
)
1990 tree eltlist
= NULL_TREE
;
1991 tree encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
1992 eltlist
= tree_cons (NULL_TREE
, expr
, NULL_TREE
);
1993 eltlist
= tree_cons (NULL_TREE
, encoding
, eltlist
);
1994 expr
= build_constructor (objc_selector_template
,
1995 nreverse (eltlist
));
1997 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2002 if (! flag_next_runtime
)
2004 /* Cause the variable and its initial value to be actually output. */
2005 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl
) = 0;
2006 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl
) = 1;
2007 /* NULL terminate the list and fix the decl for output. */
2008 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
2009 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl
) = objc_ellipsis_node
;
2010 initlist
= build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
2011 nreverse (initlist
));
2012 finish_decl (UOBJC_SELECTOR_TABLE_decl
, initlist
, NULL_TREE
);
2013 current_function_decl
= NULL_TREE
;
2018 get_proto_encoding (proto
)
2026 if (! METHOD_ENCODING (proto
))
2028 tmp_decl
= build_tmp_function_decl ();
2029 hack_method_prototype (proto
, tmp_decl
);
2030 encoding
= encode_method_prototype (proto
, tmp_decl
);
2031 METHOD_ENCODING (proto
) = encoding
;
2034 encoding
= METHOD_ENCODING (proto
);
2036 return add_objc_string (encoding
, meth_var_types
);
2039 return build_int_2 (0, 0);
2042 /* sel_ref_chain is a list whose "value" fields will be instances of
2043 identifier_node that represent the selector. */
2046 build_typed_selector_reference (ident
, proto
)
2049 tree
*chain
= &sel_ref_chain
;
2055 if (TREE_PURPOSE (*chain
) == ident
&& TREE_VALUE (*chain
) == proto
)
2056 goto return_at_index
;
2059 chain
= &TREE_CHAIN (*chain
);
2062 *chain
= tree_cons (proto
, ident
, NULL_TREE
);
2065 expr
= build_unary_op (ADDR_EXPR
,
2066 build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2067 build_int_2 (index
, 0)),
2069 return build_c_cast (selector_type
, expr
);
2073 build_selector_reference (ident
)
2076 tree
*chain
= &sel_ref_chain
;
2082 if (TREE_VALUE (*chain
) == ident
)
2083 return (flag_next_runtime
2084 ? TREE_PURPOSE (*chain
)
2085 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2086 build_int_2 (index
, 0)));
2089 chain
= &TREE_CHAIN (*chain
);
2092 expr
= build_selector_reference_decl ();
2094 *chain
= tree_cons (expr
, ident
, NULL_TREE
);
2096 return (flag_next_runtime
2098 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2099 build_int_2 (index
, 0)));
2103 build_class_reference_decl ()
2109 sprintf (buf
, "_OBJC_CLASS_REFERENCES_%d", idx
++);
2111 ident
= get_identifier (buf
);
2113 decl
= build_decl (VAR_DECL
, ident
, objc_class_type
);
2114 DECL_EXTERNAL (decl
) = 1;
2115 TREE_PUBLIC (decl
) = 1;
2116 TREE_USED (decl
) = 1;
2117 TREE_READONLY (decl
) = 1;
2118 DECL_CONTEXT (decl
) = 0;
2119 DECL_ARTIFICIAL (decl
) = 1;
2121 make_decl_rtl (decl
, 0);
2122 pushdecl_top_level (decl
);
2127 /* Create a class reference, but don't create a variable to reference
2131 add_class_reference (ident
)
2136 if ((chain
= cls_ref_chain
))
2141 if (ident
== TREE_VALUE (chain
))
2145 chain
= TREE_CHAIN (chain
);
2149 /* Append to the end of the list */
2150 TREE_CHAIN (tail
) = tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2153 cls_ref_chain
= tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2156 /* Get a class reference, creating it if necessary. Also create the
2157 reference variable. */
2160 get_class_reference (ident
)
2163 if (flag_next_runtime
)
2168 for (chain
= &cls_ref_chain
; *chain
; chain
= &TREE_CHAIN (*chain
))
2169 if (TREE_VALUE (*chain
) == ident
)
2171 if (! TREE_PURPOSE (*chain
))
2172 TREE_PURPOSE (*chain
) = build_class_reference_decl ();
2174 return TREE_PURPOSE (*chain
);
2177 decl
= build_class_reference_decl ();
2178 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2185 add_class_reference (ident
);
2187 params
= build_tree_list (NULL_TREE
,
2188 my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
2189 IDENTIFIER_POINTER (ident
)));
2191 assemble_external (objc_get_class_decl
);
2192 return build_function_call (objc_get_class_decl
, params
);
2196 /* For each string section we have a chain which maps identifier nodes
2197 to decls for the strings. */
2200 add_objc_string (ident
, section
)
2202 enum string_section section
;
2206 if (section
== class_names
)
2207 chain
= &class_names_chain
;
2208 else if (section
== meth_var_names
)
2209 chain
= &meth_var_names_chain
;
2210 else if (section
== meth_var_types
)
2211 chain
= &meth_var_types_chain
;
2217 if (TREE_VALUE (*chain
) == ident
)
2218 return build_unary_op (ADDR_EXPR
, TREE_PURPOSE (*chain
), 1);
2220 chain
= &TREE_CHAIN (*chain
);
2223 decl
= build_objc_string_decl (section
);
2225 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2227 return build_unary_op (ADDR_EXPR
, decl
, 1);
2231 build_objc_string_decl (section
)
2232 enum string_section section
;
2236 static int class_names_idx
= 0;
2237 static int meth_var_names_idx
= 0;
2238 static int meth_var_types_idx
= 0;
2240 if (section
== class_names
)
2241 sprintf (buf
, "_OBJC_CLASS_NAME_%d", class_names_idx
++);
2242 else if (section
== meth_var_names
)
2243 sprintf (buf
, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx
++);
2244 else if (section
== meth_var_types
)
2245 sprintf (buf
, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx
++);
2247 ident
= get_identifier (buf
);
2249 decl
= build_decl (VAR_DECL
, ident
, build_array_type (char_type_node
, 0));
2250 DECL_EXTERNAL (decl
) = 1;
2251 TREE_PUBLIC (decl
) = 1;
2252 TREE_USED (decl
) = 1;
2253 TREE_READONLY (decl
) = 1;
2254 TREE_CONSTANT (decl
) = 1;
2255 DECL_CONTEXT (decl
) = 0;
2256 DECL_ARTIFICIAL (decl
) = 1;
2258 make_decl_rtl (decl
, 0);
2259 pushdecl_top_level (decl
);
2266 objc_declare_alias (alias_ident
, class_ident
)
2270 if (is_class_name (class_ident
) != class_ident
)
2271 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident
));
2272 else if (is_class_name (alias_ident
))
2273 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident
));
2275 alias_chain
= tree_cons (class_ident
, alias_ident
, alias_chain
);
2279 objc_declare_class (ident_list
)
2284 for (list
= ident_list
; list
; list
= TREE_CHAIN (list
))
2286 tree ident
= TREE_VALUE (list
);
2289 if ((decl
= lookup_name (ident
)))
2291 error ("`%s' redeclared as different kind of symbol",
2292 IDENTIFIER_POINTER (ident
));
2293 error_with_decl (decl
, "previous declaration of `%s'");
2296 if (! is_class_name (ident
))
2298 tree record
= xref_tag (RECORD_TYPE
, ident
);
2299 TREE_STATIC_TEMPLATE (record
) = 1;
2300 class_chain
= tree_cons (NULL_TREE
, ident
, class_chain
);
2306 is_class_name (ident
)
2311 if (lookup_interface (ident
))
2314 for (chain
= class_chain
; chain
; chain
= TREE_CHAIN (chain
))
2316 if (ident
== TREE_VALUE (chain
))
2320 for (chain
= alias_chain
; chain
; chain
= TREE_CHAIN (chain
))
2322 if (ident
== TREE_VALUE (chain
))
2323 return TREE_PURPOSE (chain
);
2330 lookup_interface (ident
)
2335 for (chain
= interface_chain
; chain
; chain
= TREE_CHAIN (chain
))
2337 if (ident
== CLASS_NAME (chain
))
2344 objc_copy_list (list
, head
)
2348 tree newlist
= NULL_TREE
, tail
= NULL_TREE
;
2352 tail
= copy_node (list
);
2354 /* The following statement fixes a bug when inheriting instance
2355 variables that are declared to be bitfields. finish_struct
2356 expects to find the width of the bitfield in DECL_INITIAL. */
2357 if (DECL_BIT_FIELD (tail
) && DECL_INITIAL (tail
) == 0)
2358 DECL_INITIAL (tail
) = DECL_SIZE (tail
);
2360 newlist
= chainon (newlist
, tail
);
2361 list
= TREE_CHAIN (list
);
2368 /* Used by: build_private_template, get_class_ivars, and
2369 continue_class. COPY is 1 when called from @defs. In this case
2370 copy all fields. Otherwise don't copy leaf ivars since we rely on
2371 them being side-effected exactly once by finish_struct. */
2374 build_ivar_chain (interface
, copy
)
2378 tree my_name
, super_name
, ivar_chain
;
2380 my_name
= CLASS_NAME (interface
);
2381 super_name
= CLASS_SUPER_NAME (interface
);
2383 /* Possibly copy leaf ivars. */
2385 objc_copy_list (CLASS_IVARS (interface
), &ivar_chain
);
2387 ivar_chain
= CLASS_IVARS (interface
);
2392 tree super_interface
= lookup_interface (super_name
);
2394 if (!super_interface
)
2396 /* fatal did not work with 2 args...should fix */
2397 error ("cannot find interface declaration for `%s', superclass of `%s'",
2398 IDENTIFIER_POINTER (super_name
),
2399 IDENTIFIER_POINTER (my_name
));
2400 exit (FATAL_EXIT_CODE
);
2403 if (super_interface
== interface
)
2404 fatal_error ("circular inheritance in interface declaration for `%s'",
2405 IDENTIFIER_POINTER (super_name
));
2407 interface
= super_interface
;
2408 my_name
= CLASS_NAME (interface
);
2409 super_name
= CLASS_SUPER_NAME (interface
);
2411 op1
= CLASS_IVARS (interface
);
2414 tree head
, tail
= objc_copy_list (op1
, &head
);
2416 /* Prepend super class ivars...make a copy of the list, we
2417 do not want to alter the original. */
2418 TREE_CHAIN (tail
) = ivar_chain
;
2425 /* struct <classname> {
2426 struct objc_class *isa;
2431 build_private_template (class)
2436 if (CLASS_STATIC_TEMPLATE (class))
2438 uprivate_record
= CLASS_STATIC_TEMPLATE (class);
2439 ivar_context
= TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2443 uprivate_record
= start_struct (RECORD_TYPE
, CLASS_NAME (class));
2445 ivar_context
= build_ivar_chain (class, 0);
2447 finish_struct (uprivate_record
, ivar_context
, NULL_TREE
);
2449 CLASS_STATIC_TEMPLATE (class) = uprivate_record
;
2451 /* mark this record as class template - for class type checking */
2452 TREE_STATIC_TEMPLATE (uprivate_record
) = 1;
2456 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
2458 build1 (INDIRECT_REF
, NULL_TREE
,
2461 return ivar_context
;
2464 /* Begin code generation for protocols... */
2466 /* struct objc_protocol {
2467 char *protocol_name;
2468 struct objc_protocol **protocol_list;
2469 struct objc_method_desc *instance_methods;
2470 struct objc_method_desc *class_methods;
2474 build_protocol_template ()
2476 tree decl_specs
, field_decl
, field_decl_chain
;
2479 template = start_struct (RECORD_TYPE
, get_identifier (UTAG_PROTOCOL
));
2481 /* struct objc_class *isa; */
2483 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2484 get_identifier (UTAG_CLASS
)));
2485 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
2487 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2488 field_decl_chain
= field_decl
;
2490 /* char *protocol_name; */
2492 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
2494 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_name"));
2496 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2497 chainon (field_decl_chain
, field_decl
);
2499 /* struct objc_protocol **protocol_list; */
2501 decl_specs
= build_tree_list (NULL_TREE
, template);
2503 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
2504 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
2506 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2507 chainon (field_decl_chain
, field_decl
);
2509 /* struct objc_method_list *instance_methods; */
2512 = build_tree_list (NULL_TREE
,
2513 xref_tag (RECORD_TYPE
,
2514 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2516 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
2518 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2519 chainon (field_decl_chain
, field_decl
);
2521 /* struct objc_method_list *class_methods; */
2524 = build_tree_list (NULL_TREE
,
2525 xref_tag (RECORD_TYPE
,
2526 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2528 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
2530 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2531 chainon (field_decl_chain
, field_decl
);
2533 return finish_struct (template, field_decl_chain
, NULL_TREE
);
2537 build_descriptor_table_initializer (type
, entries
)
2541 tree initlist
= NULL_TREE
;
2545 tree eltlist
= NULL_TREE
;
2548 = tree_cons (NULL_TREE
,
2549 build_selector (METHOD_SEL_NAME (entries
)), NULL_TREE
);
2551 = tree_cons (NULL_TREE
,
2552 add_objc_string (METHOD_ENCODING (entries
),
2557 = tree_cons (NULL_TREE
,
2558 build_constructor (type
, nreverse (eltlist
)), initlist
);
2560 entries
= TREE_CHAIN (entries
);
2564 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
2567 /* struct objc_method_prototype_list {
2569 struct objc_method_prototype {
2576 build_method_prototype_list_template (list_type
, size
)
2580 tree objc_ivar_list_record
;
2581 tree decl_specs
, field_decl
, field_decl_chain
;
2583 /* Generate an unnamed struct definition. */
2585 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
2587 /* int method_count; */
2589 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
2590 field_decl
= get_identifier ("method_count");
2593 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2594 field_decl_chain
= field_decl
;
2596 /* struct objc_method method_list[]; */
2598 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
2599 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
2600 build_int_2 (size
, 0));
2603 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2604 chainon (field_decl_chain
, field_decl
);
2606 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
2608 return objc_ivar_list_record
;
2612 build_method_prototype_template ()
2615 tree decl_specs
, field_decl
, field_decl_chain
;
2618 = start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD_PROTOTYPE
));
2620 /* struct objc_selector *_cmd; */
2621 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
2622 get_identifier (TAG_SELECTOR
)), NULL_TREE
);
2623 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
2626 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2627 field_decl_chain
= field_decl
;
2629 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
2631 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_types"));
2633 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2634 chainon (field_decl_chain
, field_decl
);
2636 finish_struct (proto_record
, field_decl_chain
, NULL_TREE
);
2638 return proto_record
;
2641 /* True if last call to forwarding_offset yielded a register offset. */
2642 static int offset_is_register
;
2645 forwarding_offset (parm
)
2648 int offset_in_bytes
;
2650 if (GET_CODE (DECL_INCOMING_RTL (parm
)) == MEM
)
2652 rtx addr
= XEXP (DECL_INCOMING_RTL (parm
), 0);
2654 /* ??? Here we assume that the parm address is indexed
2655 off the frame pointer or arg pointer.
2656 If that is not true, we produce meaningless results,
2657 but do not crash. */
2658 if (GET_CODE (addr
) == PLUS
2659 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
2660 offset_in_bytes
= INTVAL (XEXP (addr
, 1));
2662 offset_in_bytes
= 0;
2664 offset_in_bytes
+= OBJC_FORWARDING_STACK_OFFSET
;
2665 offset_is_register
= 0;
2667 else if (GET_CODE (DECL_INCOMING_RTL (parm
)) == REG
)
2669 int regno
= REGNO (DECL_INCOMING_RTL (parm
));
2670 offset_in_bytes
= apply_args_register_offset (regno
);
2671 offset_is_register
= 1;
2676 /* This is the case where the parm is passed as an int or double
2677 and it is converted to a char, short or float and stored back
2678 in the parmlist. In this case, describe the parm
2679 with the variable's declared type, and adjust the address
2680 if the least significant bytes (which we are using) are not
2682 if (BYTES_BIG_ENDIAN
&& TREE_TYPE (parm
) != DECL_ARG_TYPE (parm
))
2683 offset_in_bytes
+= (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm
)))
2684 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm
))));
2686 return offset_in_bytes
;
2690 encode_method_prototype (method_decl
, func_decl
)
2697 HOST_WIDE_INT max_parm_end
= 0;
2701 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2702 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl
)));
2705 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
2706 obstack_object_size (&util_obstack
),
2707 OBJC_ENCODE_INLINE_DEFS
);
2710 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
2711 parms
= TREE_CHAIN (parms
))
2713 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
2714 + int_size_in_bytes (TREE_TYPE (parms
)));
2716 if (!offset_is_register
&& max_parm_end
< parm_end
)
2717 max_parm_end
= parm_end
;
2720 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
2722 sprintf (buf
, "%d", stack_size
);
2723 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2725 user_args
= METHOD_SEL_ARGS (method_decl
);
2727 /* Argument types. */
2728 for (parms
= DECL_ARGUMENTS (func_decl
), i
= 0; parms
;
2729 parms
= TREE_CHAIN (parms
), i
++)
2731 /* Process argument qualifiers for user supplied arguments. */
2734 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args
)));
2735 user_args
= TREE_CHAIN (user_args
);
2739 encode_type (TREE_TYPE (parms
),
2740 obstack_object_size (&util_obstack
),
2741 OBJC_ENCODE_INLINE_DEFS
);
2743 /* Compute offset. */
2744 sprintf (buf
, "%d", forwarding_offset (parms
));
2746 /* Indicate register. */
2747 if (offset_is_register
)
2748 obstack_1grow (&util_obstack
, '+');
2750 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2753 obstack_1grow (&util_obstack
, '\0');
2754 result
= get_identifier (obstack_finish (&util_obstack
));
2755 obstack_free (&util_obstack
, util_firstobj
);
2760 generate_descriptor_table (type
, name
, size
, list
, proto
)
2767 tree sc_spec
, decl_specs
, decl
, initlist
;
2769 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2770 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
2772 decl
= start_decl (synth_id_with_class_suffix (name
, proto
),
2773 decl_specs
, 1, NULL_TREE
);
2774 DECL_CONTEXT (decl
) = NULL_TREE
;
2776 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
2777 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
2779 finish_decl (decl
, build_constructor (type
, nreverse (initlist
)),
2786 generate_method_descriptors (protocol
)
2789 tree initlist
, chain
, method_list_template
;
2790 tree cast
, variable_length_type
;
2793 if (!objc_method_prototype_template
)
2794 objc_method_prototype_template
= build_method_prototype_template ();
2796 cast
= build_tree_list (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2797 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
))),
2799 variable_length_type
= groktypename (cast
);
2801 chain
= PROTOCOL_CLS_METHODS (protocol
);
2804 size
= list_length (chain
);
2806 method_list_template
2807 = build_method_prototype_list_template (objc_method_prototype_template
,
2811 = build_descriptor_table_initializer (objc_method_prototype_template
,
2814 UOBJC_CLASS_METHODS_decl
2815 = generate_descriptor_table (method_list_template
,
2816 "_OBJC_PROTOCOL_CLASS_METHODS",
2817 size
, initlist
, protocol
);
2818 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
2821 UOBJC_CLASS_METHODS_decl
= 0;
2823 chain
= PROTOCOL_NST_METHODS (protocol
);
2826 size
= list_length (chain
);
2828 method_list_template
2829 = build_method_prototype_list_template (objc_method_prototype_template
,
2832 = build_descriptor_table_initializer (objc_method_prototype_template
,
2835 UOBJC_INSTANCE_METHODS_decl
2836 = generate_descriptor_table (method_list_template
,
2837 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2838 size
, initlist
, protocol
);
2839 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
2842 UOBJC_INSTANCE_METHODS_decl
= 0;
2845 /* Generate a temporary FUNCTION_DECL node to be used in
2846 hack_method_prototype below. */
2849 build_tmp_function_decl ()
2851 tree decl_specs
, expr_decl
, parms
;
2855 /* struct objc_object *objc_xxx (id, SEL, ...); */
2857 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
2858 push_parm_decl (build_tree_list
2859 (build_tree_list (decl_specs
,
2860 build1 (INDIRECT_REF
, NULL_TREE
,
2864 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2865 get_identifier (TAG_SELECTOR
)));
2866 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
);
2868 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, expr_decl
),
2870 parms
= get_parm_info (0);
2873 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
2874 sprintf (buffer
, "__objc_tmp_%x", xxx
++);
2875 expr_decl
= build_nt (CALL_EXPR
, get_identifier (buffer
), parms
, NULL_TREE
);
2876 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
2878 return define_decl (expr_decl
, decl_specs
);
2881 /* Generate the prototypes for protocol methods. This is used to
2882 generate method encodings for these.
2884 NST_METHODS is the method to generate a _DECL node for TMP_DECL is
2885 a decl node to be used. This is also where the return value is
2889 hack_method_prototype (nst_methods
, tmp_decl
)
2896 /* Hack to avoid problem with static typing of self arg. */
2897 TREE_SET_CODE (nst_methods
, CLASS_METHOD_DECL
);
2898 start_method_def (nst_methods
);
2899 TREE_SET_CODE (nst_methods
, INSTANCE_METHOD_DECL
);
2901 if (METHOD_ADD_ARGS (nst_methods
) == objc_ellipsis_node
)
2902 parms
= get_parm_info (0); /* we have a `, ...' */
2904 parms
= get_parm_info (1); /* place a `void_at_end' */
2906 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2908 /* Usually called from store_parm_decls -> init_function_start. */
2910 DECL_ARGUMENTS (tmp_decl
) = TREE_PURPOSE (parms
);
2912 if (current_function_decl
)
2914 current_function_decl
= tmp_decl
;
2917 /* Code taken from start_function. */
2918 tree restype
= TREE_TYPE (TREE_TYPE (tmp_decl
));
2919 /* Promote the value to int before returning it. */
2920 if (TREE_CODE (restype
) == INTEGER_TYPE
2921 && TYPE_PRECISION (restype
) < TYPE_PRECISION (integer_type_node
))
2922 restype
= integer_type_node
;
2923 DECL_RESULT (tmp_decl
) = build_decl (RESULT_DECL
, 0, restype
);
2926 for (parm
= DECL_ARGUMENTS (tmp_decl
); parm
; parm
= TREE_CHAIN (parm
))
2927 DECL_CONTEXT (parm
) = tmp_decl
;
2929 init_function_start (tmp_decl
, "objc-act", 0);
2931 /* Typically called from expand_function_start for function definitions. */
2932 assign_parms (tmp_decl
);
2934 /* install return type */
2935 TREE_TYPE (TREE_TYPE (tmp_decl
)) = groktypename (TREE_TYPE (nst_methods
));
2937 current_function_decl
= NULL
;
2941 generate_protocol_references (plist
)
2946 /* Forward declare protocols referenced. */
2947 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
2949 tree proto
= TREE_VALUE (lproto
);
2951 if (TREE_CODE (proto
) == PROTOCOL_INTERFACE_TYPE
2952 && PROTOCOL_NAME (proto
))
2954 if (! PROTOCOL_FORWARD_DECL (proto
))
2955 build_protocol_reference (proto
);
2957 if (PROTOCOL_LIST (proto
))
2958 generate_protocol_references (PROTOCOL_LIST (proto
));
2964 generate_protocols ()
2966 tree p
, tmp_decl
, encoding
;
2967 tree sc_spec
, decl_specs
, decl
;
2968 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
2971 tmp_decl
= build_tmp_function_decl ();
2973 if (! objc_protocol_template
)
2974 objc_protocol_template
= build_protocol_template ();
2976 /* If a protocol was directly referenced, pull in indirect references. */
2977 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
2978 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
2979 generate_protocol_references (PROTOCOL_LIST (p
));
2981 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
2983 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
2984 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
2986 /* If protocol wasn't referenced, don't generate any code. */
2987 if (! PROTOCOL_FORWARD_DECL (p
))
2990 /* Make sure we link in the Protocol class. */
2991 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
2995 if (! METHOD_ENCODING (nst_methods
))
2997 hack_method_prototype (nst_methods
, tmp_decl
);
2998 encoding
= encode_method_prototype (nst_methods
, tmp_decl
);
2999 METHOD_ENCODING (nst_methods
) = encoding
;
3001 nst_methods
= TREE_CHAIN (nst_methods
);
3006 if (! METHOD_ENCODING (cls_methods
))
3008 hack_method_prototype (cls_methods
, tmp_decl
);
3009 encoding
= encode_method_prototype (cls_methods
, tmp_decl
);
3010 METHOD_ENCODING (cls_methods
) = encoding
;
3013 cls_methods
= TREE_CHAIN (cls_methods
);
3015 generate_method_descriptors (p
);
3017 if (PROTOCOL_LIST (p
))
3018 refs_decl
= generate_protocol_list (p
);
3022 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3024 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
],
3026 decl_specs
= tree_cons (NULL_TREE
, objc_protocol_template
, sc_spec
);
3028 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
),
3029 decl_specs
, 1, NULL_TREE
);
3031 DECL_CONTEXT (decl
) = NULL_TREE
;
3033 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
3039 (build_tree_list (build_tree_list (NULL_TREE
,
3040 objc_protocol_template
),
3041 build1 (INDIRECT_REF
, NULL_TREE
,
3042 build1 (INDIRECT_REF
, NULL_TREE
,
3045 refs_expr
= build_unary_op (ADDR_EXPR
, refs_decl
, 0);
3046 TREE_TYPE (refs_expr
) = cast_type2
;
3049 refs_expr
= build_int_2 (0, 0);
3051 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3052 by generate_method_descriptors, which is called above. */
3053 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
3054 protocol_name_expr
, refs_expr
,
3055 UOBJC_INSTANCE_METHODS_decl
,
3056 UOBJC_CLASS_METHODS_decl
);
3057 finish_decl (decl
, initlist
, NULL_TREE
);
3059 /* Mark the decl as used to avoid "defined but not used" warning. */
3060 TREE_USED (decl
) = 1;
3065 build_protocol_initializer (type
, protocol_name
, protocol_list
,
3066 instance_methods
, class_methods
)
3070 tree instance_methods
;
3073 tree initlist
= NULL_TREE
, expr
;
3076 cast_type
= groktypename
3078 (build_tree_list (NULL_TREE
,
3079 xref_tag (RECORD_TYPE
,
3080 get_identifier (UTAG_CLASS
))),
3081 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
3083 /* Filling the "isa" in with one allows the runtime system to
3084 detect that the version change...should remove before final release. */
3086 expr
= build_int_2 (PROTOCOL_VERSION
, 0);
3087 TREE_TYPE (expr
) = cast_type
;
3088 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3089 initlist
= tree_cons (NULL_TREE
, protocol_name
, initlist
);
3090 initlist
= tree_cons (NULL_TREE
, protocol_list
, initlist
);
3092 if (!instance_methods
)
3093 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3096 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
3097 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3101 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3104 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
3105 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3108 return build_constructor (type
, nreverse (initlist
));
3111 /* struct objc_category {
3112 char *category_name;
3114 struct objc_method_list *instance_methods;
3115 struct objc_method_list *class_methods;
3116 struct objc_protocol_list *protocols;
3120 build_category_template ()
3122 tree decl_specs
, field_decl
, field_decl_chain
;
3124 objc_category_template
= start_struct (RECORD_TYPE
,
3125 get_identifier (UTAG_CATEGORY
));
3126 /* char *category_name; */
3128 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3130 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("category_name"));
3132 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3133 field_decl_chain
= field_decl
;
3135 /* char *class_name; */
3137 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3138 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_name"));
3140 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3141 chainon (field_decl_chain
, field_decl
);
3143 /* struct objc_method_list *instance_methods; */
3145 decl_specs
= build_tree_list (NULL_TREE
,
3146 xref_tag (RECORD_TYPE
,
3147 get_identifier (UTAG_METHOD_LIST
)));
3149 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
3151 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3152 chainon (field_decl_chain
, field_decl
);
3154 /* struct objc_method_list *class_methods; */
3156 decl_specs
= build_tree_list (NULL_TREE
,
3157 xref_tag (RECORD_TYPE
,
3158 get_identifier (UTAG_METHOD_LIST
)));
3160 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
3162 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3163 chainon (field_decl_chain
, field_decl
);
3165 /* struct objc_protocol **protocol_list; */
3167 decl_specs
= build_tree_list (NULL_TREE
,
3168 xref_tag (RECORD_TYPE
,
3169 get_identifier (UTAG_PROTOCOL
)));
3171 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3172 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3174 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3175 chainon (field_decl_chain
, field_decl
);
3177 finish_struct (objc_category_template
, field_decl_chain
, NULL_TREE
);
3180 /* struct objc_selector {
3186 build_selector_template ()
3189 tree decl_specs
, field_decl
, field_decl_chain
;
3191 objc_selector_template
3192 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SELECTOR
));
3196 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3197 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3199 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3200 field_decl_chain
= field_decl
;
3202 /* char *sel_type; */
3204 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3205 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_type"));
3207 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3208 chainon (field_decl_chain
, field_decl
);
3210 finish_struct (objc_selector_template
, field_decl_chain
, NULL_TREE
);
3213 /* struct objc_class {
3214 struct objc_class *isa;
3215 struct objc_class *super_class;
3220 struct objc_ivar_list *ivars;
3221 struct objc_method_list *methods;
3222 if (flag_next_runtime)
3223 struct objc_cache *cache;
3225 struct sarray *dtable;
3226 struct objc_class *subclass_list;
3227 struct objc_class *sibling_class;
3229 struct objc_protocol_list *protocols;
3230 void *gc_object_type;
3234 build_class_template ()
3236 tree decl_specs
, field_decl
, field_decl_chain
;
3239 = start_struct (RECORD_TYPE
, get_identifier (UTAG_CLASS
));
3241 /* struct objc_class *isa; */
3243 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3244 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
3246 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3247 field_decl_chain
= field_decl
;
3249 /* struct objc_class *super_class; */
3251 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3253 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("super_class"));
3255 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3256 chainon (field_decl_chain
, field_decl
);
3260 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3261 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
3263 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3264 chainon (field_decl_chain
, field_decl
);
3268 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3269 field_decl
= get_identifier ("version");
3271 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3272 chainon (field_decl_chain
, field_decl
);
3276 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3277 field_decl
= get_identifier ("info");
3279 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3280 chainon (field_decl_chain
, field_decl
);
3282 /* long instance_size; */
3284 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3285 field_decl
= get_identifier ("instance_size");
3287 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3288 chainon (field_decl_chain
, field_decl
);
3290 /* struct objc_ivar_list *ivars; */
3292 decl_specs
= build_tree_list (NULL_TREE
,
3293 xref_tag (RECORD_TYPE
,
3294 get_identifier (UTAG_IVAR_LIST
)));
3295 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivars"));
3297 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3298 chainon (field_decl_chain
, field_decl
);
3300 /* struct objc_method_list *methods; */
3302 decl_specs
= build_tree_list (NULL_TREE
,
3303 xref_tag (RECORD_TYPE
,
3304 get_identifier (UTAG_METHOD_LIST
)));
3305 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("methods"));
3307 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3308 chainon (field_decl_chain
, field_decl
);
3310 if (flag_next_runtime
)
3312 /* struct objc_cache *cache; */
3314 decl_specs
= build_tree_list (NULL_TREE
,
3315 xref_tag (RECORD_TYPE
,
3316 get_identifier ("objc_cache")));
3317 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("cache"));
3318 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3319 decl_specs
, NULL_TREE
);
3320 chainon (field_decl_chain
, field_decl
);
3324 /* struct sarray *dtable; */
3326 decl_specs
= build_tree_list (NULL_TREE
,
3327 xref_tag (RECORD_TYPE
,
3328 get_identifier ("sarray")));
3329 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("dtable"));
3330 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3331 decl_specs
, NULL_TREE
);
3332 chainon (field_decl_chain
, field_decl
);
3334 /* struct objc_class *subclass_list; */
3336 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3338 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("subclass_list"));
3339 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3340 decl_specs
, NULL_TREE
);
3341 chainon (field_decl_chain
, field_decl
);
3343 /* struct objc_class *sibling_class; */
3345 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3347 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sibling_class"));
3348 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3349 decl_specs
, NULL_TREE
);
3350 chainon (field_decl_chain
, field_decl
);
3353 /* struct objc_protocol **protocol_list; */
3355 decl_specs
= build_tree_list (NULL_TREE
,
3356 xref_tag (RECORD_TYPE
,
3357 get_identifier (UTAG_PROTOCOL
)));
3359 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3361 = build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3362 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3363 decl_specs
, NULL_TREE
);
3364 chainon (field_decl_chain
, field_decl
);
3368 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3369 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3371 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3372 chainon (field_decl_chain
, field_decl
);
3374 /* void *gc_object_type; */
3376 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3377 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("gc_object_type"));
3379 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3380 chainon (field_decl_chain
, field_decl
);
3382 finish_struct (objc_class_template
, field_decl_chain
, NULL_TREE
);
3385 /* Generate appropriate forward declarations for an implementation. */
3388 synth_forward_declarations ()
3390 tree sc_spec
, decl_specs
, an_id
;
3392 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3394 an_id
= synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context
);
3396 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
3397 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
3398 UOBJC_CLASS_decl
= define_decl (an_id
, decl_specs
);
3399 TREE_USED (UOBJC_CLASS_decl
) = 1;
3400 DECL_ARTIFICIAL (UOBJC_CLASS_decl
) = 1;
3402 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3404 an_id
= synth_id_with_class_suffix ("_OBJC_METACLASS",
3405 objc_implementation_context
);
3407 UOBJC_METACLASS_decl
= define_decl (an_id
, decl_specs
);
3408 TREE_USED (UOBJC_METACLASS_decl
) = 1;
3409 DECL_ARTIFICIAL(UOBJC_METACLASS_decl
) = 1;
3411 /* Pre-build the following entities - for speed/convenience. */
3413 an_id
= get_identifier ("super_class");
3414 ucls_super_ref
= build_component_ref (UOBJC_CLASS_decl
, an_id
);
3415 uucls_super_ref
= build_component_ref (UOBJC_METACLASS_decl
, an_id
);
3419 error_with_ivar (message
, decl
, rawdecl
)
3420 const char *message
;
3424 diagnostic_count_diagnostic (global_dc
, DK_ERROR
);
3426 diagnostic_report_current_function (global_dc
);
3428 error_with_file_and_line (DECL_SOURCE_FILE (decl
),
3429 DECL_SOURCE_LINE (decl
),
3431 message
, gen_declaration (rawdecl
, errbuf
));
3435 #define USERTYPE(t) \
3436 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3437 || TREE_CODE (t) == ENUMERAL_TYPE)
3440 check_ivars (inter
, imp
)
3444 tree intdecls
= CLASS_IVARS (inter
);
3445 tree impdecls
= CLASS_IVARS (imp
);
3446 tree rawintdecls
= CLASS_RAW_IVARS (inter
);
3447 tree rawimpdecls
= CLASS_RAW_IVARS (imp
);
3453 if (intdecls
== 0 && impdecls
== 0)
3455 if (intdecls
== 0 || impdecls
== 0)
3457 error ("inconsistent instance variable specification");
3461 t1
= TREE_TYPE (intdecls
); t2
= TREE_TYPE (impdecls
);
3463 if (!comptypes (t1
, t2
))
3465 if (DECL_NAME (intdecls
) == DECL_NAME (impdecls
))
3467 error_with_ivar ("conflicting instance variable type",
3468 impdecls
, rawimpdecls
);
3469 error_with_ivar ("previous declaration of",
3470 intdecls
, rawintdecls
);
3472 else /* both the type and the name don't match */
3474 error ("inconsistent instance variable specification");
3479 else if (DECL_NAME (intdecls
) != DECL_NAME (impdecls
))
3481 error_with_ivar ("conflicting instance variable name",
3482 impdecls
, rawimpdecls
);
3483 error_with_ivar ("previous declaration of",
3484 intdecls
, rawintdecls
);
3487 intdecls
= TREE_CHAIN (intdecls
);
3488 impdecls
= TREE_CHAIN (impdecls
);
3489 rawintdecls
= TREE_CHAIN (rawintdecls
);
3490 rawimpdecls
= TREE_CHAIN (rawimpdecls
);
3494 /* Set super_type to the data type node for struct objc_super *,
3495 first defining struct objc_super itself.
3496 This needs to be done just once per compilation. */
3499 build_super_template ()
3501 tree record
, decl_specs
, field_decl
, field_decl_chain
;
3503 record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_SUPER
));
3505 /* struct objc_object *self; */
3507 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3508 field_decl
= get_identifier ("self");
3509 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3510 field_decl
= grokfield (input_filename
, lineno
,
3511 field_decl
, decl_specs
, NULL_TREE
);
3512 field_decl_chain
= field_decl
;
3514 /* struct objc_class *class; */
3516 decl_specs
= get_identifier (UTAG_CLASS
);
3517 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
3518 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class"));
3520 field_decl
= grokfield (input_filename
, lineno
,
3521 field_decl
, decl_specs
, NULL_TREE
);
3522 chainon (field_decl_chain
, field_decl
);
3524 finish_struct (record
, field_decl_chain
, NULL_TREE
);
3526 /* `struct objc_super *' */
3527 super_type
= groktypename (build_tree_list (build_tree_list (NULL_TREE
,
3529 build1 (INDIRECT_REF
,
3530 NULL_TREE
, NULL_TREE
)));
3534 /* struct objc_ivar {
3541 build_ivar_template ()
3543 tree objc_ivar_id
, objc_ivar_record
;
3544 tree decl_specs
, field_decl
, field_decl_chain
;
3546 objc_ivar_id
= get_identifier (UTAG_IVAR
);
3547 objc_ivar_record
= start_struct (RECORD_TYPE
, objc_ivar_id
);
3549 /* char *ivar_name; */
3551 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3552 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_name"));
3554 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3555 decl_specs
, NULL_TREE
);
3556 field_decl_chain
= field_decl
;
3558 /* char *ivar_type; */
3560 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3561 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_type"));
3563 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3564 decl_specs
, NULL_TREE
);
3565 chainon (field_decl_chain
, field_decl
);
3567 /* int ivar_offset; */
3569 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3570 field_decl
= get_identifier ("ivar_offset");
3572 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3573 decl_specs
, NULL_TREE
);
3574 chainon (field_decl_chain
, field_decl
);
3576 finish_struct (objc_ivar_record
, field_decl_chain
, NULL_TREE
);
3578 return objc_ivar_record
;
3583 struct objc_ivar ivar_list[ivar_count];
3587 build_ivar_list_template (list_type
, size
)
3591 tree objc_ivar_list_record
;
3592 tree decl_specs
, field_decl
, field_decl_chain
;
3594 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3596 /* int ivar_count; */
3598 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3599 field_decl
= get_identifier ("ivar_count");
3601 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3602 decl_specs
, NULL_TREE
);
3603 field_decl_chain
= field_decl
;
3605 /* struct objc_ivar ivar_list[]; */
3607 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3608 field_decl
= build_nt (ARRAY_REF
, get_identifier ("ivar_list"),
3609 build_int_2 (size
, 0));
3611 field_decl
= grokfield (input_filename
, lineno
,
3612 field_decl
, decl_specs
, NULL_TREE
);
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
;
3623 struct objc_method method_list[method_count];
3627 build_method_list_template (list_type
, size
)
3631 tree objc_ivar_list_record
;
3632 tree decl_specs
, field_decl
, field_decl_chain
;
3634 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3636 /* int method_next; */
3641 xref_tag (RECORD_TYPE
,
3642 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
3644 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_next"));
3645 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3646 decl_specs
, NULL_TREE
);
3647 field_decl_chain
= field_decl
;
3649 /* int method_count; */
3651 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3652 field_decl
= get_identifier ("method_count");
3654 field_decl
= grokfield (input_filename
, lineno
,
3655 field_decl
, decl_specs
, NULL_TREE
);
3656 chainon (field_decl_chain
, field_decl
);
3658 /* struct objc_method method_list[]; */
3660 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3661 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
3662 build_int_2 (size
, 0));
3664 field_decl
= grokfield (input_filename
, lineno
,
3665 field_decl
, decl_specs
, NULL_TREE
);
3666 chainon (field_decl_chain
, field_decl
);
3668 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3670 return objc_ivar_list_record
;
3674 build_ivar_list_initializer (type
, field_decl
)
3678 tree initlist
= NULL_TREE
;
3682 tree ivar
= NULL_TREE
;
3685 if (DECL_NAME (field_decl
))
3686 ivar
= tree_cons (NULL_TREE
,
3687 add_objc_string (DECL_NAME (field_decl
),
3691 /* Unnamed bit-field ivar (yuck). */
3692 ivar
= tree_cons (NULL_TREE
, build_int_2 (0, 0), ivar
);
3695 encode_field_decl (field_decl
,
3696 obstack_object_size (&util_obstack
),
3697 OBJC_ENCODE_DONT_INLINE_DEFS
);
3699 /* Null terminate string. */
3700 obstack_1grow (&util_obstack
, 0);
3704 add_objc_string (get_identifier (obstack_finish (&util_obstack
)),
3707 obstack_free (&util_obstack
, util_firstobj
);
3710 ivar
= tree_cons (NULL_TREE
, byte_position (field_decl
), ivar
);
3711 initlist
= tree_cons (NULL_TREE
,
3712 build_constructor (type
, nreverse (ivar
)),
3715 field_decl
= TREE_CHAIN (field_decl
);
3719 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3723 generate_ivars_list (type
, name
, size
, list
)
3729 tree sc_spec
, decl_specs
, decl
, initlist
;
3731 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3732 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
3734 decl
= start_decl (synth_id_with_class_suffix (name
, objc_implementation_context
),
3735 decl_specs
, 1, NULL_TREE
);
3737 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
3738 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3741 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3748 generate_ivar_lists ()
3750 tree initlist
, ivar_list_template
, chain
;
3751 tree cast
, variable_length_type
;
3754 generating_instance_variables
= 1;
3756 if (!objc_ivar_template
)
3757 objc_ivar_template
= build_ivar_template ();
3761 (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3762 get_identifier (UTAG_IVAR_LIST
))),
3764 variable_length_type
= groktypename (cast
);
3766 /* Only generate class variables for the root of the inheritance
3767 hierarchy since these will be the same for every class. */
3769 if (CLASS_SUPER_NAME (implementation_template
) == NULL_TREE
3770 && (chain
= TYPE_FIELDS (objc_class_template
)))
3772 size
= list_length (chain
);
3774 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3775 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3777 UOBJC_CLASS_VARIABLES_decl
3778 = generate_ivars_list (ivar_list_template
, "_OBJC_CLASS_VARIABLES",
3780 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl
) = variable_length_type
;
3783 UOBJC_CLASS_VARIABLES_decl
= 0;
3785 chain
= CLASS_IVARS (implementation_template
);
3788 size
= list_length (chain
);
3789 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3790 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3792 UOBJC_INSTANCE_VARIABLES_decl
3793 = generate_ivars_list (ivar_list_template
, "_OBJC_INSTANCE_VARIABLES",
3795 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl
) = variable_length_type
;
3798 UOBJC_INSTANCE_VARIABLES_decl
= 0;
3800 generating_instance_variables
= 0;
3804 build_dispatch_table_initializer (type
, entries
)
3808 tree initlist
= NULL_TREE
;
3812 tree elemlist
= NULL_TREE
;
3814 elemlist
= tree_cons (NULL_TREE
,
3815 build_selector (METHOD_SEL_NAME (entries
)),
3818 /* Generate the method encoding if we don't have one already. */
3819 if (! METHOD_ENCODING (entries
))
3820 METHOD_ENCODING (entries
) =
3821 encode_method_def (METHOD_DEFINITION (entries
));
3823 elemlist
= tree_cons (NULL_TREE
,
3824 add_objc_string (METHOD_ENCODING (entries
),
3828 elemlist
= tree_cons (NULL_TREE
,
3829 build_unary_op (ADDR_EXPR
,
3830 METHOD_DEFINITION (entries
), 1),
3833 initlist
= tree_cons (NULL_TREE
,
3834 build_constructor (type
, nreverse (elemlist
)),
3837 entries
= TREE_CHAIN (entries
);
3841 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3844 /* To accomplish method prototyping without generating all kinds of
3845 inane warnings, the definition of the dispatch table entries were
3848 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3850 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3853 build_method_template ()
3856 tree decl_specs
, field_decl
, field_decl_chain
;
3858 _SLT_record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD
));
3860 /* struct objc_selector *_cmd; */
3861 decl_specs
= tree_cons (NULL_TREE
,
3862 xref_tag (RECORD_TYPE
,
3863 get_identifier (TAG_SELECTOR
)),
3865 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
3867 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3868 decl_specs
, NULL_TREE
);
3869 field_decl_chain
= field_decl
;
3871 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
3872 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
,
3873 get_identifier ("method_types"));
3874 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3875 decl_specs
, NULL_TREE
);
3876 chainon (field_decl_chain
, field_decl
);
3880 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_VOID
], NULL_TREE
);
3881 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_imp"));
3882 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3883 decl_specs
, NULL_TREE
);
3884 chainon (field_decl_chain
, field_decl
);
3886 finish_struct (_SLT_record
, field_decl_chain
, NULL_TREE
);
3893 generate_dispatch_table (type
, name
, size
, list
)
3899 tree sc_spec
, decl_specs
, decl
, initlist
;
3901 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3902 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
3904 decl
= start_decl (synth_id_with_class_suffix (name
, objc_implementation_context
),
3905 decl_specs
, 1, NULL_TREE
);
3907 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
3908 initlist
= tree_cons (NULL_TREE
, build_int_2 (size
, 0), initlist
);
3909 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3912 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3919 generate_dispatch_tables ()
3921 tree initlist
, chain
, method_list_template
;
3922 tree cast
, variable_length_type
;
3925 if (!objc_method_template
)
3926 objc_method_template
= build_method_template ();
3930 (build_tree_list (NULL_TREE
,
3931 xref_tag (RECORD_TYPE
,
3932 get_identifier (UTAG_METHOD_LIST
))),
3935 variable_length_type
= groktypename (cast
);
3937 chain
= CLASS_CLS_METHODS (objc_implementation_context
);
3940 size
= list_length (chain
);
3942 method_list_template
3943 = build_method_list_template (objc_method_template
, size
);
3945 = build_dispatch_table_initializer (objc_method_template
, chain
);
3947 UOBJC_CLASS_METHODS_decl
3948 = generate_dispatch_table (method_list_template
,
3949 ((TREE_CODE (objc_implementation_context
)
3950 == CLASS_IMPLEMENTATION_TYPE
)
3951 ? "_OBJC_CLASS_METHODS"
3952 : "_OBJC_CATEGORY_CLASS_METHODS"),
3954 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
3957 UOBJC_CLASS_METHODS_decl
= 0;
3959 chain
= CLASS_NST_METHODS (objc_implementation_context
);
3962 size
= list_length (chain
);
3964 method_list_template
3965 = build_method_list_template (objc_method_template
, size
);
3967 = build_dispatch_table_initializer (objc_method_template
, chain
);
3969 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
3970 UOBJC_INSTANCE_METHODS_decl
3971 = generate_dispatch_table (method_list_template
,
3972 "_OBJC_INSTANCE_METHODS",
3975 /* We have a category. */
3976 UOBJC_INSTANCE_METHODS_decl
3977 = generate_dispatch_table (method_list_template
,
3978 "_OBJC_CATEGORY_INSTANCE_METHODS",
3980 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
3983 UOBJC_INSTANCE_METHODS_decl
= 0;
3987 generate_protocol_list (i_or_p
)
3990 tree initlist
, decl_specs
, sc_spec
;
3991 tree refs_decl
, expr_decl
, lproto
, e
, plist
;
3995 if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
3996 || TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
3997 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
3998 else if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
3999 plist
= PROTOCOL_LIST (i_or_p
);
4003 cast_type
= groktypename
4005 (build_tree_list (NULL_TREE
,
4006 xref_tag (RECORD_TYPE
,
4007 get_identifier (UTAG_PROTOCOL
))),
4008 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
4011 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4012 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
4013 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
4016 /* Build initializer. */
4017 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), NULL_TREE
);
4019 e
= build_int_2 (size
, 0);
4020 TREE_TYPE (e
) = cast_type
;
4021 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4023 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4025 tree pval
= TREE_VALUE (lproto
);
4027 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
4028 && PROTOCOL_FORWARD_DECL (pval
))
4030 e
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (pval
), 0);
4031 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4035 /* static struct objc_protocol *refs[n]; */
4037 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4038 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
4039 get_identifier (UTAG_PROTOCOL
)),
4042 if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4043 expr_decl
= build_nt (ARRAY_REF
,
4044 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4046 build_int_2 (size
+ 2, 0));
4047 else if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
)
4048 expr_decl
= build_nt (ARRAY_REF
,
4049 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4051 build_int_2 (size
+ 2, 0));
4052 else if (TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4054 = build_nt (ARRAY_REF
,
4055 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4057 build_int_2 (size
+ 2, 0));
4061 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
4063 refs_decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
4064 DECL_CONTEXT (refs_decl
) = NULL_TREE
;
4066 finish_decl (refs_decl
, build_constructor (TREE_TYPE (refs_decl
),
4067 nreverse (initlist
)),
4074 build_category_initializer (type
, cat_name
, class_name
,
4075 instance_methods
, class_methods
, protocol_list
)
4079 tree instance_methods
;
4083 tree initlist
= NULL_TREE
, expr
;
4085 initlist
= tree_cons (NULL_TREE
, cat_name
, initlist
);
4086 initlist
= tree_cons (NULL_TREE
, class_name
, initlist
);
4088 if (!instance_methods
)
4089 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4092 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
4093 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4096 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4099 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
4100 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4103 /* protocol_list = */
4105 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4108 tree cast_type2
= groktypename
4110 (build_tree_list (NULL_TREE
,
4111 xref_tag (RECORD_TYPE
,
4112 get_identifier (UTAG_PROTOCOL
))),
4113 build1 (INDIRECT_REF
, NULL_TREE
,
4114 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4116 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4117 TREE_TYPE (expr
) = cast_type2
;
4118 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4121 return build_constructor (type
, nreverse (initlist
));
4124 /* struct objc_class {
4125 struct objc_class *isa;
4126 struct objc_class *super_class;
4131 struct objc_ivar_list *ivars;
4132 struct objc_method_list *methods;
4133 if (flag_next_runtime)
4134 struct objc_cache *cache;
4136 struct sarray *dtable;
4137 struct objc_class *subclass_list;
4138 struct objc_class *sibling_class;
4140 struct objc_protocol_list *protocols;
4141 void *gc_object_type;
4145 build_shared_structure_initializer (type
, isa
, super
, name
, size
, status
,
4146 dispatch_table
, ivar_list
, protocol_list
)
4153 tree dispatch_table
;
4157 tree initlist
= NULL_TREE
, expr
;
4160 initlist
= tree_cons (NULL_TREE
, isa
, initlist
);
4163 initlist
= tree_cons (NULL_TREE
, super
, initlist
);
4166 initlist
= tree_cons (NULL_TREE
, default_conversion (name
), initlist
);
4169 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4172 initlist
= tree_cons (NULL_TREE
, build_int_2 (status
, 0), initlist
);
4174 /* instance_size = */
4175 initlist
= tree_cons (NULL_TREE
, size
, initlist
);
4177 /* objc_ivar_list = */
4179 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4182 expr
= build_unary_op (ADDR_EXPR
, ivar_list
, 0);
4183 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4186 /* objc_method_list = */
4187 if (!dispatch_table
)
4188 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4191 expr
= build_unary_op (ADDR_EXPR
, dispatch_table
, 0);
4192 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4195 if (flag_next_runtime
)
4196 /* method_cache = */
4197 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4201 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4203 /* subclass_list = */
4204 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4206 /* sibling_class = */
4207 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4210 /* protocol_list = */
4211 if (! protocol_list
)
4212 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4218 (build_tree_list (NULL_TREE
,
4219 xref_tag (RECORD_TYPE
,
4220 get_identifier (UTAG_PROTOCOL
))),
4221 build1 (INDIRECT_REF
, NULL_TREE
,
4222 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4224 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4225 TREE_TYPE (expr
) = cast_type2
;
4226 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4229 /* gc_object_type = NULL */
4230 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4232 return build_constructor (type
, nreverse (initlist
));
4235 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4238 generate_category (cat
)
4241 tree sc_spec
, decl_specs
, decl
;
4242 tree initlist
, cat_name_expr
, class_name_expr
;
4243 tree protocol_decl
, category
;
4245 add_class_reference (CLASS_NAME (cat
));
4246 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
4248 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
4250 category
= CLASS_CATEGORY_LIST (implementation_template
);
4252 /* find the category interface from the class it is associated with */
4255 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
4257 category
= CLASS_CATEGORY_LIST (category
);
4260 if (category
&& CLASS_PROTOCOL_LIST (category
))
4262 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
4263 protocol_decl
= generate_protocol_list (category
);
4268 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4269 decl_specs
= tree_cons (NULL_TREE
, objc_category_template
, sc_spec
);
4271 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4272 objc_implementation_context
),
4273 decl_specs
, 1, NULL_TREE
);
4275 initlist
= build_category_initializer (TREE_TYPE (decl
),
4276 cat_name_expr
, class_name_expr
,
4277 UOBJC_INSTANCE_METHODS_decl
,
4278 UOBJC_CLASS_METHODS_decl
,
4281 TREE_USED (decl
) = 1;
4282 finish_decl (decl
, initlist
, NULL_TREE
);
4285 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4286 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4289 generate_shared_structures ()
4291 tree sc_spec
, decl_specs
, decl
;
4292 tree name_expr
, super_expr
, root_expr
;
4293 tree my_root_id
= NULL_TREE
, my_super_id
= NULL_TREE
;
4294 tree cast_type
, initlist
, protocol_decl
;
4296 my_super_id
= CLASS_SUPER_NAME (implementation_template
);
4299 add_class_reference (my_super_id
);
4301 /* Compute "my_root_id" - this is required for code generation.
4302 the "isa" for all meta class structures points to the root of
4303 the inheritance hierarchy (e.g. "__Object")... */
4304 my_root_id
= my_super_id
;
4307 tree my_root_int
= lookup_interface (my_root_id
);
4309 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
4310 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
4317 /* No super class. */
4318 my_root_id
= CLASS_NAME (implementation_template
);
4321 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
4322 objc_class_template
),
4323 build1 (INDIRECT_REF
,
4324 NULL_TREE
, NULL_TREE
)));
4326 name_expr
= add_objc_string (CLASS_NAME (implementation_template
),
4329 /* Install class `isa' and `super' pointers at runtime. */
4332 super_expr
= add_objc_string (my_super_id
, class_names
);
4333 super_expr
= build_c_cast (cast_type
, super_expr
); /* cast! */
4336 super_expr
= build_int_2 (0, 0);
4338 root_expr
= add_objc_string (my_root_id
, class_names
);
4339 root_expr
= build_c_cast (cast_type
, root_expr
); /* cast! */
4341 if (CLASS_PROTOCOL_LIST (implementation_template
))
4343 generate_protocol_references
4344 (CLASS_PROTOCOL_LIST (implementation_template
));
4345 protocol_decl
= generate_protocol_list (implementation_template
);
4350 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4352 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
4353 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
4355 decl
= start_decl (DECL_NAME (UOBJC_METACLASS_decl
), decl_specs
, 1,
4359 = build_shared_structure_initializer
4361 root_expr
, super_expr
, name_expr
,
4362 convert (integer_type_node
, TYPE_SIZE_UNIT (objc_class_template
)),
4364 UOBJC_CLASS_METHODS_decl
,
4365 UOBJC_CLASS_VARIABLES_decl
,
4368 finish_decl (decl
, initlist
, NULL_TREE
);
4370 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4372 decl
= start_decl (DECL_NAME (UOBJC_CLASS_decl
), decl_specs
, 1,
4376 = build_shared_structure_initializer
4378 build_unary_op (ADDR_EXPR
, UOBJC_METACLASS_decl
, 0),
4379 super_expr
, name_expr
,
4380 convert (integer_type_node
,
4381 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4382 (implementation_template
))),
4384 UOBJC_INSTANCE_METHODS_decl
,
4385 UOBJC_INSTANCE_VARIABLES_decl
,
4388 finish_decl (decl
, initlist
, NULL_TREE
);
4392 synth_id_with_class_suffix (preamble
, ctxt
)
4393 const char *preamble
;
4397 if (TREE_CODE (ctxt
) == CLASS_IMPLEMENTATION_TYPE
4398 || TREE_CODE (ctxt
) == CLASS_INTERFACE_TYPE
)
4400 const char *const class_name
4401 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
4402 string
= (char *) alloca (strlen (preamble
) + strlen (class_name
) + 3);
4403 sprintf (string
, "%s_%s", preamble
,
4404 IDENTIFIER_POINTER (CLASS_NAME (ctxt
)));
4406 else if (TREE_CODE (ctxt
) == CATEGORY_IMPLEMENTATION_TYPE
4407 || TREE_CODE (ctxt
) == CATEGORY_INTERFACE_TYPE
)
4409 /* We have a category. */
4410 const char *const class_name
4411 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
4412 const char *const class_super_name
4413 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
));
4414 string
= (char *) alloca (strlen (preamble
)
4415 + strlen (class_name
)
4416 + strlen (class_super_name
)
4418 sprintf (string
, "%s_%s_%s", preamble
, class_name
, class_super_name
);
4420 else if (TREE_CODE (ctxt
) == PROTOCOL_INTERFACE_TYPE
)
4422 const char *protocol_name
= IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt
));
4424 = (char *) alloca (strlen (preamble
) + strlen (protocol_name
) + 3);
4425 sprintf (string
, "%s_%s", preamble
, protocol_name
);
4430 return get_identifier (string
);
4434 is_objc_type_qualifier (node
)
4437 return (TREE_CODE (node
) == IDENTIFIER_NODE
4438 && (node
== ridpointers
[(int) RID_CONST
]
4439 || node
== ridpointers
[(int) RID_VOLATILE
]
4440 || node
== ridpointers
[(int) RID_IN
]
4441 || node
== ridpointers
[(int) RID_OUT
]
4442 || node
== ridpointers
[(int) RID_INOUT
]
4443 || node
== ridpointers
[(int) RID_BYCOPY
]
4444 || node
== ridpointers
[(int) RID_BYREF
]
4445 || node
== ridpointers
[(int) RID_ONEWAY
]));
4448 /* If type is empty or only type qualifiers are present, add default
4449 type of id (otherwise grokdeclarator will default to int). */
4452 adjust_type_for_id_default (type
)
4455 tree declspecs
, chain
;
4458 return build_tree_list (build_tree_list (NULL_TREE
, objc_object_reference
),
4459 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4461 declspecs
= TREE_PURPOSE (type
);
4463 /* Determine if a typespec is present. */
4464 for (chain
= declspecs
;
4466 chain
= TREE_CHAIN (chain
))
4468 if (TREE_CODE (TREE_VALUE (chain
)) == RECORD_TYPE
4469 && !(TREE_VALUE (type
)
4470 && TREE_CODE (TREE_VALUE (type
)) == INDIRECT_REF
))
4471 error ("can not use an object as parameter to a method\n");
4472 if (!is_objc_type_qualifier (TREE_VALUE (chain
)))
4476 return build_tree_list (tree_cons (NULL_TREE
, objc_object_reference
,
4478 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4483 selector ':' '(' typename ')' identifier
4486 Transform an Objective-C keyword argument into
4487 the C equivalent parameter declarator.
4489 In: key_name, an "identifier_node" (optional).
4490 arg_type, a "tree_list" (optional).
4491 arg_name, an "identifier_node".
4493 Note: It would be really nice to strongly type the preceding
4494 arguments in the function prototype; however, then I
4495 could not use the "accessor" macros defined in "tree.h".
4497 Out: an instance of "keyword_decl". */
4500 build_keyword_decl (key_name
, arg_type
, arg_name
)
4507 /* If no type is specified, default to "id". */
4508 arg_type
= adjust_type_for_id_default (arg_type
);
4510 keyword_decl
= make_node (KEYWORD_DECL
);
4512 TREE_TYPE (keyword_decl
) = arg_type
;
4513 KEYWORD_ARG_NAME (keyword_decl
) = arg_name
;
4514 KEYWORD_KEY_NAME (keyword_decl
) = key_name
;
4516 return keyword_decl
;
4519 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4522 build_keyword_selector (selector
)
4526 tree key_chain
, key_name
;
4529 /* Scan the selector to see how much space we'll need. */
4530 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4532 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4533 key_name
= KEYWORD_KEY_NAME (key_chain
);
4534 else if (TREE_CODE (selector
) == TREE_LIST
)
4535 key_name
= TREE_PURPOSE (key_chain
);
4540 len
+= IDENTIFIER_LENGTH (key_name
) + 1;
4542 /* Just a ':' arg. */
4546 buf
= (char *) alloca (len
+ 1);
4547 /* Start the buffer out as an empty string. */
4550 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4552 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4553 key_name
= KEYWORD_KEY_NAME (key_chain
);
4554 else if (TREE_CODE (selector
) == TREE_LIST
)
4555 key_name
= TREE_PURPOSE (key_chain
);
4560 strcat (buf
, IDENTIFIER_POINTER (key_name
));
4564 return get_identifier (buf
);
4567 /* Used for declarations and definitions. */
4570 build_method_decl (code
, ret_type
, selector
, add_args
)
4571 enum tree_code code
;
4578 /* If no type is specified, default to "id". */
4579 ret_type
= adjust_type_for_id_default (ret_type
);
4581 method_decl
= make_node (code
);
4582 TREE_TYPE (method_decl
) = ret_type
;
4584 /* If we have a keyword selector, create an identifier_node that
4585 represents the full selector name (`:' included)... */
4586 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4588 METHOD_SEL_NAME (method_decl
) = build_keyword_selector (selector
);
4589 METHOD_SEL_ARGS (method_decl
) = selector
;
4590 METHOD_ADD_ARGS (method_decl
) = add_args
;
4594 METHOD_SEL_NAME (method_decl
) = selector
;
4595 METHOD_SEL_ARGS (method_decl
) = NULL_TREE
;
4596 METHOD_ADD_ARGS (method_decl
) = NULL_TREE
;
4602 #define METHOD_DEF 0
4603 #define METHOD_REF 1
4605 /* Used by `build_objc_method_call' and `comp_method_types'. Return
4606 an argument list for method METH. CONTEXT is either METHOD_DEF or
4607 METHOD_REF, saying whether we are trying to define a method or call
4608 one. SUPERFLAG says this is for a send to super; this makes a
4609 difference for the NeXT calling sequence in which the lookup and
4610 the method call are done together. */
4613 get_arg_type_list (meth
, context
, superflag
)
4620 /* Receiver type. */
4621 if (flag_next_runtime
&& superflag
)
4622 arglist
= build_tree_list (NULL_TREE
, super_type
);
4623 else if (context
== METHOD_DEF
)
4624 arglist
= build_tree_list (NULL_TREE
, TREE_TYPE (self_decl
));
4626 arglist
= build_tree_list (NULL_TREE
, id_type
);
4628 /* Selector type - will eventually change to `int'. */
4629 chainon (arglist
, build_tree_list (NULL_TREE
, selector_type
));
4631 /* Build a list of argument types. */
4632 for (akey
= METHOD_SEL_ARGS (meth
); akey
; akey
= TREE_CHAIN (akey
))
4634 tree arg_decl
= groktypename_in_parm_context (TREE_TYPE (akey
));
4635 chainon (arglist
, build_tree_list (NULL_TREE
, TREE_TYPE (arg_decl
)));
4638 if (METHOD_ADD_ARGS (meth
) == objc_ellipsis_node
)
4639 /* We have a `, ...' immediately following the selector,
4640 finalize the arglist...simulate get_parm_info (0). */
4642 else if (METHOD_ADD_ARGS (meth
))
4644 /* we have a variable length selector */
4645 tree add_arg_list
= TREE_CHAIN (METHOD_ADD_ARGS (meth
));
4646 chainon (arglist
, add_arg_list
);
4649 /* finalize the arglist...simulate get_parm_info (1) */
4650 chainon (arglist
, build_tree_list (NULL_TREE
, void_type_node
));
4656 check_duplicates (hsh
)
4659 tree meth
= NULL_TREE
;
4667 /* We have two methods with the same name and different types. */
4669 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
) ? '-' : '+';
4671 warning ("multiple declarations for method `%s'",
4672 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
4674 warn_with_method ("using", type
, meth
);
4675 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
4676 warn_with_method ("also found", type
, loop
->value
);
4682 /* If RECEIVER is a class reference, return the identifier node for
4683 the referenced class. RECEIVER is created by get_class_reference,
4684 so we check the exact form created depending on which runtimes are
4688 receiver_is_class_object (receiver
)
4691 tree chain
, exp
, arg
;
4693 /* The receiver is 'self' in the context of a class method. */
4694 if (objc_method_context
4695 && receiver
== self_decl
4696 && TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
4698 return CLASS_NAME (objc_implementation_context
);
4701 if (flag_next_runtime
)
4703 /* The receiver is a variable created by
4704 build_class_reference_decl. */
4705 if (TREE_CODE (receiver
) == VAR_DECL
4706 && TREE_TYPE (receiver
) == objc_class_type
)
4707 /* Look up the identifier. */
4708 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
4709 if (TREE_PURPOSE (chain
) == receiver
)
4710 return TREE_VALUE (chain
);
4714 /* The receiver is a function call that returns an id. Check if
4715 it is a call to objc_getClass, if so, pick up the class name. */
4716 if (TREE_CODE (receiver
) == CALL_EXPR
4717 && (exp
= TREE_OPERAND (receiver
, 0))
4718 && TREE_CODE (exp
) == ADDR_EXPR
4719 && (exp
= TREE_OPERAND (exp
, 0))
4720 && TREE_CODE (exp
) == FUNCTION_DECL
4721 && exp
== objc_get_class_decl
4722 /* We have a call to objc_getClass! */
4723 && (arg
= TREE_OPERAND (receiver
, 1))
4724 && TREE_CODE (arg
) == TREE_LIST
4725 && (arg
= TREE_VALUE (arg
)))
4728 if (TREE_CODE (arg
) == ADDR_EXPR
4729 && (arg
= TREE_OPERAND (arg
, 0))
4730 && TREE_CODE (arg
) == STRING_CST
)
4731 /* Finally, we have the class name. */
4732 return get_identifier (TREE_STRING_POINTER (arg
));
4738 /* If we are currently building a message expr, this holds
4739 the identifier of the selector of the message. This is
4740 used when printing warnings about argument mismatches. */
4742 static tree building_objc_message_expr
= 0;
4745 maybe_building_objc_message_expr ()
4747 return building_objc_message_expr
;
4750 /* Construct an expression for sending a message.
4751 MESS has the object to send to in TREE_PURPOSE
4752 and the argument list (including selector) in TREE_VALUE.
4754 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4755 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4758 build_message_expr (mess
)
4761 tree receiver
= TREE_PURPOSE (mess
);
4763 tree args
= TREE_VALUE (mess
);
4764 tree method_params
= NULL_TREE
;
4766 if (TREE_CODE (receiver
) == ERROR_MARK
)
4767 return error_mark_node
;
4769 /* Obtain the full selector name. */
4770 if (TREE_CODE (args
) == IDENTIFIER_NODE
)
4771 /* A unary selector. */
4773 else if (TREE_CODE (args
) == TREE_LIST
)
4774 sel_name
= build_keyword_selector (args
);
4778 /* Build the parameter list to give to the method. */
4779 if (TREE_CODE (args
) == TREE_LIST
)
4781 tree chain
= args
, prev
= NULL_TREE
;
4783 /* We have a keyword selector--check for comma expressions. */
4786 tree element
= TREE_VALUE (chain
);
4788 /* We have a comma expression, must collapse... */
4789 if (TREE_CODE (element
) == TREE_LIST
)
4792 TREE_CHAIN (prev
) = element
;
4797 chain
= TREE_CHAIN (chain
);
4799 method_params
= args
;
4802 return finish_message_expr (receiver
, sel_name
, method_params
);
4805 /* The 'finish_message_expr' routine is called from within
4806 'build_message_expr' for non-template functions. In the case of
4807 C++ template functions, it is called from 'build_expr_from_tree'
4808 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
4811 finish_message_expr (receiver
, sel_name
, method_params
)
4812 tree receiver
, sel_name
, method_params
;
4814 tree method_prototype
= NULL_TREE
, class_ident
= NULL_TREE
;
4815 tree selector
, self_object
, retval
;
4816 int statically_typed
= 0, statically_allocated
= 0;
4818 /* Determine receiver type. */
4819 tree rtype
= TREE_TYPE (receiver
);
4820 int super
= IS_SUPER (rtype
);
4824 if (TREE_STATIC_TEMPLATE (rtype
))
4825 statically_allocated
= 1;
4826 else if (TREE_CODE (rtype
) == POINTER_TYPE
4827 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype
)))
4828 statically_typed
= 1;
4829 else if ((flag_next_runtime
4831 && (class_ident
= receiver_is_class_object (receiver
)))
4833 else if (! IS_ID (rtype
)
4834 /* Allow any type that matches objc_class_type. */
4835 && ! comptypes (rtype
, objc_class_type
))
4837 warning ("invalid receiver type `%s'",
4838 gen_declaration (rtype
, errbuf
));
4840 if (statically_allocated
)
4841 receiver
= build_unary_op (ADDR_EXPR
, receiver
, 0);
4843 /* Don't evaluate the receiver twice. */
4844 receiver
= save_expr (receiver
);
4845 self_object
= receiver
;
4848 /* If sending to `super', use current self as the object. */
4849 self_object
= self_decl
;
4851 /* Determine operation return type. */
4857 if (CLASS_SUPER_NAME (implementation_template
))
4860 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
4862 if (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
)
4863 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4865 method_prototype
= lookup_class_method_static (iface
, sel_name
);
4867 if (iface
&& !method_prototype
)
4868 warning ("`%s' does not respond to `%s'",
4869 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template
)),
4870 IDENTIFIER_POINTER (sel_name
));
4874 error ("no super class declared in interface for `%s'",
4875 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
4876 return error_mark_node
;
4880 else if (statically_allocated
)
4882 tree ctype
= TREE_TYPE (rtype
);
4883 tree iface
= lookup_interface (TYPE_NAME (rtype
));
4886 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4888 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
4890 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
4893 if (!method_prototype
)
4894 warning ("`%s' does not respond to `%s'",
4895 IDENTIFIER_POINTER (TYPE_NAME (rtype
)),
4896 IDENTIFIER_POINTER (sel_name
));
4898 else if (statically_typed
)
4900 tree ctype
= TREE_TYPE (rtype
);
4902 /* `self' is now statically_typed. All methods should be visible
4903 within the context of the implementation. */
4904 if (objc_implementation_context
4905 && CLASS_NAME (objc_implementation_context
) == TYPE_NAME (ctype
))
4908 = lookup_instance_method_static (implementation_template
,
4911 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
4913 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
4916 if (! method_prototype
4917 && implementation_template
!= objc_implementation_context
)
4918 /* The method is not published in the interface. Check
4921 = lookup_method (CLASS_NST_METHODS (objc_implementation_context
),
4928 if ((iface
= lookup_interface (TYPE_NAME (ctype
))))
4929 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4931 if (! method_prototype
)
4933 tree protocol_list
= TYPE_PROTOCOL_LIST (ctype
);
4936 = lookup_method_in_protocol_list (protocol_list
,
4941 if (!method_prototype
)
4942 warning ("`%s' does not respond to `%s'",
4943 IDENTIFIER_POINTER (TYPE_NAME (ctype
)),
4944 IDENTIFIER_POINTER (sel_name
));
4946 else if (class_ident
)
4948 if (objc_implementation_context
4949 && CLASS_NAME (objc_implementation_context
) == class_ident
)
4952 = lookup_class_method_static (implementation_template
, sel_name
);
4954 if (!method_prototype
4955 && implementation_template
!= objc_implementation_context
)
4956 /* The method is not published in the interface. Check
4959 = lookup_method (CLASS_CLS_METHODS (objc_implementation_context
),
4966 if ((iface
= lookup_interface (class_ident
)))
4967 method_prototype
= lookup_class_method_static (iface
, sel_name
);
4970 if (!method_prototype
)
4972 warning ("cannot find class (factory) method");
4973 warning ("return type for `%s' defaults to id",
4974 IDENTIFIER_POINTER (sel_name
));
4977 else if (IS_PROTOCOL_QUALIFIED_ID (rtype
))
4979 /* An anonymous object that has been qualified with a protocol. */
4981 tree protocol_list
= TYPE_PROTOCOL_LIST (rtype
);
4983 method_prototype
= lookup_method_in_protocol_list (protocol_list
,
4986 if (!method_prototype
)
4990 warning ("method `%s' not implemented by protocol",
4991 IDENTIFIER_POINTER (sel_name
));
4993 /* Try and find the method signature in the global pools. */
4995 if (!(hsh
= hash_lookup (nst_method_hash_list
, sel_name
)))
4996 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
4998 if (!(method_prototype
= check_duplicates (hsh
)))
4999 warning ("return type defaults to id");
5006 /* We think we have an instance...loophole: extern id Object; */
5007 hsh
= hash_lookup (nst_method_hash_list
, sel_name
);
5010 /* For various loopholes */
5011 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5013 method_prototype
= check_duplicates (hsh
);
5014 if (!method_prototype
)
5016 warning ("cannot find method");
5017 warning ("return type for `%s' defaults to id",
5018 IDENTIFIER_POINTER (sel_name
));
5022 /* Save the selector name for printing error messages. */
5023 building_objc_message_expr
= sel_name
;
5025 /* Build the parameters list for looking up the method.
5026 These are the object itself and the selector. */
5028 if (flag_typed_selectors
)
5029 selector
= build_typed_selector_reference (sel_name
, method_prototype
);
5031 selector
= build_selector_reference (sel_name
);
5033 retval
= build_objc_method_call (super
, method_prototype
,
5034 receiver
, self_object
,
5035 selector
, method_params
);
5037 building_objc_message_expr
= 0;
5042 /* Build a tree expression to send OBJECT the operation SELECTOR,
5043 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5044 assuming the method has prototype METHOD_PROTOTYPE.
5045 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5046 Use METHOD_PARAMS as list of args to pass to the method.
5047 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5050 build_objc_method_call (super_flag
, method_prototype
, lookup_object
, object
,
5051 selector
, method_params
)
5053 tree method_prototype
, lookup_object
, object
, selector
, method_params
;
5055 tree sender
= (super_flag
? umsg_super_decl
: umsg_decl
);
5056 tree rcv_p
= (super_flag
5057 ? build_pointer_type (xref_tag (RECORD_TYPE
,
5058 get_identifier (TAG_SUPER
)))
5061 if (flag_next_runtime
)
5063 if (! method_prototype
)
5065 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5066 tree_cons (NULL_TREE
, selector
,
5068 assemble_external (sender
);
5069 return build_function_call (sender
, method_params
);
5073 /* This is a real kludge, but it is used only for the Next.
5074 Clobber the data type of SENDER temporarily to accept
5075 all the arguments for this operation, and to return
5076 whatever this operation returns. */
5077 tree arglist
= NULL_TREE
, retval
, savarg
, savret
;
5078 tree ret_type
= groktypename (TREE_TYPE (method_prototype
));
5080 /* Save the proper contents of SENDER's data type. */
5081 savarg
= TYPE_ARG_TYPES (TREE_TYPE (sender
));
5082 savret
= TREE_TYPE (TREE_TYPE (sender
));
5084 /* Install this method's argument types. */
5085 arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5087 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = arglist
;
5089 /* Install this method's return type. */
5090 TREE_TYPE (TREE_TYPE (sender
)) = ret_type
;
5092 /* Call SENDER with all the parameters. This will do type
5093 checking using the arg types for this method. */
5094 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5095 tree_cons (NULL_TREE
, selector
,
5097 assemble_external (sender
);
5098 retval
= build_function_call (sender
, method_params
);
5100 /* Restore SENDER's return/argument types. */
5101 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = savarg
;
5102 TREE_TYPE (TREE_TYPE (sender
)) = savret
;
5108 /* This is the portable way.
5109 First call the lookup function to get a pointer to the method,
5110 then cast the pointer, then call it with the method arguments. */
5113 /* Avoid trouble since we may evaluate each of these twice. */
5114 object
= save_expr (object
);
5115 selector
= save_expr (selector
);
5117 lookup_object
= build_c_cast (rcv_p
, lookup_object
);
5119 assemble_external (sender
);
5121 = build_function_call (sender
,
5122 tree_cons (NULL_TREE
, lookup_object
,
5123 tree_cons (NULL_TREE
, selector
,
5126 /* If we have a method prototype, construct the data type this
5127 method needs, and cast what we got from SENDER into a pointer
5129 if (method_prototype
)
5131 tree arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5133 tree valtype
= groktypename (TREE_TYPE (method_prototype
));
5134 tree fake_function_type
= build_function_type (valtype
, arglist
);
5135 TREE_TYPE (method
) = build_pointer_type (fake_function_type
);
5139 = build_pointer_type (build_function_type (ptr_type_node
, NULL_TREE
));
5141 /* Pass the object to the method. */
5142 assemble_external (method
);
5143 return build_function_call (method
,
5144 tree_cons (NULL_TREE
, object
,
5145 tree_cons (NULL_TREE
, selector
,
5151 build_protocol_reference (p
)
5154 tree decl
, ident
, ptype
;
5156 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5158 ident
= synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
);
5160 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
5161 objc_protocol_template
),
5164 if (IDENTIFIER_GLOBAL_VALUE (ident
))
5165 decl
= IDENTIFIER_GLOBAL_VALUE (ident
); /* Set by pushdecl. */
5168 decl
= build_decl (VAR_DECL
, ident
, ptype
);
5169 DECL_EXTERNAL (decl
) = 1;
5170 TREE_PUBLIC (decl
) = 1;
5171 TREE_USED (decl
) = 1;
5172 DECL_ARTIFICIAL (decl
) = 1;
5174 make_decl_rtl (decl
, 0);
5175 pushdecl_top_level (decl
);
5178 PROTOCOL_FORWARD_DECL (p
) = decl
;
5182 build_protocol_expr (protoname
)
5186 tree p
= lookup_protocol (protoname
);
5190 error ("cannot find protocol declaration for `%s'",
5191 IDENTIFIER_POINTER (protoname
));
5192 return error_mark_node
;
5195 if (!PROTOCOL_FORWARD_DECL (p
))
5196 build_protocol_reference (p
);
5198 expr
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
5200 TREE_TYPE (expr
) = protocol_type
;
5206 build_selector_expr (selnamelist
)
5211 /* Obtain the full selector name. */
5212 if (TREE_CODE (selnamelist
) == IDENTIFIER_NODE
)
5213 /* A unary selector. */
5214 selname
= selnamelist
;
5215 else if (TREE_CODE (selnamelist
) == TREE_LIST
)
5216 selname
= build_keyword_selector (selnamelist
);
5220 if (flag_typed_selectors
)
5221 return build_typed_selector_reference (selname
, 0);
5223 return build_selector_reference (selname
);
5227 build_encode_expr (type
)
5233 encode_type (type
, obstack_object_size (&util_obstack
),
5234 OBJC_ENCODE_INLINE_DEFS
);
5235 obstack_1grow (&util_obstack
, 0); /* null terminate string */
5236 string
= obstack_finish (&util_obstack
);
5238 /* Synthesize a string that represents the encoded struct/union. */
5239 result
= my_build_string (strlen (string
) + 1, string
);
5240 obstack_free (&util_obstack
, util_firstobj
);
5245 build_ivar_reference (id
)
5248 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
5250 /* Historically, a class method that produced objects (factory
5251 method) would assign `self' to the instance that it
5252 allocated. This would effectively turn the class method into
5253 an instance method. Following this assignment, the instance
5254 variables could be accessed. That practice, while safe,
5255 violates the simple rule that a class method should not refer
5256 to an instance variable. It's better to catch the cases
5257 where this is done unknowingly than to support the above
5259 warning ("instance variable `%s' accessed in class method",
5260 IDENTIFIER_POINTER (id
));
5261 TREE_TYPE (self_decl
) = instance_type
; /* cast */
5264 return build_component_ref (build_indirect_ref (self_decl
, "->"), id
);
5267 /* Compute a hash value for a given method SEL_NAME. */
5270 hash_func (sel_name
)
5273 const unsigned char *s
5274 = (const unsigned char *)IDENTIFIER_POINTER (sel_name
);
5278 h
= h
* 67 + *s
++ - 113;
5285 nst_method_hash_list
= (hash
*) ggc_calloc (SIZEHASHTABLE
, sizeof (hash
));
5286 cls_method_hash_list
= (hash
*) ggc_calloc (SIZEHASHTABLE
, sizeof (hash
));
5289 /* WARNING!!!! hash_enter is called with a method, and will peek
5290 inside to find its selector! But hash_lookup is given a selector
5291 directly, and looks for the selector that's inside the found
5292 entry's key (method) for comparison. */
5295 hash_enter (hashlist
, method
)
5300 int slot
= hash_func (METHOD_SEL_NAME (method
)) % SIZEHASHTABLE
;
5302 obj
= (hash
) ggc_alloc (sizeof (struct hashed_entry
));
5304 obj
->next
= hashlist
[slot
];
5307 hashlist
[slot
] = obj
; /* append to front */
5311 hash_lookup (hashlist
, sel_name
)
5317 target
= hashlist
[hash_func (sel_name
) % SIZEHASHTABLE
];
5321 if (sel_name
== METHOD_SEL_NAME (target
->key
))
5324 target
= target
->next
;
5330 hash_add_attr (entry
, value
)
5336 obj
= (attr
) ggc_alloc (sizeof (struct hashed_attribute
));
5337 obj
->next
= entry
->list
;
5340 entry
->list
= obj
; /* append to front */
5344 lookup_method (mchain
, method
)
5350 if (TREE_CODE (method
) == IDENTIFIER_NODE
)
5353 key
= METHOD_SEL_NAME (method
);
5357 if (METHOD_SEL_NAME (mchain
) == key
)
5359 mchain
= TREE_CHAIN (mchain
);
5365 lookup_instance_method_static (interface
, ident
)
5369 tree inter
= interface
;
5370 tree chain
= CLASS_NST_METHODS (inter
);
5371 tree meth
= NULL_TREE
;
5375 if ((meth
= lookup_method (chain
, ident
)))
5378 if (CLASS_CATEGORY_LIST (inter
))
5380 tree category
= CLASS_CATEGORY_LIST (inter
);
5381 chain
= CLASS_NST_METHODS (category
);
5385 if ((meth
= lookup_method (chain
, ident
)))
5388 /* Check for instance methods in protocols in categories. */
5389 if (CLASS_PROTOCOL_LIST (category
))
5391 if ((meth
= (lookup_method_in_protocol_list
5392 (CLASS_PROTOCOL_LIST (category
), ident
, 0))))
5396 if ((category
= CLASS_CATEGORY_LIST (category
)))
5397 chain
= CLASS_NST_METHODS (category
);
5402 if (CLASS_PROTOCOL_LIST (inter
))
5404 if ((meth
= (lookup_method_in_protocol_list
5405 (CLASS_PROTOCOL_LIST (inter
), ident
, 0))))
5409 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5410 chain
= CLASS_NST_METHODS (inter
);
5418 lookup_class_method_static (interface
, ident
)
5422 tree inter
= interface
;
5423 tree chain
= CLASS_CLS_METHODS (inter
);
5424 tree meth
= NULL_TREE
;
5425 tree root_inter
= NULL_TREE
;
5429 if ((meth
= lookup_method (chain
, ident
)))
5432 if (CLASS_CATEGORY_LIST (inter
))
5434 tree category
= CLASS_CATEGORY_LIST (inter
);
5435 chain
= CLASS_CLS_METHODS (category
);
5439 if ((meth
= lookup_method (chain
, ident
)))
5442 /* Check for class methods in protocols in categories. */
5443 if (CLASS_PROTOCOL_LIST (category
))
5445 if ((meth
= (lookup_method_in_protocol_list
5446 (CLASS_PROTOCOL_LIST (category
), ident
, 1))))
5450 if ((category
= CLASS_CATEGORY_LIST (category
)))
5451 chain
= CLASS_CLS_METHODS (category
);
5456 /* Check for class methods in protocols. */
5457 if (CLASS_PROTOCOL_LIST (inter
))
5459 if ((meth
= (lookup_method_in_protocol_list
5460 (CLASS_PROTOCOL_LIST (inter
), ident
, 1))))
5465 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5466 chain
= CLASS_CLS_METHODS (inter
);
5470 /* If no class (factory) method was found, check if an _instance_
5471 method of the same name exists in the root class. This is what
5472 the Objective-C runtime will do. */
5473 return lookup_instance_method_static (root_inter
, ident
);
5477 add_class_method (class, method
)
5484 if (!(mth
= lookup_method (CLASS_CLS_METHODS (class), method
)))
5486 /* put method on list in reverse order */
5487 TREE_CHAIN (method
) = CLASS_CLS_METHODS (class);
5488 CLASS_CLS_METHODS (class) = method
;
5492 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5493 error ("duplicate definition of class method `%s'",
5494 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5497 /* Check types; if different, complain. */
5498 if (!comp_proto_with_proto (method
, mth
))
5499 error ("duplicate declaration of class method `%s'",
5500 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5504 if (!(hsh
= hash_lookup (cls_method_hash_list
, METHOD_SEL_NAME (method
))))
5506 /* Install on a global chain. */
5507 hash_enter (cls_method_hash_list
, method
);
5511 /* Check types; if different, add to a list. */
5512 if (!comp_proto_with_proto (method
, hsh
->key
))
5513 hash_add_attr (hsh
, method
);
5519 add_instance_method (class, method
)
5526 if (!(mth
= lookup_method (CLASS_NST_METHODS (class), method
)))
5528 /* Put method on list in reverse order. */
5529 TREE_CHAIN (method
) = CLASS_NST_METHODS (class);
5530 CLASS_NST_METHODS (class) = method
;
5534 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5535 error ("duplicate definition of instance method `%s'",
5536 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5539 /* Check types; if different, complain. */
5540 if (!comp_proto_with_proto (method
, mth
))
5541 error ("duplicate declaration of instance method `%s'",
5542 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5546 if (!(hsh
= hash_lookup (nst_method_hash_list
, METHOD_SEL_NAME (method
))))
5548 /* Install on a global chain. */
5549 hash_enter (nst_method_hash_list
, method
);
5553 /* Check types; if different, add to a list. */
5554 if (!comp_proto_with_proto (method
, hsh
->key
))
5555 hash_add_attr (hsh
, method
);
5564 /* Put interfaces on list in reverse order. */
5565 TREE_CHAIN (class) = interface_chain
;
5566 interface_chain
= class;
5567 return interface_chain
;
5571 add_category (class, category
)
5575 /* Put categories on list in reverse order. */
5576 tree cat
= CLASS_CATEGORY_LIST (class);
5580 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
5581 warning ("duplicate interface declaration for category `%s(%s)'",
5582 IDENTIFIER_POINTER (CLASS_NAME (class)),
5583 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category
)));
5584 cat
= CLASS_CATEGORY_LIST (cat
);
5587 CLASS_CATEGORY_LIST (category
) = CLASS_CATEGORY_LIST (class);
5588 CLASS_CATEGORY_LIST (class) = category
;
5591 /* Called after parsing each instance variable declaration. Necessary to
5592 preserve typedefs and implement public/private...
5594 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5597 add_instance_variable (class, public, declarator
, declspecs
, width
)
5604 tree field_decl
, raw_decl
;
5606 raw_decl
= build_tree_list (declspecs
, declarator
);
5608 if (CLASS_RAW_IVARS (class))
5609 chainon (CLASS_RAW_IVARS (class), raw_decl
);
5611 CLASS_RAW_IVARS (class) = raw_decl
;
5613 field_decl
= grokfield (input_filename
, lineno
,
5614 declarator
, declspecs
, width
);
5616 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5620 TREE_PUBLIC (field_decl
) = 0;
5621 TREE_PRIVATE (field_decl
) = 0;
5622 TREE_PROTECTED (field_decl
) = 1;
5626 TREE_PUBLIC (field_decl
) = 1;
5627 TREE_PRIVATE (field_decl
) = 0;
5628 TREE_PROTECTED (field_decl
) = 0;
5632 TREE_PUBLIC (field_decl
) = 0;
5633 TREE_PRIVATE (field_decl
) = 1;
5634 TREE_PROTECTED (field_decl
) = 0;
5639 if (CLASS_IVARS (class))
5640 chainon (CLASS_IVARS (class), field_decl
);
5642 CLASS_IVARS (class) = field_decl
;
5648 is_ivar (decl_chain
, ident
)
5652 for ( ; decl_chain
; decl_chain
= TREE_CHAIN (decl_chain
))
5653 if (DECL_NAME (decl_chain
) == ident
)
5658 /* True if the ivar is private and we are not in its implementation. */
5664 if (TREE_PRIVATE (decl
)
5665 && ! is_ivar (CLASS_IVARS (implementation_template
), DECL_NAME (decl
)))
5667 error ("instance variable `%s' is declared private",
5668 IDENTIFIER_POINTER (DECL_NAME (decl
)));
5675 /* We have an instance variable reference;, check to see if it is public. */
5678 is_public (expr
, identifier
)
5682 tree basetype
= TREE_TYPE (expr
);
5683 enum tree_code code
= TREE_CODE (basetype
);
5686 if (code
== RECORD_TYPE
)
5688 if (TREE_STATIC_TEMPLATE (basetype
))
5690 if (!lookup_interface (TYPE_NAME (basetype
)))
5692 error ("cannot find interface declaration for `%s'",
5693 IDENTIFIER_POINTER (TYPE_NAME (basetype
)));
5697 if ((decl
= is_ivar (TYPE_FIELDS (basetype
), identifier
)))
5699 if (TREE_PUBLIC (decl
))
5702 /* Important difference between the Stepstone translator:
5703 all instance variables should be public within the context
5704 of the implementation. */
5705 if (objc_implementation_context
5706 && (((TREE_CODE (objc_implementation_context
)
5707 == CLASS_IMPLEMENTATION_TYPE
)
5708 || (TREE_CODE (objc_implementation_context
)
5709 == CATEGORY_IMPLEMENTATION_TYPE
))
5710 && (CLASS_NAME (objc_implementation_context
)
5711 == TYPE_NAME (basetype
))))
5712 return ! is_private (decl
);
5714 error ("instance variable `%s' is declared %s",
5715 IDENTIFIER_POINTER (identifier
),
5716 TREE_PRIVATE (decl
) ? "private" : "protected");
5721 else if (objc_implementation_context
&& (basetype
== objc_object_reference
))
5723 TREE_TYPE (expr
) = uprivate_record
;
5724 warning ("static access to object of type `id'");
5731 /* Implement @defs (<classname>) within struct bodies. */
5734 get_class_ivars (interface
)
5737 /* Make sure we copy the leaf ivars in case @defs is used in a local
5738 context. Otherwise finish_struct will overwrite the layout info
5739 using temporary storage. */
5740 return build_ivar_chain (interface
, 1);
5743 /* Make sure all entries in CHAIN are also in LIST. */
5746 check_methods (chain
, list
, mtype
)
5755 if (!lookup_method (list
, chain
))
5759 if (TREE_CODE (objc_implementation_context
)
5760 == CLASS_IMPLEMENTATION_TYPE
)
5761 warning ("incomplete implementation of class `%s'",
5762 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
)));
5763 else if (TREE_CODE (objc_implementation_context
)
5764 == CATEGORY_IMPLEMENTATION_TYPE
)
5765 warning ("incomplete implementation of category `%s'",
5766 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
5770 warning ("method definition for `%c%s' not found",
5771 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
5774 chain
= TREE_CHAIN (chain
);
5780 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
5783 conforms_to_protocol (class, protocol
)
5787 if (TREE_CODE (protocol
) == PROTOCOL_INTERFACE_TYPE
)
5789 tree p
= CLASS_PROTOCOL_LIST (class);
5790 while (p
&& TREE_VALUE (p
) != protocol
)
5795 tree super
= (CLASS_SUPER_NAME (class)
5796 ? lookup_interface (CLASS_SUPER_NAME (class))
5798 int tmp
= super
? conforms_to_protocol (super
, protocol
) : 0;
5807 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5808 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5811 check_methods_accessible (chain
, context
, mtype
)
5818 tree base_context
= context
;
5822 context
= base_context
;
5826 list
= CLASS_CLS_METHODS (context
);
5828 list
= CLASS_NST_METHODS (context
);
5830 if (lookup_method (list
, chain
))
5833 else if (TREE_CODE (context
) == CLASS_IMPLEMENTATION_TYPE
5834 || TREE_CODE (context
) == CLASS_INTERFACE_TYPE
)
5835 context
= (CLASS_SUPER_NAME (context
)
5836 ? lookup_interface (CLASS_SUPER_NAME (context
))
5839 else if (TREE_CODE (context
) == CATEGORY_IMPLEMENTATION_TYPE
5840 || TREE_CODE (context
) == CATEGORY_INTERFACE_TYPE
)
5841 context
= (CLASS_NAME (context
)
5842 ? lookup_interface (CLASS_NAME (context
))
5848 if (context
== NULL_TREE
)
5852 if (TREE_CODE (objc_implementation_context
)
5853 == CLASS_IMPLEMENTATION_TYPE
)
5854 warning ("incomplete implementation of class `%s'",
5856 (CLASS_NAME (objc_implementation_context
)));
5857 else if (TREE_CODE (objc_implementation_context
)
5858 == CATEGORY_IMPLEMENTATION_TYPE
)
5859 warning ("incomplete implementation of category `%s'",
5861 (CLASS_SUPER_NAME (objc_implementation_context
)));
5864 warning ("method definition for `%c%s' not found",
5865 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
5868 chain
= TREE_CHAIN (chain
); /* next method... */
5873 /* Check whether the current interface (accessible via
5874 'objc_implementation_context') actually implements protocol P, along
5875 with any protocols that P inherits. */
5878 check_protocol (p
, type
, name
)
5883 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
5887 /* Ensure that all protocols have bodies! */
5888 if (flag_warn_protocol
)
5890 f1
= check_methods (PROTOCOL_CLS_METHODS (p
),
5891 CLASS_CLS_METHODS (objc_implementation_context
),
5893 f2
= check_methods (PROTOCOL_NST_METHODS (p
),
5894 CLASS_NST_METHODS (objc_implementation_context
),
5899 f1
= check_methods_accessible (PROTOCOL_CLS_METHODS (p
),
5900 objc_implementation_context
,
5902 f2
= check_methods_accessible (PROTOCOL_NST_METHODS (p
),
5903 objc_implementation_context
,
5908 warning ("%s `%s' does not fully implement the `%s' protocol",
5909 type
, name
, IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
5912 /* Check protocols recursively. */
5913 if (PROTOCOL_LIST (p
))
5915 tree subs
= PROTOCOL_LIST (p
);
5917 lookup_interface (CLASS_SUPER_NAME (implementation_template
));
5921 tree sub
= TREE_VALUE (subs
);
5923 /* If the superclass does not conform to the protocols
5924 inherited by P, then we must! */
5925 if (!super_class
|| !conforms_to_protocol (super_class
, sub
))
5926 check_protocol (sub
, type
, name
);
5927 subs
= TREE_CHAIN (subs
);
5932 /* Check whether the current interface (accessible via
5933 'objc_implementation_context') actually implements the protocols listed
5937 check_protocols (proto_list
, type
, name
)
5942 for ( ; proto_list
; proto_list
= TREE_CHAIN (proto_list
))
5944 tree p
= TREE_VALUE (proto_list
);
5946 check_protocol (p
, type
, name
);
5950 /* Make sure that the class CLASS_NAME is defined
5951 CODE says which kind of thing CLASS_NAME ought to be.
5952 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
5953 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
5956 start_class (code
, class_name
, super_name
, protocol_list
)
5957 enum tree_code code
;
5964 if (objc_implementation_context
)
5966 warning ("`@end' missing in implementation context");
5967 finish_class (objc_implementation_context
);
5968 objc_ivar_chain
= NULL_TREE
;
5969 objc_implementation_context
= NULL_TREE
;
5972 class = make_node (code
);
5973 TYPE_BINFO (class) = make_tree_vec (5);
5975 CLASS_NAME (class) = class_name
;
5976 CLASS_SUPER_NAME (class) = super_name
;
5977 CLASS_CLS_METHODS (class) = NULL_TREE
;
5979 if (! is_class_name (class_name
) && (decl
= lookup_name (class_name
)))
5981 error ("`%s' redeclared as different kind of symbol",
5982 IDENTIFIER_POINTER (class_name
));
5983 error_with_decl (decl
, "previous declaration of `%s'");
5986 if (code
== CLASS_IMPLEMENTATION_TYPE
)
5991 for (chain
= implemented_classes
; chain
; chain
= TREE_CHAIN (chain
))
5992 if (TREE_VALUE (chain
) == class_name
)
5994 error ("reimplementation of class `%s'",
5995 IDENTIFIER_POINTER (class_name
));
5996 return error_mark_node
;
5998 implemented_classes
= tree_cons (NULL_TREE
, class_name
,
5999 implemented_classes
);
6002 /* Pre-build the following entities - for speed/convenience. */
6004 self_id
= get_identifier ("self");
6006 ucmd_id
= get_identifier ("_cmd");
6009 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6010 if (!objc_super_template
)
6011 objc_super_template
= build_super_template ();
6013 /* Reset for multiple classes per file. */
6016 objc_implementation_context
= class;
6018 /* Lookup the interface for this implementation. */
6020 if (!(implementation_template
= lookup_interface (class_name
)))
6022 warning ("cannot find interface declaration for `%s'",
6023 IDENTIFIER_POINTER (class_name
));
6024 add_class (implementation_template
= objc_implementation_context
);
6027 /* If a super class has been specified in the implementation,
6028 insure it conforms to the one specified in the interface. */
6031 && (super_name
!= CLASS_SUPER_NAME (implementation_template
)))
6033 tree previous_name
= CLASS_SUPER_NAME (implementation_template
);
6034 const char *const name
=
6035 previous_name
? IDENTIFIER_POINTER (previous_name
) : "";
6036 error ("conflicting super class name `%s'",
6037 IDENTIFIER_POINTER (super_name
));
6038 error ("previous declaration of `%s'", name
);
6041 else if (! super_name
)
6043 CLASS_SUPER_NAME (objc_implementation_context
)
6044 = CLASS_SUPER_NAME (implementation_template
);
6048 else if (code
== CLASS_INTERFACE_TYPE
)
6050 if (lookup_interface (class_name
))
6051 warning ("duplicate interface declaration for class `%s'",
6052 IDENTIFIER_POINTER (class_name
));
6057 CLASS_PROTOCOL_LIST (class)
6058 = lookup_and_install_protocols (protocol_list
);
6061 else if (code
== CATEGORY_INTERFACE_TYPE
)
6063 tree class_category_is_assoc_with
;
6065 /* For a category, class_name is really the name of the class that
6066 the following set of methods will be associated with. We must
6067 find the interface so that can derive the objects template. */
6069 if (!(class_category_is_assoc_with
= lookup_interface (class_name
)))
6071 error ("cannot find interface declaration for `%s'",
6072 IDENTIFIER_POINTER (class_name
));
6073 exit (FATAL_EXIT_CODE
);
6076 add_category (class_category_is_assoc_with
, class);
6079 CLASS_PROTOCOL_LIST (class)
6080 = lookup_and_install_protocols (protocol_list
);
6083 else if (code
== CATEGORY_IMPLEMENTATION_TYPE
)
6085 /* Pre-build the following entities for speed/convenience. */
6087 self_id
= get_identifier ("self");
6089 ucmd_id
= get_identifier ("_cmd");
6092 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6093 if (!objc_super_template
)
6094 objc_super_template
= build_super_template ();
6096 /* Reset for multiple classes per file. */
6099 objc_implementation_context
= class;
6101 /* For a category, class_name is really the name of the class that
6102 the following set of methods will be associated with. We must
6103 find the interface so that can derive the objects template. */
6105 if (!(implementation_template
= lookup_interface (class_name
)))
6107 error ("cannot find interface declaration for `%s'",
6108 IDENTIFIER_POINTER (class_name
));
6109 exit (FATAL_EXIT_CODE
);
6116 continue_class (class)
6119 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6120 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6122 struct imp_entry
*imp_entry
;
6125 /* Check consistency of the instance variables. */
6127 if (CLASS_IVARS (class))
6128 check_ivars (implementation_template
, class);
6130 /* code generation */
6132 ivar_context
= build_private_template (implementation_template
);
6134 if (!objc_class_template
)
6135 build_class_template ();
6137 imp_entry
= (struct imp_entry
*) ggc_alloc (sizeof (struct imp_entry
));
6139 imp_entry
->next
= imp_list
;
6140 imp_entry
->imp_context
= class;
6141 imp_entry
->imp_template
= implementation_template
;
6143 synth_forward_declarations ();
6144 imp_entry
->class_decl
= UOBJC_CLASS_decl
;
6145 imp_entry
->meta_decl
= UOBJC_METACLASS_decl
;
6147 /* Append to front and increment count. */
6148 imp_list
= imp_entry
;
6149 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6154 return ivar_context
;
6157 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6159 tree record
= xref_tag (RECORD_TYPE
, CLASS_NAME (class));
6161 if (!TYPE_FIELDS (record
))
6163 finish_struct (record
, build_ivar_chain (class, 0), NULL_TREE
);
6164 CLASS_STATIC_TEMPLATE (class) = record
;
6166 /* Mark this record as a class template for static typing. */
6167 TREE_STATIC_TEMPLATE (record
) = 1;
6174 return error_mark_node
;
6177 /* This is called once we see the "@end" in an interface/implementation. */
6180 finish_class (class)
6183 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6185 /* All code generation is done in finish_objc. */
6187 if (implementation_template
!= objc_implementation_context
)
6189 /* Ensure that all method listed in the interface contain bodies. */
6190 check_methods (CLASS_CLS_METHODS (implementation_template
),
6191 CLASS_CLS_METHODS (objc_implementation_context
), '+');
6192 check_methods (CLASS_NST_METHODS (implementation_template
),
6193 CLASS_NST_METHODS (objc_implementation_context
), '-');
6195 if (CLASS_PROTOCOL_LIST (implementation_template
))
6196 check_protocols (CLASS_PROTOCOL_LIST (implementation_template
),
6198 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
)));
6202 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6204 tree category
= CLASS_CATEGORY_LIST (implementation_template
);
6206 /* Find the category interface from the class it is associated with. */
6209 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category
))
6211 category
= CLASS_CATEGORY_LIST (category
);
6216 /* Ensure all method listed in the interface contain bodies. */
6217 check_methods (CLASS_CLS_METHODS (category
),
6218 CLASS_CLS_METHODS (objc_implementation_context
), '+');
6219 check_methods (CLASS_NST_METHODS (category
),
6220 CLASS_NST_METHODS (objc_implementation_context
), '-');
6222 if (CLASS_PROTOCOL_LIST (category
))
6223 check_protocols (CLASS_PROTOCOL_LIST (category
),
6225 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
6229 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6232 const char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (class));
6233 char *string
= (char *) alloca (strlen (class_name
) + 3);
6235 /* extern struct objc_object *_<my_name>; */
6237 sprintf (string
, "_%s", class_name
);
6239 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
6240 decl_specs
= tree_cons (NULL_TREE
, objc_object_reference
, decl_specs
);
6241 define_decl (build1 (INDIRECT_REF
, NULL_TREE
, get_identifier (string
)),
6247 add_protocol (protocol
)
6250 /* Put protocol on list in reverse order. */
6251 TREE_CHAIN (protocol
) = protocol_chain
;
6252 protocol_chain
= protocol
;
6253 return protocol_chain
;
6257 lookup_protocol (ident
)
6262 for (chain
= protocol_chain
; chain
; chain
= TREE_CHAIN (chain
))
6263 if (ident
== PROTOCOL_NAME (chain
))
6269 /* This function forward declares the protocols named by NAMES. If
6270 they are already declared or defined, the function has no effect. */
6273 objc_declare_protocols (names
)
6278 for (list
= names
; list
; list
= TREE_CHAIN (list
))
6280 tree name
= TREE_VALUE (list
);
6282 if (lookup_protocol (name
) == NULL_TREE
)
6284 tree protocol
= make_node (PROTOCOL_INTERFACE_TYPE
);
6286 TYPE_BINFO (protocol
) = make_tree_vec (2);
6287 PROTOCOL_NAME (protocol
) = name
;
6288 PROTOCOL_LIST (protocol
) = NULL_TREE
;
6289 add_protocol (protocol
);
6290 PROTOCOL_DEFINED (protocol
) = 0;
6291 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6297 start_protocol (code
, name
, list
)
6298 enum tree_code code
;
6304 /* This is as good a place as any. Need to invoke
6305 push_tag_toplevel. */
6306 if (!objc_protocol_template
)
6307 objc_protocol_template
= build_protocol_template ();
6309 protocol
= lookup_protocol (name
);
6313 protocol
= make_node (code
);
6314 TYPE_BINFO (protocol
) = make_tree_vec (2);
6316 PROTOCOL_NAME (protocol
) = name
;
6317 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
6318 add_protocol (protocol
);
6319 PROTOCOL_DEFINED (protocol
) = 1;
6320 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6322 check_protocol_recursively (protocol
, list
);
6324 else if (! PROTOCOL_DEFINED (protocol
))
6326 PROTOCOL_DEFINED (protocol
) = 1;
6327 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
6329 check_protocol_recursively (protocol
, list
);
6333 warning ("duplicate declaration for protocol `%s'",
6334 IDENTIFIER_POINTER (name
));
6340 finish_protocol (protocol
)
6341 tree protocol ATTRIBUTE_UNUSED
;
6346 /* "Encode" a data type into a string, which grows in util_obstack.
6347 ??? What is the FORMAT? Someone please document this! */
6350 encode_type_qualifiers (declspecs
)
6355 for (spec
= declspecs
; spec
; spec
= TREE_CHAIN (spec
))
6357 if (ridpointers
[(int) RID_CONST
] == TREE_VALUE (spec
))
6358 obstack_1grow (&util_obstack
, 'r');
6359 else if (ridpointers
[(int) RID_IN
] == TREE_VALUE (spec
))
6360 obstack_1grow (&util_obstack
, 'n');
6361 else if (ridpointers
[(int) RID_INOUT
] == TREE_VALUE (spec
))
6362 obstack_1grow (&util_obstack
, 'N');
6363 else if (ridpointers
[(int) RID_OUT
] == TREE_VALUE (spec
))
6364 obstack_1grow (&util_obstack
, 'o');
6365 else if (ridpointers
[(int) RID_BYCOPY
] == TREE_VALUE (spec
))
6366 obstack_1grow (&util_obstack
, 'O');
6367 else if (ridpointers
[(int) RID_BYREF
] == TREE_VALUE (spec
))
6368 obstack_1grow (&util_obstack
, 'R');
6369 else if (ridpointers
[(int) RID_ONEWAY
] == TREE_VALUE (spec
))
6370 obstack_1grow (&util_obstack
, 'V');
6374 /* Encode a pointer type. */
6377 encode_pointer (type
, curtype
, format
)
6382 tree pointer_to
= TREE_TYPE (type
);
6384 if (TREE_CODE (pointer_to
) == RECORD_TYPE
)
6386 if (TYPE_NAME (pointer_to
)
6387 && TREE_CODE (TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
)
6389 const char *name
= IDENTIFIER_POINTER (TYPE_NAME (pointer_to
));
6391 if (strcmp (name
, TAG_OBJECT
) == 0) /* '@' */
6393 obstack_1grow (&util_obstack
, '@');
6396 else if (TREE_STATIC_TEMPLATE (pointer_to
))
6398 if (generating_instance_variables
)
6400 obstack_1grow (&util_obstack
, '@');
6401 obstack_1grow (&util_obstack
, '"');
6402 obstack_grow (&util_obstack
, name
, strlen (name
));
6403 obstack_1grow (&util_obstack
, '"');
6408 obstack_1grow (&util_obstack
, '@');
6412 else if (strcmp (name
, TAG_CLASS
) == 0) /* '#' */
6414 obstack_1grow (&util_obstack
, '#');
6417 else if (strcmp (name
, TAG_SELECTOR
) == 0) /* ':' */
6419 obstack_1grow (&util_obstack
, ':');
6424 else if (TREE_CODE (pointer_to
) == INTEGER_TYPE
6425 && TYPE_MODE (pointer_to
) == QImode
)
6427 obstack_1grow (&util_obstack
, '*');
6431 /* We have a type that does not get special treatment. */
6433 /* NeXT extension */
6434 obstack_1grow (&util_obstack
, '^');
6435 encode_type (pointer_to
, curtype
, format
);
6439 encode_array (type
, curtype
, format
)
6444 tree an_int_cst
= TYPE_SIZE (type
);
6445 tree array_of
= TREE_TYPE (type
);
6448 /* An incomplete array is treated like a pointer. */
6449 if (an_int_cst
== NULL
)
6451 encode_pointer (type
, curtype
, format
);
6455 sprintf (buffer
, "[%ld",
6456 (long) (TREE_INT_CST_LOW (an_int_cst
)
6457 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
6459 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6460 encode_type (array_of
, curtype
, format
);
6461 obstack_1grow (&util_obstack
, ']');
6466 encode_aggregate_within (type
, curtype
, format
, left
, right
)
6473 /* The RECORD_TYPE may in fact be a typedef! For purposes
6474 of encoding, we need the real underlying enchilada. */
6475 if (TYPE_MAIN_VARIANT (type
))
6476 type
= TYPE_MAIN_VARIANT (type
);
6478 if (obstack_object_size (&util_obstack
) > 0
6479 && *(obstack_next_free (&util_obstack
) - 1) == '^')
6481 tree name
= TYPE_NAME (type
);
6483 /* we have a reference; this is a NeXT extension. */
6485 if (obstack_object_size (&util_obstack
) - curtype
== 1
6486 && format
== OBJC_ENCODE_INLINE_DEFS
)
6488 /* Output format of struct for first level only. */
6489 tree fields
= TYPE_FIELDS (type
);
6491 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6493 obstack_1grow (&util_obstack
, left
);
6494 obstack_grow (&util_obstack
,
6495 IDENTIFIER_POINTER (name
),
6496 strlen (IDENTIFIER_POINTER (name
)));
6497 obstack_1grow (&util_obstack
, '=');
6501 obstack_1grow (&util_obstack
, left
);
6502 obstack_grow (&util_obstack
, "?=", 2);
6505 for ( ; fields
; fields
= TREE_CHAIN (fields
))
6506 encode_field_decl (fields
, curtype
, format
);
6508 obstack_1grow (&util_obstack
, right
);
6511 else if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6513 obstack_1grow (&util_obstack
, left
);
6514 obstack_grow (&util_obstack
,
6515 IDENTIFIER_POINTER (name
),
6516 strlen (IDENTIFIER_POINTER (name
)));
6517 obstack_1grow (&util_obstack
, right
);
6522 /* We have an untagged structure or a typedef. */
6523 obstack_1grow (&util_obstack
, left
);
6524 obstack_1grow (&util_obstack
, '?');
6525 obstack_1grow (&util_obstack
, right
);
6531 tree name
= TYPE_NAME (type
);
6532 tree fields
= TYPE_FIELDS (type
);
6534 if (format
== OBJC_ENCODE_INLINE_DEFS
6535 || generating_instance_variables
)
6537 obstack_1grow (&util_obstack
, left
);
6538 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6539 obstack_grow (&util_obstack
,
6540 IDENTIFIER_POINTER (name
),
6541 strlen (IDENTIFIER_POINTER (name
)));
6543 obstack_1grow (&util_obstack
, '?');
6545 obstack_1grow (&util_obstack
, '=');
6547 for (; fields
; fields
= TREE_CHAIN (fields
))
6549 if (generating_instance_variables
)
6551 tree fname
= DECL_NAME (fields
);
6553 obstack_1grow (&util_obstack
, '"');
6554 if (fname
&& TREE_CODE (fname
) == IDENTIFIER_NODE
)
6556 obstack_grow (&util_obstack
,
6557 IDENTIFIER_POINTER (fname
),
6558 strlen (IDENTIFIER_POINTER (fname
)));
6561 obstack_1grow (&util_obstack
, '"');
6564 encode_field_decl (fields
, curtype
, format
);
6567 obstack_1grow (&util_obstack
, right
);
6572 obstack_1grow (&util_obstack
, left
);
6573 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6574 obstack_grow (&util_obstack
,
6575 IDENTIFIER_POINTER (name
),
6576 strlen (IDENTIFIER_POINTER (name
)));
6578 /* We have an untagged structure or a typedef. */
6579 obstack_1grow (&util_obstack
, '?');
6581 obstack_1grow (&util_obstack
, right
);
6587 encode_aggregate (type
, curtype
, format
)
6592 enum tree_code code
= TREE_CODE (type
);
6598 encode_aggregate_within(type
, curtype
, format
, '{', '}');
6603 encode_aggregate_within(type
, curtype
, format
, '(', ')');
6608 obstack_1grow (&util_obstack
, 'i');
6616 /* Support bitfields. The current version of Objective-C does not support
6617 them. The string will consist of one or more "b:n"'s where n is an
6618 integer describing the width of the bitfield. Currently, classes in
6619 the kit implement a method "-(char *)describeBitfieldStruct:" that
6620 simulates this. If they do not implement this method, the archiver
6621 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6622 according to the GNU compiler. After looking at the "kit", it appears
6623 that all classes currently rely on this default behavior, rather than
6624 hand generating this string (which is tedious). */
6627 encode_bitfield (width
)
6631 sprintf (buffer
, "b%d", width
);
6632 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6635 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6638 encode_type (type
, curtype
, format
)
6643 enum tree_code code
= TREE_CODE (type
);
6645 if (code
== INTEGER_TYPE
)
6647 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6649 /* Unsigned integer types. */
6651 if (TYPE_MODE (type
) == QImode
)
6652 obstack_1grow (&util_obstack
, 'C');
6653 else if (TYPE_MODE (type
) == HImode
)
6654 obstack_1grow (&util_obstack
, 'S');
6655 else if (TYPE_MODE (type
) == SImode
)
6657 if (type
== long_unsigned_type_node
)
6658 obstack_1grow (&util_obstack
, 'L');
6660 obstack_1grow (&util_obstack
, 'I');
6662 else if (TYPE_MODE (type
) == DImode
)
6663 obstack_1grow (&util_obstack
, 'Q');
6667 /* Signed integer types. */
6669 if (TYPE_MODE (type
) == QImode
)
6670 obstack_1grow (&util_obstack
, 'c');
6671 else if (TYPE_MODE (type
) == HImode
)
6672 obstack_1grow (&util_obstack
, 's');
6673 else if (TYPE_MODE (type
) == SImode
)
6675 if (type
== long_integer_type_node
)
6676 obstack_1grow (&util_obstack
, 'l');
6678 obstack_1grow (&util_obstack
, 'i');
6681 else if (TYPE_MODE (type
) == DImode
)
6682 obstack_1grow (&util_obstack
, 'q');
6686 else if (code
== REAL_TYPE
)
6688 /* Floating point types. */
6690 if (TYPE_MODE (type
) == SFmode
)
6691 obstack_1grow (&util_obstack
, 'f');
6692 else if (TYPE_MODE (type
) == DFmode
6693 || TYPE_MODE (type
) == TFmode
)
6694 obstack_1grow (&util_obstack
, 'd');
6697 else if (code
== VOID_TYPE
)
6698 obstack_1grow (&util_obstack
, 'v');
6700 else if (code
== ARRAY_TYPE
)
6701 encode_array (type
, curtype
, format
);
6703 else if (code
== POINTER_TYPE
)
6704 encode_pointer (type
, curtype
, format
);
6706 else if (code
== RECORD_TYPE
|| code
== UNION_TYPE
|| code
== ENUMERAL_TYPE
)
6707 encode_aggregate (type
, curtype
, format
);
6709 else if (code
== FUNCTION_TYPE
) /* '?' */
6710 obstack_1grow (&util_obstack
, '?');
6714 encode_complete_bitfield (int position
, tree type
, int size
)
6716 enum tree_code code
= TREE_CODE (type
);
6718 char charType
= '?';
6720 if (code
== INTEGER_TYPE
)
6722 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6724 /* Unsigned integer types. */
6726 if (TYPE_MODE (type
) == QImode
)
6728 else if (TYPE_MODE (type
) == HImode
)
6730 else if (TYPE_MODE (type
) == SImode
)
6732 if (type
== long_unsigned_type_node
)
6737 else if (TYPE_MODE (type
) == DImode
)
6742 /* Signed integer types. */
6744 if (TYPE_MODE (type
) == QImode
)
6746 else if (TYPE_MODE (type
) == HImode
)
6748 else if (TYPE_MODE (type
) == SImode
)
6750 if (type
== long_integer_type_node
)
6756 else if (TYPE_MODE (type
) == DImode
)
6760 else if (code
== ENUMERAL_TYPE
)
6765 sprintf (buffer
, "b%d%c%d", position
, charType
, size
);
6766 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6770 encode_field_decl (field_decl
, curtype
, format
)
6777 type
= TREE_TYPE (field_decl
);
6779 /* If this field is obviously a bitfield, or is a bitfield that has been
6780 clobbered to look like a ordinary integer mode, go ahead and generate
6781 the bitfield typing information. */
6782 if (flag_next_runtime
)
6784 if (DECL_BIT_FIELD (field_decl
))
6785 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl
), 1));
6787 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6791 if (DECL_BIT_FIELD (field_decl
))
6792 encode_complete_bitfield (int_bit_position (field_decl
),
6793 DECL_BIT_FIELD_TYPE (field_decl
),
6794 tree_low_cst (DECL_SIZE (field_decl
), 1));
6796 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6801 expr_last (complex_expr
)
6807 while ((next
= TREE_OPERAND (complex_expr
, 0)))
6808 complex_expr
= next
;
6810 return complex_expr
;
6813 /* Transform a method definition into a function definition as follows:
6814 - synthesize the first two arguments, "self" and "_cmd". */
6817 start_method_def (method
)
6822 /* Required to implement _msgSuper. */
6823 objc_method_context
= method
;
6824 UOBJC_SUPER_decl
= NULL_TREE
;
6826 /* Must be called BEFORE start_function. */
6829 /* Generate prototype declarations for arguments..."new-style". */
6831 if (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
)
6832 decl_specs
= build_tree_list (NULL_TREE
, uprivate_record
);
6834 /* Really a `struct objc_class *'. However, we allow people to
6835 assign to self, which changes its type midstream. */
6836 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
6838 push_parm_decl (build_tree_list
6839 (build_tree_list (decl_specs
,
6840 build1 (INDIRECT_REF
, NULL_TREE
, self_id
)),
6843 decl_specs
= build_tree_list (NULL_TREE
,
6844 xref_tag (RECORD_TYPE
,
6845 get_identifier (TAG_SELECTOR
)));
6846 push_parm_decl (build_tree_list
6847 (build_tree_list (decl_specs
,
6848 build1 (INDIRECT_REF
, NULL_TREE
, ucmd_id
)),
6851 /* Generate argument declarations if a keyword_decl. */
6852 if (METHOD_SEL_ARGS (method
))
6854 tree arglist
= METHOD_SEL_ARGS (method
);
6857 tree arg_spec
= TREE_PURPOSE (TREE_TYPE (arglist
));
6858 tree arg_decl
= TREE_VALUE (TREE_TYPE (arglist
));
6862 tree last_expr
= expr_last (arg_decl
);
6864 /* Unite the abstract decl with its name. */
6865 TREE_OPERAND (last_expr
, 0) = KEYWORD_ARG_NAME (arglist
);
6866 push_parm_decl (build_tree_list
6867 (build_tree_list (arg_spec
, arg_decl
),
6870 /* Unhook: restore the abstract declarator. */
6871 TREE_OPERAND (last_expr
, 0) = NULL_TREE
;
6875 push_parm_decl (build_tree_list
6876 (build_tree_list (arg_spec
,
6877 KEYWORD_ARG_NAME (arglist
)),
6880 arglist
= TREE_CHAIN (arglist
);
6885 if (METHOD_ADD_ARGS (method
) != NULL_TREE
6886 && METHOD_ADD_ARGS (method
) != objc_ellipsis_node
)
6888 /* We have a variable length selector - in "prototype" format. */
6889 tree akey
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
6892 /* This must be done prior to calling pushdecl. pushdecl is
6893 going to change our chain on us. */
6894 tree nextkey
= TREE_CHAIN (akey
);
6902 warn_with_method (message
, mtype
, method
)
6903 const char *message
;
6907 if (!diagnostic_count_diagnostic (global_dc
, DK_WARNING
))
6910 diagnostic_report_current_function (global_dc
);
6912 /* Add a readable method name to the warning. */
6913 warning_with_file_and_line (DECL_SOURCE_FILE (method
),
6914 DECL_SOURCE_LINE (method
),
6917 gen_method_decl (method
, errbuf
));
6920 /* Return 1 if METHOD is consistent with PROTO. */
6923 comp_method_with_proto (method
, proto
)
6926 /* Create a function template node at most once. */
6927 if (!function1_template
)
6928 function1_template
= make_node (FUNCTION_TYPE
);
6930 /* Install argument types - normally set by build_function_type. */
6931 TYPE_ARG_TYPES (function1_template
) = get_arg_type_list (proto
, METHOD_DEF
, 0);
6933 /* install return type */
6934 TREE_TYPE (function1_template
) = groktypename (TREE_TYPE (proto
));
6936 return comptypes (TREE_TYPE (METHOD_DEFINITION (method
)), function1_template
);
6939 /* Return 1 if PROTO1 is consistent with PROTO2. */
6942 comp_proto_with_proto (proto0
, proto1
)
6943 tree proto0
, proto1
;
6945 /* Create a couple of function_template nodes at most once. */
6946 if (!function1_template
)
6947 function1_template
= make_node (FUNCTION_TYPE
);
6948 if (!function2_template
)
6949 function2_template
= make_node (FUNCTION_TYPE
);
6951 /* Install argument types; normally set by build_function_type. */
6952 TYPE_ARG_TYPES (function1_template
) = get_arg_type_list (proto0
, METHOD_REF
, 0);
6953 TYPE_ARG_TYPES (function2_template
) = get_arg_type_list (proto1
, METHOD_REF
, 0);
6955 /* Install return type. */
6956 TREE_TYPE (function1_template
) = groktypename (TREE_TYPE (proto0
));
6957 TREE_TYPE (function2_template
) = groktypename (TREE_TYPE (proto1
));
6959 return comptypes (function1_template
, function2_template
);
6962 /* - Generate an identifier for the function. the format is "_n_cls",
6963 where 1 <= n <= nMethods, and cls is the name the implementation we
6965 - Install the return type from the method declaration.
6966 - If we have a prototype, check for type consistency. */
6969 really_start_method (method
, parmlist
)
6970 tree method
, parmlist
;
6972 tree sc_spec
, ret_spec
, ret_decl
, decl_specs
;
6973 tree method_decl
, method_id
;
6974 const char *sel_name
, *class_name
, *cat_name
;
6977 /* Synth the storage class & assemble the return type. */
6978 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
6979 ret_spec
= TREE_PURPOSE (TREE_TYPE (method
));
6980 decl_specs
= chainon (sc_spec
, ret_spec
);
6982 sel_name
= IDENTIFIER_POINTER (METHOD_SEL_NAME (method
));
6983 class_name
= IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
6984 cat_name
= ((TREE_CODE (objc_implementation_context
)
6985 == CLASS_IMPLEMENTATION_TYPE
)
6987 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
6990 /* Make sure this is big enough for any plausible method label. */
6991 buf
= (char *) alloca (50 + strlen (sel_name
) + strlen (class_name
)
6992 + (cat_name
? strlen (cat_name
) : 0));
6994 OBJC_GEN_METHOD_LABEL (buf
, TREE_CODE (method
) == INSTANCE_METHOD_DECL
,
6995 class_name
, cat_name
, sel_name
, method_slot
);
6997 method_id
= get_identifier (buf
);
6999 method_decl
= build_nt (CALL_EXPR
, method_id
, parmlist
, NULL_TREE
);
7001 /* Check the declarator portion of the return type for the method. */
7002 if ((ret_decl
= TREE_VALUE (TREE_TYPE (method
))))
7004 /* Unite the complex decl (specified in the abstract decl) with the
7005 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7006 tree save_expr
= expr_last (ret_decl
);
7008 TREE_OPERAND (save_expr
, 0) = method_decl
;
7009 method_decl
= ret_decl
;
7011 /* Fool the parser into thinking it is starting a function. */
7012 start_function (decl_specs
, method_decl
, NULL_TREE
);
7014 /* Unhook: this has the effect of restoring the abstract declarator. */
7015 TREE_OPERAND (save_expr
, 0) = NULL_TREE
;
7020 TREE_VALUE (TREE_TYPE (method
)) = method_decl
;
7022 /* Fool the parser into thinking it is starting a function. */
7023 start_function (decl_specs
, method_decl
, NULL_TREE
);
7025 /* Unhook: this has the effect of restoring the abstract declarator. */
7026 TREE_VALUE (TREE_TYPE (method
)) = NULL_TREE
;
7029 METHOD_DEFINITION (method
) = current_function_decl
;
7031 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7033 if (implementation_template
!= objc_implementation_context
)
7037 if (TREE_CODE (method
) == INSTANCE_METHOD_DECL
)
7038 proto
= lookup_instance_method_static (implementation_template
,
7039 METHOD_SEL_NAME (method
));
7041 proto
= lookup_class_method_static (implementation_template
,
7042 METHOD_SEL_NAME (method
));
7044 if (proto
&& ! comp_method_with_proto (method
, proto
))
7046 char type
= (TREE_CODE (method
) == INSTANCE_METHOD_DECL
? '-' : '+');
7048 warn_with_method ("conflicting types for", type
, method
);
7049 warn_with_method ("previous declaration of", type
, proto
);
7054 /* The following routine is always called...this "architecture" is to
7055 accommodate "old-style" variable length selectors.
7057 - a:a b:b // prototype ; id c; id d; // old-style. */
7060 continue_method_def ()
7064 if (METHOD_ADD_ARGS (objc_method_context
) == objc_ellipsis_node
)
7065 /* We have a `, ...' immediately following the selector. */
7066 parmlist
= get_parm_info (0);
7068 parmlist
= get_parm_info (1); /* place a `void_at_end' */
7070 /* Set self_decl from the first argument...this global is used by
7071 build_ivar_reference calling build_indirect_ref. */
7072 self_decl
= TREE_PURPOSE (parmlist
);
7075 really_start_method (objc_method_context
, parmlist
);
7076 store_parm_decls ();
7079 /* Called by the parser, from the `pushlevel' production. */
7084 if (!UOBJC_SUPER_decl
)
7086 UOBJC_SUPER_decl
= start_decl (get_identifier (UTAG_SUPER
),
7087 build_tree_list (NULL_TREE
,
7088 objc_super_template
),
7091 finish_decl (UOBJC_SUPER_decl
, NULL_TREE
, NULL_TREE
);
7093 /* This prevents `unused variable' warnings when compiling with -Wall. */
7094 TREE_USED (UOBJC_SUPER_decl
) = 1;
7095 DECL_ARTIFICIAL (UOBJC_SUPER_decl
) = 1;
7099 /* _n_Method (id self, SEL sel, ...)
7101 struct objc_super _S;
7102 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7106 get_super_receiver ()
7108 if (objc_method_context
)
7110 tree super_expr
, super_expr_list
;
7112 /* Set receiver to self. */
7113 super_expr
= build_component_ref (UOBJC_SUPER_decl
, self_id
);
7114 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, self_decl
);
7115 super_expr_list
= build_tree_list (NULL_TREE
, super_expr
);
7117 /* Set class to begin searching. */
7118 super_expr
= build_component_ref (UOBJC_SUPER_decl
,
7119 get_identifier ("class"));
7121 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
7123 /* [_cls, __cls]Super are "pre-built" in
7124 synth_forward_declarations. */
7126 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
,
7127 ((TREE_CODE (objc_method_context
)
7128 == INSTANCE_METHOD_DECL
)
7130 : uucls_super_ref
));
7134 /* We have a category. */
7136 tree super_name
= CLASS_SUPER_NAME (implementation_template
);
7139 /* Barf if super used in a category of Object. */
7142 error ("no super class declared in interface for `%s'",
7143 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
7144 return error_mark_node
;
7147 if (flag_next_runtime
)
7149 super_class
= get_class_reference (super_name
);
7150 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
7152 = build_component_ref (build_indirect_ref (super_class
, "->"),
7153 get_identifier ("isa"));
7157 add_class_reference (super_name
);
7158 super_class
= (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
7159 ? objc_get_class_decl
: objc_get_meta_class_decl
);
7160 assemble_external (super_class
);
7162 = build_function_call
7166 my_build_string (IDENTIFIER_LENGTH (super_name
) + 1,
7167 IDENTIFIER_POINTER (super_name
))));
7170 TREE_TYPE (super_class
) = TREE_TYPE (ucls_super_ref
);
7171 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, super_class
);
7174 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7176 super_expr
= build_unary_op (ADDR_EXPR
, UOBJC_SUPER_decl
, 0);
7177 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7179 return build_compound_expr (super_expr_list
);
7183 error ("[super ...] must appear in a method context");
7184 return error_mark_node
;
7189 encode_method_def (func_decl
)
7194 HOST_WIDE_INT max_parm_end
= 0;
7199 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
7200 obstack_object_size (&util_obstack
),
7201 OBJC_ENCODE_INLINE_DEFS
);
7204 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7205 parms
= TREE_CHAIN (parms
))
7207 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
7208 + int_size_in_bytes (TREE_TYPE (parms
)));
7210 if (! offset_is_register
&& parm_end
> max_parm_end
)
7211 max_parm_end
= parm_end
;
7214 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
7216 sprintf (buffer
, "%d", stack_size
);
7217 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7219 /* Argument types. */
7220 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7221 parms
= TREE_CHAIN (parms
))
7224 encode_type (TREE_TYPE (parms
),
7225 obstack_object_size (&util_obstack
),
7226 OBJC_ENCODE_INLINE_DEFS
);
7228 /* Compute offset. */
7229 sprintf (buffer
, "%d", forwarding_offset (parms
));
7231 /* Indicate register. */
7232 if (offset_is_register
)
7233 obstack_1grow (&util_obstack
, '+');
7235 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7238 /* Null terminate string. */
7239 obstack_1grow (&util_obstack
, 0);
7240 result
= get_identifier (obstack_finish (&util_obstack
));
7241 obstack_free (&util_obstack
, util_firstobj
);
7246 objc_expand_function_end ()
7248 METHOD_ENCODING (objc_method_context
) = encode_method_def (current_function_decl
);
7252 finish_method_def ()
7254 lang_expand_function_end
= objc_expand_function_end
;
7255 finish_function (0, 1);
7256 lang_expand_function_end
= NULL
;
7258 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7259 since the optimizer may find "may be used before set" errors. */
7260 objc_method_context
= NULL_TREE
;
7265 lang_report_error_function (decl
)
7268 if (objc_method_context
)
7270 fprintf (stderr
, "In method `%s'\n",
7271 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context
)));
7281 is_complex_decl (type
)
7284 return (TREE_CODE (type
) == ARRAY_TYPE
7285 || TREE_CODE (type
) == FUNCTION_TYPE
7286 || (TREE_CODE (type
) == POINTER_TYPE
&& ! IS_ID (type
)));
7290 /* Code to convert a decl node into text for a declaration in C. */
7292 static char tmpbuf
[256];
7295 adorn_decl (decl
, str
)
7299 enum tree_code code
= TREE_CODE (decl
);
7301 if (code
== ARRAY_REF
)
7303 tree an_int_cst
= TREE_OPERAND (decl
, 1);
7305 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_CST
)
7306 sprintf (str
+ strlen (str
), "[%ld]",
7307 (long) TREE_INT_CST_LOW (an_int_cst
));
7312 else if (code
== ARRAY_TYPE
)
7314 tree an_int_cst
= TYPE_SIZE (decl
);
7315 tree array_of
= TREE_TYPE (decl
);
7317 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_TYPE
)
7318 sprintf (str
+ strlen (str
), "[%ld]",
7319 (long) (TREE_INT_CST_LOW (an_int_cst
)
7320 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
7325 else if (code
== CALL_EXPR
)
7327 tree chain
= TREE_PURPOSE (TREE_OPERAND (decl
, 1));
7332 gen_declaration_1 (chain
, str
);
7333 chain
= TREE_CHAIN (chain
);
7340 else if (code
== FUNCTION_TYPE
)
7342 tree chain
= TYPE_ARG_TYPES (decl
);
7345 while (chain
&& TREE_VALUE (chain
) != void_type_node
)
7347 gen_declaration_1 (TREE_VALUE (chain
), str
);
7348 chain
= TREE_CHAIN (chain
);
7349 if (chain
&& TREE_VALUE (chain
) != void_type_node
)
7355 else if (code
== INDIRECT_REF
)
7357 strcpy (tmpbuf
, "*");
7358 if (TREE_TYPE (decl
) && TREE_CODE (TREE_TYPE (decl
)) == TREE_LIST
)
7362 for (chain
= nreverse (copy_list (TREE_TYPE (decl
)));
7364 chain
= TREE_CHAIN (chain
))
7366 if (TREE_CODE (TREE_VALUE (chain
)) == IDENTIFIER_NODE
)
7368 strcat (tmpbuf
, " ");
7369 strcat (tmpbuf
, IDENTIFIER_POINTER (TREE_VALUE (chain
)));
7373 strcat (tmpbuf
, " ");
7375 strcat (tmpbuf
, str
);
7376 strcpy (str
, tmpbuf
);
7379 else if (code
== POINTER_TYPE
)
7381 strcpy (tmpbuf
, "*");
7382 if (TREE_READONLY (decl
) || TYPE_VOLATILE (decl
))
7384 if (TREE_READONLY (decl
))
7385 strcat (tmpbuf
, " const");
7386 if (TYPE_VOLATILE (decl
))
7387 strcat (tmpbuf
, " volatile");
7389 strcat (tmpbuf
, " ");
7391 strcat (tmpbuf
, str
);
7392 strcpy (str
, tmpbuf
);
7397 gen_declarator (decl
, buf
, name
)
7404 enum tree_code code
= TREE_CODE (decl
);
7414 op
= TREE_OPERAND (decl
, 0);
7416 /* We have a pointer to a function or array...(*)(), (*)[] */
7417 if ((code
== ARRAY_REF
|| code
== CALL_EXPR
)
7418 && op
&& TREE_CODE (op
) == INDIRECT_REF
)
7421 str
= gen_declarator (op
, buf
, name
);
7425 strcpy (tmpbuf
, "(");
7426 strcat (tmpbuf
, str
);
7427 strcat (tmpbuf
, ")");
7428 strcpy (str
, tmpbuf
);
7431 adorn_decl (decl
, str
);
7440 /* This clause is done iteratively rather than recursively. */
7443 op
= (is_complex_decl (TREE_TYPE (decl
))
7444 ? TREE_TYPE (decl
) : NULL_TREE
);
7446 adorn_decl (decl
, str
);
7448 /* We have a pointer to a function or array...(*)(), (*)[] */
7449 if (code
== POINTER_TYPE
7450 && op
&& (TREE_CODE (op
) == FUNCTION_TYPE
7451 || TREE_CODE (op
) == ARRAY_TYPE
))
7453 strcpy (tmpbuf
, "(");
7454 strcat (tmpbuf
, str
);
7455 strcat (tmpbuf
, ")");
7456 strcpy (str
, tmpbuf
);
7459 decl
= (is_complex_decl (TREE_TYPE (decl
))
7460 ? TREE_TYPE (decl
) : NULL_TREE
);
7463 while (decl
&& (code
= TREE_CODE (decl
)))
7468 case IDENTIFIER_NODE
:
7469 /* Will only happen if we are processing a "raw" expr-decl. */
7470 strcpy (buf
, IDENTIFIER_POINTER (decl
));
7481 /* We have an abstract declarator or a _DECL node. */
7489 gen_declspecs (declspecs
, buf
, raw
)
7498 for (chain
= nreverse (copy_list (declspecs
));
7499 chain
; chain
= TREE_CHAIN (chain
))
7501 tree aspec
= TREE_VALUE (chain
);
7503 if (TREE_CODE (aspec
) == IDENTIFIER_NODE
)
7504 strcat (buf
, IDENTIFIER_POINTER (aspec
));
7505 else if (TREE_CODE (aspec
) == RECORD_TYPE
)
7507 if (TYPE_NAME (aspec
))
7509 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7511 if (! TREE_STATIC_TEMPLATE (aspec
))
7512 strcat (buf
, "struct ");
7513 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7518 tree chain
= protocol_list
;
7525 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7526 chain
= TREE_CHAIN (chain
);
7535 strcat (buf
, "untagged struct");
7538 else if (TREE_CODE (aspec
) == UNION_TYPE
)
7540 if (TYPE_NAME (aspec
))
7542 if (! TREE_STATIC_TEMPLATE (aspec
))
7543 strcat (buf
, "union ");
7544 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7547 strcat (buf
, "untagged union");
7550 else if (TREE_CODE (aspec
) == ENUMERAL_TYPE
)
7552 if (TYPE_NAME (aspec
))
7554 if (! TREE_STATIC_TEMPLATE (aspec
))
7555 strcat (buf
, "enum ");
7556 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7559 strcat (buf
, "untagged enum");
7562 else if (TREE_CODE (aspec
) == TYPE_DECL
&& DECL_NAME (aspec
))
7563 strcat (buf
, IDENTIFIER_POINTER (DECL_NAME (aspec
)));
7565 else if (IS_ID (aspec
))
7567 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7572 tree chain
= protocol_list
;
7579 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7580 chain
= TREE_CHAIN (chain
);
7587 if (TREE_CHAIN (chain
))
7593 /* Type qualifiers. */
7594 if (TREE_READONLY (declspecs
))
7595 strcat (buf
, "const ");
7596 if (TYPE_VOLATILE (declspecs
))
7597 strcat (buf
, "volatile ");
7599 switch (TREE_CODE (declspecs
))
7601 /* Type specifiers. */
7604 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7606 /* Signed integer types. */
7608 if (declspecs
== short_integer_type_node
)
7609 strcat (buf
, "short int ");
7610 else if (declspecs
== integer_type_node
)
7611 strcat (buf
, "int ");
7612 else if (declspecs
== long_integer_type_node
)
7613 strcat (buf
, "long int ");
7614 else if (declspecs
== long_long_integer_type_node
)
7615 strcat (buf
, "long long int ");
7616 else if (declspecs
== signed_char_type_node
7617 || declspecs
== char_type_node
)
7618 strcat (buf
, "char ");
7620 /* Unsigned integer types. */
7622 else if (declspecs
== short_unsigned_type_node
)
7623 strcat (buf
, "unsigned short ");
7624 else if (declspecs
== unsigned_type_node
)
7625 strcat (buf
, "unsigned int ");
7626 else if (declspecs
== long_unsigned_type_node
)
7627 strcat (buf
, "unsigned long ");
7628 else if (declspecs
== long_long_unsigned_type_node
)
7629 strcat (buf
, "unsigned long long ");
7630 else if (declspecs
== unsigned_char_type_node
)
7631 strcat (buf
, "unsigned char ");
7635 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7637 if (declspecs
== float_type_node
)
7638 strcat (buf
, "float ");
7639 else if (declspecs
== double_type_node
)
7640 strcat (buf
, "double ");
7641 else if (declspecs
== long_double_type_node
)
7642 strcat (buf
, "long double ");
7646 if (TYPE_NAME (declspecs
)
7647 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7649 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7651 if (! TREE_STATIC_TEMPLATE (declspecs
))
7652 strcat (buf
, "struct ");
7653 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7657 tree chain
= protocol_list
;
7664 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7665 chain
= TREE_CHAIN (chain
);
7674 strcat (buf
, "untagged struct");
7680 if (TYPE_NAME (declspecs
)
7681 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7683 strcat (buf
, "union ");
7684 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7689 strcat (buf
, "untagged union ");
7693 if (TYPE_NAME (declspecs
)
7694 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7696 strcat (buf
, "enum ");
7697 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7702 strcat (buf
, "untagged enum ");
7706 strcat (buf
, "void ");
7711 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7716 tree chain
= protocol_list
;
7723 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7724 chain
= TREE_CHAIN (chain
);
7740 /* Given a tree node, produce a printable description of it in the given
7741 buffer, overwriting the buffer. */
7744 gen_declaration (atype_or_adecl
, buf
)
7745 tree atype_or_adecl
;
7749 gen_declaration_1 (atype_or_adecl
, buf
);
7753 /* Given a tree node, append a printable description to the end of the
7757 gen_declaration_1 (atype_or_adecl
, buf
)
7758 tree atype_or_adecl
;
7763 if (TREE_CODE (atype_or_adecl
) == TREE_LIST
)
7765 tree declspecs
; /* "identifier_node", "record_type" */
7766 tree declarator
; /* "array_ref", "indirect_ref", "call_expr"... */
7768 /* We have a "raw", abstract declarator (typename). */
7769 declarator
= TREE_VALUE (atype_or_adecl
);
7770 declspecs
= TREE_PURPOSE (atype_or_adecl
);
7772 gen_declspecs (declspecs
, buf
, 1);
7776 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7783 tree declspecs
; /* "integer_type", "real_type", "record_type"... */
7784 tree declarator
; /* "array_type", "function_type", "pointer_type". */
7786 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7787 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7788 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7789 atype
= TREE_TYPE (atype_or_adecl
);
7791 /* Assume we have a *_type node. */
7792 atype
= atype_or_adecl
;
7794 if (is_complex_decl (atype
))
7798 /* Get the declaration specifier; it is at the end of the list. */
7799 declarator
= chain
= atype
;
7801 chain
= TREE_TYPE (chain
); /* not TREE_CHAIN (chain); */
7802 while (is_complex_decl (chain
));
7809 declarator
= NULL_TREE
;
7812 gen_declspecs (declspecs
, buf
, 0);
7814 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7815 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7816 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7818 const char *const decl_name
=
7819 (DECL_NAME (atype_or_adecl
)
7820 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl
)) : "");
7825 strcat (buf
, gen_declarator (declarator
, declbuf
, decl_name
));
7828 else if (decl_name
[0])
7831 strcat (buf
, decl_name
);
7834 else if (declarator
)
7837 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7842 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7844 /* Given a method tree, put a printable description into the given
7845 buffer (overwriting) and return a pointer to the buffer. */
7848 gen_method_decl (method
, buf
)
7855 if (RAW_TYPESPEC (method
) != objc_object_reference
)
7858 gen_declaration_1 (TREE_TYPE (method
), buf
);
7862 chain
= METHOD_SEL_ARGS (method
);
7865 /* We have a chain of keyword_decls. */
7868 if (KEYWORD_KEY_NAME (chain
))
7869 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain
)));
7872 if (RAW_TYPESPEC (chain
) != objc_object_reference
)
7875 gen_declaration_1 (TREE_TYPE (chain
), buf
);
7879 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain
)));
7880 if ((chain
= TREE_CHAIN (chain
)))
7885 if (METHOD_ADD_ARGS (method
) == objc_ellipsis_node
)
7886 strcat (buf
, ", ...");
7887 else if (METHOD_ADD_ARGS (method
))
7889 /* We have a tree list node as generate by get_parm_info. */
7890 chain
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
7892 /* Know we have a chain of parm_decls. */
7896 gen_declaration_1 (chain
, buf
);
7897 chain
= TREE_CHAIN (chain
);
7903 /* We have a unary selector. */
7904 strcat (buf
, IDENTIFIER_POINTER (METHOD_SEL_NAME (method
)));
7912 dump_interface (fp
, chain
)
7916 char *buf
= (char *) xmalloc (256);
7917 const char *my_name
= IDENTIFIER_POINTER (CLASS_NAME (chain
));
7918 tree ivar_decls
= CLASS_RAW_IVARS (chain
);
7919 tree nst_methods
= CLASS_NST_METHODS (chain
);
7920 tree cls_methods
= CLASS_CLS_METHODS (chain
);
7922 fprintf (fp
, "\n@interface %s", my_name
);
7924 if (CLASS_SUPER_NAME (chain
))
7926 const char *super_name
= IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain
));
7927 fprintf (fp
, " : %s\n", super_name
);
7934 fprintf (fp
, "{\n");
7937 fprintf (fp
, "\t%s;\n", gen_declaration (ivar_decls
, buf
));
7938 ivar_decls
= TREE_CHAIN (ivar_decls
);
7941 fprintf (fp
, "}\n");
7946 fprintf (fp
, "- %s;\n", gen_method_decl (nst_methods
, buf
));
7947 nst_methods
= TREE_CHAIN (nst_methods
);
7952 fprintf (fp
, "+ %s;\n", gen_method_decl (cls_methods
, buf
));
7953 cls_methods
= TREE_CHAIN (cls_methods
);
7955 fprintf (fp
, "\n@end");
7958 /* Demangle function for Objective-C */
7960 objc_demangle (mangled
)
7961 const char *mangled
;
7963 char *demangled
, *cp
;
7965 if (mangled
[0] == '_' &&
7966 (mangled
[1] == 'i' || mangled
[1] == 'c') &&
7969 cp
= demangled
= xmalloc(strlen(mangled
) + 2);
7970 if (mangled
[1] == 'i')
7971 *cp
++ = '-'; /* for instance method */
7973 *cp
++ = '+'; /* for class method */
7974 *cp
++ = '['; /* opening left brace */
7975 strcpy(cp
, mangled
+3); /* tack on the rest of the mangled name */
7976 while (*cp
&& *cp
== '_')
7977 cp
++; /* skip any initial underbars in class name */
7978 cp
= strchr(cp
, '_'); /* find first non-initial underbar */
7981 free(demangled
); /* not mangled name */
7984 if (cp
[1] == '_') /* easy case: no category name */
7986 *cp
++ = ' '; /* replace two '_' with one ' ' */
7987 strcpy(cp
, mangled
+ (cp
- demangled
) + 2);
7991 *cp
++ = '('; /* less easy case: category name */
7992 cp
= strchr(cp
, '_');
7995 free(demangled
); /* not mangled name */
7999 *cp
++ = ' '; /* overwriting 1st char of method name... */
8000 strcpy(cp
, mangled
+ (cp
- demangled
)); /* get it back */
8002 while (*cp
&& *cp
== '_')
8003 cp
++; /* skip any initial underbars in method name */
8006 *cp
= ':'; /* replace remaining '_' with ':' */
8007 *cp
++ = ']'; /* closing right brace */
8008 *cp
++ = 0; /* string terminator */
8012 return mangled
; /* not an objc mangled name */
8016 objc_printable_name (decl
, kind
)
8018 int kind ATTRIBUTE_UNUSED
;
8020 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl
)));
8026 gcc_obstack_init (&util_obstack
);
8027 util_firstobj
= (char *) obstack_finish (&util_obstack
);
8029 errbuf
= (char *) xmalloc (BUFSIZE
);
8031 synth_module_prologue ();
8037 struct imp_entry
*impent
;
8039 /* The internally generated initializers appear to have missing braces.
8040 Don't warn about this. */
8041 int save_warn_missing_braces
= warn_missing_braces
;
8042 warn_missing_braces
= 0;
8044 /* A missing @end may not be detected by the parser. */
8045 if (objc_implementation_context
)
8047 warning ("`@end' missing in implementation context");
8048 finish_class (objc_implementation_context
);
8049 objc_ivar_chain
= NULL_TREE
;
8050 objc_implementation_context
= NULL_TREE
;
8053 generate_forward_declaration_to_string_table ();
8055 #ifdef OBJC_PROLOGUE
8059 /* Process the static instances here because initialization of objc_symtab
8061 if (objc_static_instances
)
8062 generate_static_references ();
8064 if (imp_list
|| class_names_chain
8065 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8066 generate_objc_symtab_decl ();
8068 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8070 objc_implementation_context
= impent
->imp_context
;
8071 implementation_template
= impent
->imp_template
;
8073 UOBJC_CLASS_decl
= impent
->class_decl
;
8074 UOBJC_METACLASS_decl
= impent
->meta_decl
;
8076 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
8078 /* all of the following reference the string pool... */
8079 generate_ivar_lists ();
8080 generate_dispatch_tables ();
8081 generate_shared_structures ();
8085 generate_dispatch_tables ();
8086 generate_category (objc_implementation_context
);
8090 /* If we are using an array of selectors, we must always
8091 finish up the array decl even if no selectors were used. */
8092 if (! flag_next_runtime
|| sel_ref_chain
)
8093 build_selector_translation_table ();
8096 generate_protocols ();
8098 if (objc_implementation_context
|| class_names_chain
|| objc_static_instances
8099 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8101 /* Arrange for ObjC data structures to be initialized at run time. */
8102 rtx init_sym
= build_module_descriptor ();
8103 if (init_sym
&& targetm
.have_ctors_dtors
)
8104 (* targetm
.asm_out
.constructor
) (init_sym
, DEFAULT_INIT_PRIORITY
);
8107 /* Dump the class references. This forces the appropriate classes
8108 to be linked into the executable image, preserving unix archive
8109 semantics. This can be removed when we move to a more dynamically
8110 linked environment. */
8112 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
8114 handle_class_ref (chain
);
8115 if (TREE_PURPOSE (chain
))
8116 generate_classref_translation_entry (chain
);
8119 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8120 handle_impent (impent
);
8122 /* Dump the string table last. */
8124 generate_strings ();
8126 if (flag_gen_declaration
)
8128 add_class (objc_implementation_context
);
8129 dump_interface (gen_declaration_file
, objc_implementation_context
);
8137 /* Run through the selector hash tables and print a warning for any
8138 selector which has multiple methods. */
8140 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8141 for (hsh
= cls_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8144 tree meth
= hsh
->key
;
8145 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8149 warning ("potential selector conflict for method `%s'",
8150 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8151 warn_with_method ("found", type
, meth
);
8152 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8153 warn_with_method ("found", type
, loop
->value
);
8156 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8157 for (hsh
= nst_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8160 tree meth
= hsh
->key
;
8161 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8165 warning ("potential selector conflict for method `%s'",
8166 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8167 warn_with_method ("found", type
, meth
);
8168 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8169 warn_with_method ("found", type
, loop
->value
);
8173 warn_missing_braces
= save_warn_missing_braces
;
8176 /* Subroutines of finish_objc. */
8179 generate_classref_translation_entry (chain
)
8182 tree expr
, name
, decl_specs
, decl
, sc_spec
;
8185 type
= TREE_TYPE (TREE_PURPOSE (chain
));
8187 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
8188 expr
= build_c_cast (type
, expr
); /* cast! */
8190 name
= DECL_NAME (TREE_PURPOSE (chain
));
8192 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
8194 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8195 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
8197 /* The decl that is returned from start_decl is the one that we
8198 forward declared in build_class_reference. */
8199 decl
= start_decl (name
, decl_specs
, 1, NULL_TREE
);
8200 DECL_CONTEXT (decl
) = NULL_TREE
;
8201 finish_decl (decl
, expr
, NULL_TREE
);
8206 handle_class_ref (chain
)
8209 const char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
8210 char *string
= (char *) alloca (strlen (name
) + 30);
8214 sprintf (string
, "%sobjc_class_name_%s",
8215 (flag_next_runtime
? "." : "__"), name
);
8217 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8218 if (flag_next_runtime
)
8220 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file
, string
);
8225 /* Make a decl for this name, so we can use its address in a tree. */
8226 decl
= build_decl (VAR_DECL
, get_identifier (string
), char_type_node
);
8227 DECL_EXTERNAL (decl
) = 1;
8228 TREE_PUBLIC (decl
) = 1;
8231 rest_of_decl_compilation (decl
, 0, 0, 0);
8233 /* Make a decl for the address. */
8234 sprintf (string
, "%sobjc_class_ref_%s",
8235 (flag_next_runtime
? "." : "__"), name
);
8236 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
8237 decl
= build_decl (VAR_DECL
, get_identifier (string
), string_type_node
);
8238 DECL_INITIAL (decl
) = exp
;
8239 TREE_STATIC (decl
) = 1;
8240 TREE_USED (decl
) = 1;
8243 rest_of_decl_compilation (decl
, 0, 0, 0);
8247 handle_impent (impent
)
8248 struct imp_entry
*impent
;
8252 objc_implementation_context
= impent
->imp_context
;
8253 implementation_template
= impent
->imp_template
;
8255 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
8257 const char *const class_name
=
8258 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8260 string
= (char *) alloca (strlen (class_name
) + 30);
8262 sprintf (string
, "%sobjc_class_name_%s",
8263 (flag_next_runtime
? "." : "__"), class_name
);
8265 else if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
8267 const char *const class_name
=
8268 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8269 const char *const class_super_name
=
8270 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
8272 string
= (char *) alloca (strlen (class_name
)
8273 + strlen (class_super_name
) + 30);
8275 /* Do the same for categories. Even though no references to
8276 these symbols are generated automatically by the compiler, it
8277 gives you a handle to pull them into an archive by hand. */
8278 sprintf (string
, "*%sobjc_category_name_%s_%s",
8279 (flag_next_runtime
? "." : "__"), class_name
, class_super_name
);
8284 #ifdef ASM_DECLARE_CLASS_REFERENCE
8285 if (flag_next_runtime
)
8287 ASM_DECLARE_CLASS_REFERENCE (asm_out_file
, string
);
8295 init
= build_int_2 (0, 0);
8296 TREE_TYPE (init
) = c_common_type_for_size (BITS_PER_WORD
, 1);
8297 decl
= build_decl (VAR_DECL
, get_identifier (string
), TREE_TYPE (init
));
8298 TREE_PUBLIC (decl
) = 1;
8299 TREE_READONLY (decl
) = 1;
8300 TREE_USED (decl
) = 1;
8301 TREE_CONSTANT (decl
) = 1;
8302 DECL_CONTEXT (decl
) = 0;
8303 DECL_ARTIFICIAL (decl
) = 1;
8304 DECL_INITIAL (decl
) = init
;
8305 assemble_variable (decl
, 1, 0, 0);
8309 /* Look up ID as an instance variable. */
8311 lookup_objc_ivar (id
)
8316 if (objc_method_context
&& !strcmp (IDENTIFIER_POINTER (id
), "super"))
8317 /* We have a message to super. */
8318 return get_super_receiver ();
8319 else if (objc_method_context
&& (decl
= is_ivar (objc_ivar_chain
, id
)))
8321 if (is_private (decl
))
8322 return error_mark_node
;
8324 return build_ivar_reference (id
);
8330 #include "gtype-objc.h"