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 int objc_receiver_context
;
346 static void handle_impent
PARAMS ((struct imp_entry
*));
348 struct imp_entry
*imp_list
= 0;
349 int imp_count
= 0; /* `@implementation' */
350 int cat_count
= 0; /* `@category' */
352 static int method_slot
= 0; /* Used by start_method_def, */
356 static char *errbuf
; /* Buffer for error diagnostics */
358 /* Data imported from tree.c. */
360 extern enum debug_info_type write_symbols
;
362 /* Data imported from toplev.c. */
364 extern const char *dump_base_name
;
366 /* Generate code for GNU or NeXT runtime environment. */
368 #ifdef NEXT_OBJC_RUNTIME
369 int flag_next_runtime
= 1;
371 int flag_next_runtime
= 0;
374 int flag_typed_selectors
;
376 /* Open and close the file for outputting class declarations, if requested. */
378 int flag_gen_declaration
= 0;
380 FILE *gen_declaration_file
;
382 /* Warn if multiple methods are seen for the same selector, but with
383 different argument types. */
385 int warn_selector
= 0;
387 /* Warn if methods required by a protocol are not implemented in the
388 class adopting it. When turned off, methods inherited to that
389 class are also considered implemented */
391 int flag_warn_protocol
= 1;
393 /* Tells "encode_pointer/encode_aggregate" whether we are generating
394 type descriptors for instance variables (as opposed to methods).
395 Type descriptors for instance variables contain more information
396 than methods (for static typing and embedded structures). */
398 static int generating_instance_variables
= 0;
400 /* Tells the compiler that this is a special run. Do not perform any
401 compiling, instead we are to test some platform dependent features
402 and output a C header file with appropriate definitions. */
404 static int print_struct_values
= 0;
406 /* Some platforms pass small structures through registers versus
407 through an invisible pointer. Determine at what size structure is
408 the transition point between the two possibilities. */
411 generate_struct_by_value_array ()
414 tree field_decl
, field_decl_chain
;
416 int aggregate_in_mem
[32];
419 /* Presumably no platform passes 32 byte structures in a register. */
420 for (i
= 1; i
< 32; i
++)
424 /* Create an unnamed struct that has `i' character components */
425 type
= start_struct (RECORD_TYPE
, NULL_TREE
);
427 strcpy (buffer
, "c1");
428 field_decl
= create_builtin_decl (FIELD_DECL
,
431 field_decl_chain
= field_decl
;
433 for (j
= 1; j
< i
; j
++)
435 sprintf (buffer
, "c%d", j
+ 1);
436 field_decl
= create_builtin_decl (FIELD_DECL
,
439 chainon (field_decl_chain
, field_decl
);
441 finish_struct (type
, field_decl_chain
, NULL_TREE
);
443 aggregate_in_mem
[i
] = aggregate_value_p (type
);
444 if (!aggregate_in_mem
[i
])
448 /* We found some structures that are returned in registers instead of memory
449 so output the necessary data. */
452 for (i
= 31; i
>= 0; i
--)
453 if (!aggregate_in_mem
[i
])
455 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i
);
457 /* The first member of the structure is always 0 because we don't handle
458 structures with 0 members */
459 printf ("static int struct_forward_array[] = {\n 0");
461 for (j
= 1; j
<= i
; j
++)
462 printf (", %d", aggregate_in_mem
[j
]);
471 const char *filename
;
473 filename
= c_objc_common_init (filename
);
475 /* Force the line number back to 0; check_newline will have
476 raised it to 1, which will make the builtin functions appear
477 not to be built in. */
480 /* If gen_declaration desired, open the output file. */
481 if (flag_gen_declaration
)
483 register char * const dumpname
= concat (dump_base_name
, ".decl", NULL
);
484 gen_declaration_file
= fopen (dumpname
, "w");
485 if (gen_declaration_file
== 0)
486 fatal_io_error ("can't open %s", dumpname
);
490 if (flag_next_runtime
)
492 TAG_GETCLASS
= "objc_getClass";
493 TAG_GETMETACLASS
= "objc_getMetaClass";
494 TAG_MSGSEND
= "objc_msgSend";
495 TAG_MSGSENDSUPER
= "objc_msgSendSuper";
496 TAG_EXECCLASS
= "__objc_execClass";
497 default_constant_string_class_name
= "NSConstantString";
501 TAG_GETCLASS
= "objc_get_class";
502 TAG_GETMETACLASS
= "objc_get_meta_class";
503 TAG_MSGSEND
= "objc_msg_lookup";
504 TAG_MSGSENDSUPER
= "objc_msg_lookup_super";
505 TAG_EXECCLASS
= "__objc_exec_class";
506 default_constant_string_class_name
= "NXConstantString";
507 flag_typed_selectors
= 1;
510 objc_ellipsis_node
= make_node (ERROR_MARK
);
514 if (print_struct_values
)
515 generate_struct_by_value_array ();
523 c_objc_common_finish_file ();
525 /* Finalize Objective-C runtime data. No need to generate tables
526 and code if only checking syntax. */
527 if (!flag_syntax_only
)
530 if (gen_declaration_file
)
531 fclose (gen_declaration_file
);
535 objc_decode_option (argc
, argv
)
539 const char *p
= argv
[0];
541 if (!strcmp (p
, "-gen-decls"))
542 flag_gen_declaration
= 1;
543 else if (!strcmp (p
, "-Wselector"))
545 else if (!strcmp (p
, "-Wno-selector"))
547 else if (!strcmp (p
, "-Wprotocol"))
548 flag_warn_protocol
= 1;
549 else if (!strcmp (p
, "-Wno-protocol"))
550 flag_warn_protocol
= 0;
551 else if (!strcmp (p
, "-fgnu-runtime"))
552 flag_next_runtime
= 0;
553 else if (!strcmp (p
, "-fno-next-runtime"))
554 flag_next_runtime
= 0;
555 else if (!strcmp (p
, "-fno-gnu-runtime"))
556 flag_next_runtime
= 1;
557 else if (!strcmp (p
, "-fnext-runtime"))
558 flag_next_runtime
= 1;
559 else if (!strcmp (p
, "-print-objc-runtime-info"))
560 print_struct_values
= 1;
561 #define CSTSTRCLASS "-fconstant-string-class="
562 else if (!strncmp (p
, CSTSTRCLASS
, sizeof(CSTSTRCLASS
) - 2)) {
563 if (strlen (argv
[0]) <= strlen (CSTSTRCLASS
))
564 error ("no class name specified as argument to -fconstant-string-class");
565 constant_string_class_name
= xstrdup(argv
[0] + sizeof(CSTSTRCLASS
) - 1);
569 return c_decode_option (argc
, argv
);
576 define_decl (declarator
, declspecs
)
580 tree decl
= start_decl (declarator
, declspecs
, 0, NULL_TREE
);
581 finish_decl (decl
, NULL_TREE
, NULL_TREE
);
585 /* Return 1 if LHS and RHS are compatible types for assignment or
586 various other operations. Return 0 if they are incompatible, and
587 return -1 if we choose to not decide. When the operation is
588 REFLEXIVE, check for compatibility in either direction.
590 For statically typed objects, an assignment of the form `a' = `b'
594 `a' and `b' are the same class type, or
595 `a' and `b' are of class types A and B such that B is a descendant of A. */
598 maybe_objc_comptypes (lhs
, rhs
, reflexive
)
602 return objc_comptypes (lhs
, rhs
, reflexive
);
606 lookup_method_in_protocol_list (rproto_list
, sel_name
, class_meth
)
614 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
616 p
= TREE_VALUE (rproto
);
618 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
620 if ((fnd
= lookup_method (class_meth
621 ? PROTOCOL_CLS_METHODS (p
)
622 : PROTOCOL_NST_METHODS (p
), sel_name
)))
624 else if (PROTOCOL_LIST (p
))
625 fnd
= lookup_method_in_protocol_list (PROTOCOL_LIST (p
),
626 sel_name
, class_meth
);
630 ; /* An identifier...if we could not find a protocol. */
641 lookup_protocol_in_reflist (rproto_list
, lproto
)
647 /* Make sure the protocol is supported by the object on the rhs. */
648 if (TREE_CODE (lproto
) == PROTOCOL_INTERFACE_TYPE
)
651 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
653 p
= TREE_VALUE (rproto
);
655 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
660 else if (PROTOCOL_LIST (p
))
661 fnd
= lookup_protocol_in_reflist (PROTOCOL_LIST (p
), lproto
);
670 ; /* An identifier...if we could not find a protocol. */
676 /* Return 1 if LHS and RHS are compatible types for assignment
677 or various other operations. Return 0 if they are incompatible,
678 and return -1 if we choose to not decide. When the operation
679 is REFLEXIVE, check for compatibility in either direction. */
682 objc_comptypes (lhs
, rhs
, reflexive
)
687 /* New clause for protocols. */
689 if (TREE_CODE (lhs
) == POINTER_TYPE
690 && TREE_CODE (TREE_TYPE (lhs
)) == RECORD_TYPE
691 && TREE_CODE (rhs
) == POINTER_TYPE
692 && TREE_CODE (TREE_TYPE (rhs
)) == RECORD_TYPE
)
694 int lhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (lhs
);
695 int rhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (rhs
);
699 tree lproto
, lproto_list
= TYPE_PROTOCOL_LIST (lhs
);
700 tree rproto
, rproto_list
;
705 rproto_list
= TYPE_PROTOCOL_LIST (rhs
);
707 /* Make sure the protocol is supported by the object
709 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
711 p
= TREE_VALUE (lproto
);
712 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
715 warning ("object does not conform to the `%s' protocol",
716 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
719 else if (TYPED_OBJECT (TREE_TYPE (rhs
)))
721 tree rname
= TYPE_NAME (TREE_TYPE (rhs
));
724 /* Make sure the protocol is supported by the object
726 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
728 p
= TREE_VALUE (lproto
);
730 rinter
= lookup_interface (rname
);
732 while (rinter
&& !rproto
)
736 rproto_list
= CLASS_PROTOCOL_LIST (rinter
);
737 /* If the underlying ObjC class does not have
738 protocols attached to it, perhaps there are
739 "one-off" protocols attached to the rhs?
740 E.g., 'id<MyProt> foo;'. */
742 rproto_list
= TYPE_PROTOCOL_LIST (TREE_TYPE (rhs
));
743 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
745 /* Check for protocols adopted by categories. */
746 cat
= CLASS_CATEGORY_LIST (rinter
);
747 while (cat
&& !rproto
)
749 rproto_list
= CLASS_PROTOCOL_LIST (cat
);
750 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
752 cat
= CLASS_CATEGORY_LIST (cat
);
755 rinter
= lookup_interface (CLASS_SUPER_NAME (rinter
));
759 warning ("class `%s' does not implement the `%s' protocol",
760 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs
))),
761 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
765 /* May change...based on whether there was any mismatch */
768 else if (rhs_is_proto
)
769 /* Lhs is not a protocol...warn if it is statically typed */
770 return (TYPED_OBJECT (TREE_TYPE (lhs
)) != 0);
773 /* Defer to comptypes. */
777 else if (TREE_CODE (lhs
) == RECORD_TYPE
&& TREE_CODE (rhs
) == RECORD_TYPE
)
778 ; /* Fall thru. This is the case we have been handling all along */
780 /* Defer to comptypes. */
783 /* `id' = `<class> *', `<class> *' = `id' */
785 if ((TYPE_NAME (lhs
) == objc_object_id
&& TYPED_OBJECT (rhs
))
786 || (TYPE_NAME (rhs
) == objc_object_id
&& TYPED_OBJECT (lhs
)))
789 /* `id' = `Class', `Class' = `id' */
791 else if ((TYPE_NAME (lhs
) == objc_object_id
792 && TYPE_NAME (rhs
) == objc_class_id
)
793 || (TYPE_NAME (lhs
) == objc_class_id
794 && TYPE_NAME (rhs
) == objc_object_id
))
797 /* `<class> *' = `<class> *' */
799 else if (TYPED_OBJECT (lhs
) && TYPED_OBJECT (rhs
))
801 tree lname
= TYPE_NAME (lhs
);
802 tree rname
= TYPE_NAME (rhs
);
808 /* If the left hand side is a super class of the right hand side,
810 for (inter
= lookup_interface (rname
); inter
;
811 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
812 if (lname
== CLASS_SUPER_NAME (inter
))
815 /* Allow the reverse when reflexive. */
817 for (inter
= lookup_interface (lname
); inter
;
818 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
819 if (rname
== CLASS_SUPER_NAME (inter
))
825 /* Defer to comptypes. */
829 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
832 objc_check_decl (decl
)
835 tree type
= TREE_TYPE (decl
);
837 if (TREE_CODE (type
) == RECORD_TYPE
838 && TREE_STATIC_TEMPLATE (type
)
839 && type
!= constant_string_type
)
840 error_with_decl (decl
, "`%s' cannot be statically allocated");
844 maybe_objc_check_decl (decl
)
847 objc_check_decl (decl
);
850 /* Implement static typing. At this point, we know we have an interface. */
853 get_static_reference (interface
, protocols
)
857 tree type
= xref_tag (RECORD_TYPE
, interface
);
861 tree t
, m
= TYPE_MAIN_VARIANT (type
);
863 t
= copy_node (type
);
864 TYPE_BINFO (t
) = make_tree_vec (2);
866 /* Add this type to the chain of variants of TYPE. */
867 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
868 TYPE_NEXT_VARIANT (m
) = t
;
870 /* Look up protocols and install in lang specific list. Note
871 that the protocol list can have a different lifetime than T! */
872 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
874 /* This forces a new pointer type to be created later
875 (in build_pointer_type)...so that the new template
876 we just created will actually be used...what a hack! */
877 if (TYPE_POINTER_TO (t
))
878 TYPE_POINTER_TO (t
) = NULL_TREE
;
887 get_object_reference (protocols
)
890 tree type_decl
= lookup_name (objc_id_id
);
893 if (type_decl
&& TREE_CODE (type_decl
) == TYPE_DECL
)
895 type
= TREE_TYPE (type_decl
);
896 if (TYPE_MAIN_VARIANT (type
) != id_type
)
897 warning ("unexpected type for `id' (%s)",
898 gen_declaration (type
, errbuf
));
902 error ("undefined type `id', please import <objc/objc.h>");
903 return error_mark_node
;
906 /* This clause creates a new pointer type that is qualified with
907 the protocol specification...this info is used later to do more
908 elaborate type checking. */
912 tree t
, m
= TYPE_MAIN_VARIANT (type
);
914 t
= copy_node (type
);
915 TYPE_BINFO (t
) = make_tree_vec (2);
917 /* Add this type to the chain of variants of TYPE. */
918 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
919 TYPE_NEXT_VARIANT (m
) = t
;
921 /* Look up protocols...and install in lang specific list */
922 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
924 /* This forces a new pointer type to be created later
925 (in build_pointer_type)...so that the new template
926 we just created will actually be used...what a hack! */
927 if (TYPE_POINTER_TO (t
))
928 TYPE_POINTER_TO (t
) = NULL_TREE
;
935 /* Check for circular dependencies in protocols. The arguments are
936 PROTO, the protocol to check, and LIST, a list of protocol it
940 check_protocol_recursively (proto
, list
)
946 for (p
= list
; p
; p
= TREE_CHAIN (p
))
948 tree pp
= TREE_VALUE (p
);
950 if (TREE_CODE (pp
) == IDENTIFIER_NODE
)
951 pp
= lookup_protocol (pp
);
954 fatal_error ("protocol `%s' has circular dependency",
955 IDENTIFIER_POINTER (PROTOCOL_NAME (pp
)));
957 check_protocol_recursively (proto
, PROTOCOL_LIST (pp
));
962 lookup_and_install_protocols (protocols
)
967 tree return_value
= protocols
;
969 for (proto
= protocols
; proto
; proto
= TREE_CHAIN (proto
))
971 tree ident
= TREE_VALUE (proto
);
972 tree p
= lookup_protocol (ident
);
976 error ("cannot find protocol declaration for `%s'",
977 IDENTIFIER_POINTER (ident
));
979 TREE_CHAIN (prev
) = TREE_CHAIN (proto
);
981 return_value
= TREE_CHAIN (proto
);
985 /* Replace identifier with actual protocol node. */
986 TREE_VALUE (proto
) = p
;
994 /* Create and push a decl for a built-in external variable or field NAME.
996 TYPE is its data type. */
999 create_builtin_decl (code
, type
, name
)
1000 enum tree_code code
;
1004 tree decl
= build_decl (code
, get_identifier (name
), type
);
1006 if (code
== VAR_DECL
)
1008 TREE_STATIC (decl
) = 1;
1009 make_decl_rtl (decl
, 0);
1013 DECL_ARTIFICIAL (decl
) = 1;
1017 /* Find the decl for the constant string class. */
1020 setup_string_decl ()
1022 if (!string_class_decl
)
1024 if (!constant_string_global_id
)
1025 constant_string_global_id
= get_identifier (STRING_OBJECT_GLOBAL_NAME
);
1026 string_class_decl
= lookup_name (constant_string_global_id
);
1030 /* Purpose: "play" parser, creating/installing representations
1031 of the declarations that are required by Objective-C.
1035 type_spec--------->sc_spec
1036 (tree_list) (tree_list)
1039 identifier_node identifier_node */
1042 synth_module_prologue ()
1047 /* Defined in `objc.h' */
1048 objc_object_id
= get_identifier (TAG_OBJECT
);
1050 objc_object_reference
= xref_tag (RECORD_TYPE
, objc_object_id
);
1052 id_type
= build_pointer_type (objc_object_reference
);
1054 objc_id_id
= get_identifier (TYPE_ID
);
1055 objc_class_id
= get_identifier (TAG_CLASS
);
1057 objc_class_type
= build_pointer_type (xref_tag (RECORD_TYPE
, objc_class_id
));
1058 protocol_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
1059 get_identifier (PROTOCOL_OBJECT_CLASS_NAME
)));
1061 /* Declare type of selector-objects that represent an operation name. */
1063 /* `struct objc_selector *' */
1065 = build_pointer_type (xref_tag (RECORD_TYPE
,
1066 get_identifier (TAG_SELECTOR
)));
1068 /* Forward declare type, or else the prototype for msgSendSuper will
1071 super_p
= build_pointer_type (xref_tag (RECORD_TYPE
,
1072 get_identifier (TAG_SUPER
)));
1075 /* id objc_msgSend (id, SEL, ...); */
1078 = build_function_type (id_type
,
1079 tree_cons (NULL_TREE
, id_type
,
1080 tree_cons (NULL_TREE
, selector_type
,
1083 if (! flag_next_runtime
)
1085 umsg_decl
= build_decl (FUNCTION_DECL
,
1086 get_identifier (TAG_MSGSEND
), temp_type
);
1087 DECL_EXTERNAL (umsg_decl
) = 1;
1088 TREE_PUBLIC (umsg_decl
) = 1;
1089 DECL_INLINE (umsg_decl
) = 1;
1090 DECL_ARTIFICIAL (umsg_decl
) = 1;
1092 make_decl_rtl (umsg_decl
, NULL
);
1093 pushdecl (umsg_decl
);
1096 umsg_decl
= builtin_function (TAG_MSGSEND
, temp_type
, 0, NOT_BUILT_IN
, 0);
1098 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1101 = build_function_type (id_type
,
1102 tree_cons (NULL_TREE
, super_p
,
1103 tree_cons (NULL_TREE
, selector_type
,
1106 umsg_super_decl
= builtin_function (TAG_MSGSENDSUPER
,
1107 temp_type
, 0, NOT_BUILT_IN
, 0);
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
, 0);
1120 /* id objc_getMetaClass (const char *); */
1122 objc_get_meta_class_decl
1123 = builtin_function (TAG_GETMETACLASS
, temp_type
, 0, NOT_BUILT_IN
, 0);
1125 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1127 if (! flag_next_runtime
)
1129 if (flag_typed_selectors
)
1131 /* Suppress outputting debug symbols, because
1132 dbxout_init hasn'r been called yet. */
1133 enum debug_info_type save_write_symbols
= write_symbols
;
1134 const struct gcc_debug_hooks
*const save_hooks
= debug_hooks
;
1135 write_symbols
= NO_DEBUG
;
1136 debug_hooks
= &do_nothing_debug_hooks
;
1138 build_selector_template ();
1139 temp_type
= build_array_type (objc_selector_template
, NULL_TREE
);
1141 write_symbols
= save_write_symbols
;
1142 debug_hooks
= save_hooks
;
1145 temp_type
= build_array_type (selector_type
, NULL_TREE
);
1147 layout_type (temp_type
);
1148 UOBJC_SELECTOR_TABLE_decl
1149 = create_builtin_decl (VAR_DECL
, temp_type
,
1150 "_OBJC_SELECTOR_TABLE");
1152 /* Avoid warning when not sending messages. */
1153 TREE_USED (UOBJC_SELECTOR_TABLE_decl
) = 1;
1156 generate_forward_declaration_to_string_table ();
1158 /* Forward declare constant_string_id and constant_string_type. */
1159 if (!constant_string_class_name
)
1160 constant_string_class_name
= default_constant_string_class_name
;
1162 constant_string_id
= get_identifier (constant_string_class_name
);
1163 constant_string_type
= xref_tag (RECORD_TYPE
, constant_string_id
);
1166 /* Predefine the following data type:
1168 struct STRING_OBJECT_CLASS_NAME
1172 unsigned int length;
1176 build_string_class_template ()
1178 tree field_decl
, field_decl_chain
;
1180 field_decl
= create_builtin_decl (FIELD_DECL
, id_type
, "isa");
1181 field_decl_chain
= field_decl
;
1183 field_decl
= create_builtin_decl (FIELD_DECL
,
1184 build_pointer_type (char_type_node
),
1186 chainon (field_decl_chain
, field_decl
);
1188 field_decl
= create_builtin_decl (FIELD_DECL
, unsigned_type_node
, "length");
1189 chainon (field_decl_chain
, field_decl
);
1191 finish_struct (constant_string_type
, field_decl_chain
, NULL_TREE
);
1194 /* Custom build_string which sets TREE_TYPE! */
1197 my_build_string (len
, str
)
1201 return fix_string_type (build_string (len
, str
));
1204 /* Given a chain of STRING_CST's, build a static instance of
1205 NXConstantString which points at the concatenation of those strings.
1206 We place the string object in the __string_objects section of the
1207 __OBJC segment. The Objective-C runtime will initialize the isa
1208 pointers of the string objects to point at the NXConstantString
1212 build_objc_string_object (strings
)
1215 tree string
, initlist
, constructor
;
1218 if (lookup_interface (constant_string_id
) == NULL_TREE
)
1220 error ("cannot find interface declaration for `%s'",
1221 IDENTIFIER_POINTER (constant_string_id
));
1222 return error_mark_node
;
1225 add_class_reference (constant_string_id
);
1227 if (TREE_CHAIN (strings
))
1229 varray_type vstrings
;
1230 VARRAY_TREE_INIT (vstrings
, 32, "strings");
1232 for (; strings
; strings
= TREE_CHAIN (strings
))
1233 VARRAY_PUSH_TREE (vstrings
, strings
);
1235 string
= combine_strings (vstrings
);
1240 string
= fix_string_type (string
);
1242 TREE_SET_CODE (string
, STRING_CST
);
1243 length
= TREE_STRING_LENGTH (string
) - 1;
1245 /* We could not properly create NXConstantString in synth_module_prologue,
1246 because that's called before debugging is initialized. Do it now. */
1247 if (TYPE_FIELDS (constant_string_type
) == NULL_TREE
)
1248 build_string_class_template ();
1250 /* & ((NXConstantString) { NULL, string, length }) */
1252 if (flag_next_runtime
)
1254 /* For the NeXT runtime, we can generate a literal reference
1255 to the string class, don't need to run a constructor. */
1256 setup_string_decl ();
1257 if (string_class_decl
== NULL_TREE
)
1259 error ("cannot find reference tag for class `%s'",
1260 IDENTIFIER_POINTER (constant_string_id
));
1261 return error_mark_node
;
1263 initlist
= build_tree_list
1265 copy_node (build_unary_op (ADDR_EXPR
, string_class_decl
, 0)));
1269 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1273 = tree_cons (NULL_TREE
, copy_node (build_unary_op (ADDR_EXPR
, string
, 1)),
1275 initlist
= tree_cons (NULL_TREE
, build_int_2 (length
, 0), initlist
);
1276 constructor
= build_constructor (constant_string_type
, nreverse (initlist
));
1278 if (!flag_next_runtime
)
1281 = objc_add_static_instance (constructor
, constant_string_type
);
1284 return (build_unary_op (ADDR_EXPR
, constructor
, 1));
1287 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1290 objc_add_static_instance (constructor
, class_decl
)
1291 tree constructor
, class_decl
;
1293 static int num_static_inst
;
1297 /* Find the list of static instances for the CLASS_DECL. Create one if
1299 for (chain
= &objc_static_instances
;
1300 *chain
&& TREE_VALUE (*chain
) != class_decl
;
1301 chain
= &TREE_CHAIN (*chain
));
1304 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
1305 add_objc_string (TYPE_NAME (class_decl
), class_names
);
1308 sprintf (buf
, "_OBJC_INSTANCE_%d", num_static_inst
++);
1309 decl
= build_decl (VAR_DECL
, get_identifier (buf
), class_decl
);
1310 DECL_COMMON (decl
) = 1;
1311 TREE_STATIC (decl
) = 1;
1312 DECL_ARTIFICIAL (decl
) = 1;
1313 DECL_INITIAL (decl
) = constructor
;
1315 /* We may be writing something else just now.
1316 Postpone till end of input. */
1317 DECL_DEFER_OUTPUT (decl
) = 1;
1318 pushdecl_top_level (decl
);
1319 rest_of_decl_compilation (decl
, 0, 1, 0);
1321 /* Add the DECL to the head of this CLASS' list. */
1322 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
1327 /* Build a static constant CONSTRUCTOR
1328 with type TYPE and elements ELTS. */
1331 build_constructor (type
, elts
)
1334 tree constructor
, f
, e
;
1336 /* ??? Most of the places that we build constructors, we don't fill in
1337 the type of integers properly. Convert them all en masse. */
1338 if (TREE_CODE (type
) == ARRAY_TYPE
)
1340 f
= TREE_TYPE (type
);
1341 if (TREE_CODE (f
) == POINTER_TYPE
|| TREE_CODE (f
) == INTEGER_TYPE
)
1342 for (e
= elts
; e
; e
= TREE_CHAIN (e
))
1343 TREE_VALUE (e
) = convert (f
, TREE_VALUE (e
));
1347 f
= TYPE_FIELDS (type
);
1348 for (e
= elts
; e
; e
= TREE_CHAIN (e
), f
= TREE_CHAIN (f
))
1349 if (TREE_CODE (TREE_TYPE (f
)) == POINTER_TYPE
1350 || TREE_CODE (TREE_TYPE (f
)) == INTEGER_TYPE
)
1351 TREE_VALUE (e
) = convert (TREE_TYPE (f
), TREE_VALUE (e
));
1354 constructor
= build (CONSTRUCTOR
, type
, NULL_TREE
, elts
);
1355 TREE_CONSTANT (constructor
) = 1;
1356 TREE_STATIC (constructor
) = 1;
1357 TREE_READONLY (constructor
) = 1;
1362 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1364 /* Predefine the following data type:
1372 void *defs[cls_def_cnt + cat_def_cnt];
1376 build_objc_symtab_template ()
1378 tree field_decl
, field_decl_chain
, index
;
1380 objc_symtab_template
1381 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SYMTAB
));
1383 /* long sel_ref_cnt; */
1385 field_decl
= create_builtin_decl (FIELD_DECL
,
1386 long_integer_type_node
,
1388 field_decl_chain
= field_decl
;
1392 field_decl
= create_builtin_decl (FIELD_DECL
,
1393 build_pointer_type (selector_type
),
1395 chainon (field_decl_chain
, field_decl
);
1397 /* short cls_def_cnt; */
1399 field_decl
= create_builtin_decl (FIELD_DECL
,
1400 short_integer_type_node
,
1402 chainon (field_decl_chain
, field_decl
);
1404 /* short cat_def_cnt; */
1406 field_decl
= create_builtin_decl (FIELD_DECL
,
1407 short_integer_type_node
,
1409 chainon (field_decl_chain
, field_decl
);
1411 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1413 if (!flag_next_runtime
)
1414 index
= build_index_type (build_int_2 (imp_count
+ cat_count
, 0));
1416 index
= build_index_type (build_int_2 (imp_count
+ cat_count
- 1,
1417 imp_count
== 0 && cat_count
== 0
1419 field_decl
= create_builtin_decl (FIELD_DECL
,
1420 build_array_type (ptr_type_node
, index
),
1422 chainon (field_decl_chain
, field_decl
);
1424 finish_struct (objc_symtab_template
, field_decl_chain
, NULL_TREE
);
1427 /* Create the initial value for the `defs' field of _objc_symtab.
1428 This is a CONSTRUCTOR. */
1431 init_def_list (type
)
1434 tree expr
, initlist
= NULL_TREE
;
1435 struct imp_entry
*impent
;
1438 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1440 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
1442 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1443 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1448 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1450 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1452 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1453 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1457 if (!flag_next_runtime
)
1459 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1462 if (static_instances_decl
)
1463 expr
= build_unary_op (ADDR_EXPR
, static_instances_decl
, 0);
1465 expr
= build_int_2 (0, 0);
1467 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1470 return build_constructor (type
, nreverse (initlist
));
1473 /* Construct the initial value for all of _objc_symtab. */
1476 init_objc_symtab (type
)
1481 /* sel_ref_cnt = { ..., 5, ... } */
1483 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1485 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1487 if (flag_next_runtime
|| ! sel_ref_chain
)
1488 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1490 initlist
= tree_cons (NULL_TREE
,
1491 build_unary_op (ADDR_EXPR
,
1492 UOBJC_SELECTOR_TABLE_decl
, 1),
1495 /* cls_def_cnt = { ..., 5, ... } */
1497 initlist
= tree_cons (NULL_TREE
, build_int_2 (imp_count
, 0), initlist
);
1499 /* cat_def_cnt = { ..., 5, ... } */
1501 initlist
= tree_cons (NULL_TREE
, build_int_2 (cat_count
, 0), initlist
);
1503 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1505 if (imp_count
|| cat_count
|| static_instances_decl
)
1508 tree field
= TYPE_FIELDS (type
);
1509 field
= TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field
))));
1511 initlist
= tree_cons (NULL_TREE
, init_def_list (TREE_TYPE (field
)),
1515 return build_constructor (type
, nreverse (initlist
));
1518 /* Push forward-declarations of all the categories so that
1519 init_def_list can use them in a CONSTRUCTOR. */
1522 forward_declare_categories ()
1524 struct imp_entry
*impent
;
1525 tree sav
= objc_implementation_context
;
1527 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1529 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1531 /* Set an invisible arg to synth_id_with_class_suffix. */
1532 objc_implementation_context
= impent
->imp_context
;
1534 = create_builtin_decl (VAR_DECL
, objc_category_template
,
1535 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", objc_implementation_context
)));
1538 objc_implementation_context
= sav
;
1541 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1542 and initialized appropriately. */
1545 generate_objc_symtab_decl ()
1549 if (!objc_category_template
)
1550 build_category_template ();
1552 /* forward declare categories */
1554 forward_declare_categories ();
1556 if (!objc_symtab_template
)
1557 build_objc_symtab_template ();
1559 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
1561 UOBJC_SYMBOLS_decl
= start_decl (get_identifier ("_OBJC_SYMBOLS"),
1562 tree_cons (NULL_TREE
,
1563 objc_symtab_template
, sc_spec
),
1567 TREE_USED (UOBJC_SYMBOLS_decl
) = 1;
1568 DECL_IGNORED_P (UOBJC_SYMBOLS_decl
) = 1;
1569 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl
) = 1;
1570 finish_decl (UOBJC_SYMBOLS_decl
,
1571 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)),
1576 init_module_descriptor (type
)
1579 tree initlist
, expr
;
1581 /* version = { 1, ... } */
1583 expr
= build_int_2 (OBJC_VERSION
, 0);
1584 initlist
= build_tree_list (NULL_TREE
, expr
);
1586 /* size = { ..., sizeof (struct objc_module), ... } */
1588 expr
= size_in_bytes (objc_module_template
);
1589 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1591 /* name = { ..., "foo.m", ... } */
1593 expr
= add_objc_string (get_identifier (input_filename
), class_names
);
1594 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1596 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1598 if (UOBJC_SYMBOLS_decl
)
1599 expr
= build_unary_op (ADDR_EXPR
, UOBJC_SYMBOLS_decl
, 0);
1601 expr
= build_int_2 (0, 0);
1602 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1604 return build_constructor (type
, nreverse (initlist
));
1607 /* Write out the data structures to describe Objective C classes defined.
1608 If appropriate, compile and output a setup function to initialize them.
1609 Return a symbol_ref to the function to call to initialize the Objective C
1610 data structures for this file (and perhaps for other files also).
1612 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1615 build_module_descriptor ()
1617 tree decl_specs
, field_decl
, field_decl_chain
;
1619 objc_module_template
1620 = start_struct (RECORD_TYPE
, get_identifier (UTAG_MODULE
));
1624 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1625 field_decl
= get_identifier ("version");
1627 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1628 field_decl_chain
= field_decl
;
1632 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1633 field_decl
= get_identifier ("size");
1635 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1636 chainon (field_decl_chain
, field_decl
);
1640 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
1641 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
1643 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1644 chainon (field_decl_chain
, field_decl
);
1646 /* struct objc_symtab *symtab; */
1648 decl_specs
= get_identifier (UTAG_SYMTAB
);
1649 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
1650 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("symtab"));
1652 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1653 chainon (field_decl_chain
, field_decl
);
1655 finish_struct (objc_module_template
, field_decl_chain
, NULL_TREE
);
1657 /* Create an instance of "objc_module". */
1659 decl_specs
= tree_cons (NULL_TREE
, objc_module_template
,
1660 build_tree_list (NULL_TREE
,
1661 ridpointers
[(int) RID_STATIC
]));
1663 UOBJC_MODULES_decl
= start_decl (get_identifier ("_OBJC_MODULES"),
1664 decl_specs
, 1, NULL_TREE
);
1666 DECL_ARTIFICIAL (UOBJC_MODULES_decl
) = 1;
1667 DECL_IGNORED_P (UOBJC_MODULES_decl
) = 1;
1668 DECL_CONTEXT (UOBJC_MODULES_decl
) = NULL_TREE
;
1670 finish_decl (UOBJC_MODULES_decl
,
1671 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl
)),
1674 /* Mark the decl to avoid "defined but not used" warning. */
1675 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl
) = 1;
1677 /* Generate a constructor call for the module descriptor.
1678 This code was generated by reading the grammar rules
1679 of c-parse.in; Therefore, it may not be the most efficient
1680 way of generating the requisite code. */
1682 if (flag_next_runtime
)
1686 tree parms
, execclass_decl
, decelerator
, void_list_node_1
;
1687 tree init_function_name
, init_function_decl
;
1689 /* Declare void __objc_execClass (void *); */
1691 void_list_node_1
= build_tree_list (NULL_TREE
, void_type_node
);
1692 execclass_decl
= build_decl (FUNCTION_DECL
,
1693 get_identifier (TAG_EXECCLASS
),
1694 build_function_type (void_type_node
,
1695 tree_cons (NULL_TREE
, ptr_type_node
,
1696 void_list_node_1
)));
1697 DECL_EXTERNAL (execclass_decl
) = 1;
1698 DECL_ARTIFICIAL (execclass_decl
) = 1;
1699 TREE_PUBLIC (execclass_decl
) = 1;
1700 pushdecl (execclass_decl
);
1701 rest_of_decl_compilation (execclass_decl
, 0, 0, 0);
1702 assemble_external (execclass_decl
);
1704 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1706 init_function_name
= get_file_function_name ('I');
1707 start_function (void_list_node_1
,
1708 build_nt (CALL_EXPR
, init_function_name
,
1709 tree_cons (NULL_TREE
, NULL_TREE
,
1713 store_parm_decls ();
1715 init_function_decl
= current_function_decl
;
1716 TREE_PUBLIC (init_function_decl
) = ! targetm
.have_ctors_dtors
;
1717 TREE_USED (init_function_decl
) = 1;
1718 /* Don't let this one be deferred. */
1719 DECL_INLINE (init_function_decl
) = 0;
1720 DECL_UNINLINABLE (init_function_decl
) = 1;
1721 current_function_cannot_inline
1722 = "static constructors and destructors cannot be inlined";
1725 = build_tree_list (NULL_TREE
,
1726 build_unary_op (ADDR_EXPR
, UOBJC_MODULES_decl
, 0));
1727 decelerator
= build_function_call (execclass_decl
, parms
);
1729 c_expand_expr_stmt (decelerator
);
1731 finish_function (0, 0);
1733 return XEXP (DECL_RTL (init_function_decl
), 0);
1737 /* extern const char _OBJC_STRINGS[]; */
1740 generate_forward_declaration_to_string_table ()
1742 tree sc_spec
, decl_specs
, expr_decl
;
1744 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_EXTERN
], NULL_TREE
);
1745 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1748 = build_nt (ARRAY_REF
, get_identifier ("_OBJC_STRINGS"), NULL_TREE
);
1750 UOBJC_STRINGS_decl
= define_decl (expr_decl
, decl_specs
);
1753 /* Return the DECL of the string IDENT in the SECTION. */
1756 get_objc_string_decl (ident
, section
)
1758 enum string_section section
;
1762 if (section
== class_names
)
1763 chain
= class_names_chain
;
1764 else if (section
== meth_var_names
)
1765 chain
= meth_var_names_chain
;
1766 else if (section
== meth_var_types
)
1767 chain
= meth_var_types_chain
;
1771 for (; chain
!= 0; chain
= TREE_VALUE (chain
))
1772 if (TREE_VALUE (chain
) == ident
)
1773 return (TREE_PURPOSE (chain
));
1779 /* Output references to all statically allocated objects. Return the DECL
1780 for the array built. */
1783 generate_static_references ()
1785 tree decls
= NULL_TREE
, ident
, decl_spec
, expr_decl
, expr
= NULL_TREE
;
1786 tree class_name
, class, decl
, initlist
;
1787 tree cl_chain
, in_chain
, type
;
1788 int num_inst
, num_class
;
1791 if (flag_next_runtime
)
1794 for (cl_chain
= objc_static_instances
, num_class
= 0;
1795 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
1797 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
1798 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
1800 sprintf (buf
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
1801 ident
= get_identifier (buf
);
1803 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1804 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1805 build_tree_list (NULL_TREE
,
1806 ridpointers
[(int) RID_STATIC
]));
1807 decl
= start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
);
1808 DECL_CONTEXT (decl
) = 0;
1809 DECL_ARTIFICIAL (decl
) = 1;
1811 /* Output {class_name, ...}. */
1812 class = TREE_VALUE (cl_chain
);
1813 class_name
= get_objc_string_decl (TYPE_NAME (class), class_names
);
1814 initlist
= build_tree_list (NULL_TREE
,
1815 build_unary_op (ADDR_EXPR
, class_name
, 1));
1817 /* Output {..., instance, ...}. */
1818 for (in_chain
= TREE_PURPOSE (cl_chain
);
1819 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
1821 expr
= build_unary_op (ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
1822 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1825 /* Output {..., NULL}. */
1826 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1828 expr
= build_constructor (TREE_TYPE (decl
), nreverse (initlist
));
1829 finish_decl (decl
, expr
, NULL_TREE
);
1830 TREE_USED (decl
) = 1;
1832 type
= build_array_type (build_pointer_type (void_type_node
), 0);
1833 decl
= build_decl (VAR_DECL
, ident
, type
);
1834 TREE_USED (decl
) = 1;
1835 TREE_STATIC (decl
) = 1;
1837 = tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, decl
, 1), decls
);
1840 decls
= tree_cons (NULL_TREE
, build_int_2 (0, 0), decls
);
1841 ident
= get_identifier ("_OBJC_STATIC_INSTANCES");
1842 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1843 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1844 build_tree_list (NULL_TREE
,
1845 ridpointers
[(int) RID_STATIC
]));
1846 static_instances_decl
1847 = start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
);
1848 TREE_USED (static_instances_decl
) = 1;
1849 DECL_CONTEXT (static_instances_decl
) = 0;
1850 DECL_ARTIFICIAL (static_instances_decl
) = 1;
1851 expr
= build_constructor (TREE_TYPE (static_instances_decl
),
1853 finish_decl (static_instances_decl
, expr
, NULL_TREE
);
1856 /* Output all strings. */
1861 tree sc_spec
, decl_specs
, expr_decl
;
1862 tree chain
, string_expr
;
1865 for (chain
= class_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1867 string
= TREE_VALUE (chain
);
1868 decl
= TREE_PURPOSE (chain
);
1870 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1871 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1872 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1873 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1874 DECL_CONTEXT (decl
) = NULL_TREE
;
1875 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1876 IDENTIFIER_POINTER (string
));
1877 finish_decl (decl
, string_expr
, NULL_TREE
);
1880 for (chain
= meth_var_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1882 string
= TREE_VALUE (chain
);
1883 decl
= TREE_PURPOSE (chain
);
1885 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1886 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1887 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1888 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1889 DECL_CONTEXT (decl
) = NULL_TREE
;
1890 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1891 IDENTIFIER_POINTER (string
));
1892 finish_decl (decl
, string_expr
, NULL_TREE
);
1895 for (chain
= meth_var_types_chain
; chain
; chain
= TREE_CHAIN (chain
))
1897 string
= TREE_VALUE (chain
);
1898 decl
= TREE_PURPOSE (chain
);
1900 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1901 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1902 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1903 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1904 DECL_CONTEXT (decl
) = NULL_TREE
;
1905 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1906 IDENTIFIER_POINTER (string
));
1907 finish_decl (decl
, string_expr
, NULL_TREE
);
1912 build_selector_reference_decl ()
1918 sprintf (buf
, "_OBJC_SELECTOR_REFERENCES_%d", idx
++);
1920 ident
= get_identifier (buf
);
1922 decl
= build_decl (VAR_DECL
, ident
, selector_type
);
1923 DECL_EXTERNAL (decl
) = 1;
1924 TREE_PUBLIC (decl
) = 1;
1925 TREE_USED (decl
) = 1;
1926 TREE_READONLY (decl
) = 1;
1927 DECL_ARTIFICIAL (decl
) = 1;
1928 DECL_CONTEXT (decl
) = 0;
1930 make_decl_rtl (decl
, 0);
1931 pushdecl_top_level (decl
);
1936 /* Just a handy wrapper for add_objc_string. */
1939 build_selector (ident
)
1942 tree expr
= add_objc_string (ident
, meth_var_names
);
1943 if (flag_typed_selectors
)
1946 return build_c_cast (selector_type
, expr
); /* cast! */
1950 build_selector_translation_table ()
1952 tree sc_spec
, decl_specs
;
1953 tree chain
, initlist
= NULL_TREE
;
1955 tree decl
= NULL_TREE
, var_decl
, name
;
1957 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
1961 expr
= build_selector (TREE_VALUE (chain
));
1963 if (flag_next_runtime
)
1965 name
= DECL_NAME (TREE_PURPOSE (chain
));
1967 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
1969 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
1970 decl_specs
= tree_cons (NULL_TREE
, selector_type
, sc_spec
);
1974 /* The `decl' that is returned from start_decl is the one that we
1975 forward declared in `build_selector_reference' */
1976 decl
= start_decl (var_decl
, decl_specs
, 1, NULL_TREE
);
1979 /* add one for the '\0' character */
1980 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (chain
)) + 1;
1982 if (flag_next_runtime
)
1983 finish_decl (decl
, expr
, NULL_TREE
);
1986 if (flag_typed_selectors
)
1988 tree eltlist
= NULL_TREE
;
1989 tree encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
1990 eltlist
= tree_cons (NULL_TREE
, expr
, NULL_TREE
);
1991 eltlist
= tree_cons (NULL_TREE
, encoding
, eltlist
);
1992 expr
= build_constructor (objc_selector_template
,
1993 nreverse (eltlist
));
1995 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2000 if (! flag_next_runtime
)
2002 /* Cause the variable and its initial value to be actually output. */
2003 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl
) = 0;
2004 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl
) = 1;
2005 /* NULL terminate the list and fix the decl for output. */
2006 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
2007 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl
) = objc_ellipsis_node
;
2008 initlist
= build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
2009 nreverse (initlist
));
2010 finish_decl (UOBJC_SELECTOR_TABLE_decl
, initlist
, NULL_TREE
);
2011 current_function_decl
= NULL_TREE
;
2016 get_proto_encoding (proto
)
2024 if (! METHOD_ENCODING (proto
))
2026 tmp_decl
= build_tmp_function_decl ();
2027 hack_method_prototype (proto
, tmp_decl
);
2028 encoding
= encode_method_prototype (proto
, tmp_decl
);
2029 METHOD_ENCODING (proto
) = encoding
;
2032 encoding
= METHOD_ENCODING (proto
);
2034 return add_objc_string (encoding
, meth_var_types
);
2037 return build_int_2 (0, 0);
2040 /* sel_ref_chain is a list whose "value" fields will be instances of
2041 identifier_node that represent the selector. */
2044 build_typed_selector_reference (ident
, proto
)
2047 tree
*chain
= &sel_ref_chain
;
2053 if (TREE_PURPOSE (*chain
) == ident
&& TREE_VALUE (*chain
) == proto
)
2054 goto return_at_index
;
2057 chain
= &TREE_CHAIN (*chain
);
2060 *chain
= tree_cons (proto
, ident
, NULL_TREE
);
2063 expr
= build_unary_op (ADDR_EXPR
,
2064 build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2065 build_int_2 (index
, 0)),
2067 return build_c_cast (selector_type
, expr
);
2071 build_selector_reference (ident
)
2074 tree
*chain
= &sel_ref_chain
;
2080 if (TREE_VALUE (*chain
) == ident
)
2081 return (flag_next_runtime
2082 ? TREE_PURPOSE (*chain
)
2083 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2084 build_int_2 (index
, 0)));
2087 chain
= &TREE_CHAIN (*chain
);
2090 expr
= build_selector_reference_decl ();
2092 *chain
= tree_cons (expr
, ident
, NULL_TREE
);
2094 return (flag_next_runtime
2096 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2097 build_int_2 (index
, 0)));
2101 build_class_reference_decl ()
2107 sprintf (buf
, "_OBJC_CLASS_REFERENCES_%d", idx
++);
2109 ident
= get_identifier (buf
);
2111 decl
= build_decl (VAR_DECL
, ident
, objc_class_type
);
2112 DECL_EXTERNAL (decl
) = 1;
2113 TREE_PUBLIC (decl
) = 1;
2114 TREE_USED (decl
) = 1;
2115 TREE_READONLY (decl
) = 1;
2116 DECL_CONTEXT (decl
) = 0;
2117 DECL_ARTIFICIAL (decl
) = 1;
2119 make_decl_rtl (decl
, 0);
2120 pushdecl_top_level (decl
);
2125 /* Create a class reference, but don't create a variable to reference
2129 add_class_reference (ident
)
2134 if ((chain
= cls_ref_chain
))
2139 if (ident
== TREE_VALUE (chain
))
2143 chain
= TREE_CHAIN (chain
);
2147 /* Append to the end of the list */
2148 TREE_CHAIN (tail
) = tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2151 cls_ref_chain
= tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2154 /* Get a class reference, creating it if necessary. Also create the
2155 reference variable. */
2158 get_class_reference (ident
)
2161 if (flag_next_runtime
)
2166 for (chain
= &cls_ref_chain
; *chain
; chain
= &TREE_CHAIN (*chain
))
2167 if (TREE_VALUE (*chain
) == ident
)
2169 if (! TREE_PURPOSE (*chain
))
2170 TREE_PURPOSE (*chain
) = build_class_reference_decl ();
2172 return TREE_PURPOSE (*chain
);
2175 decl
= build_class_reference_decl ();
2176 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2183 add_class_reference (ident
);
2185 params
= build_tree_list (NULL_TREE
,
2186 my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
2187 IDENTIFIER_POINTER (ident
)));
2189 assemble_external (objc_get_class_decl
);
2190 return build_function_call (objc_get_class_decl
, params
);
2194 /* For each string section we have a chain which maps identifier nodes
2195 to decls for the strings. */
2198 add_objc_string (ident
, section
)
2200 enum string_section section
;
2204 if (section
== class_names
)
2205 chain
= &class_names_chain
;
2206 else if (section
== meth_var_names
)
2207 chain
= &meth_var_names_chain
;
2208 else if (section
== meth_var_types
)
2209 chain
= &meth_var_types_chain
;
2215 if (TREE_VALUE (*chain
) == ident
)
2216 return build_unary_op (ADDR_EXPR
, TREE_PURPOSE (*chain
), 1);
2218 chain
= &TREE_CHAIN (*chain
);
2221 decl
= build_objc_string_decl (section
);
2223 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2225 return build_unary_op (ADDR_EXPR
, decl
, 1);
2229 build_objc_string_decl (section
)
2230 enum string_section section
;
2234 static int class_names_idx
= 0;
2235 static int meth_var_names_idx
= 0;
2236 static int meth_var_types_idx
= 0;
2238 if (section
== class_names
)
2239 sprintf (buf
, "_OBJC_CLASS_NAME_%d", class_names_idx
++);
2240 else if (section
== meth_var_names
)
2241 sprintf (buf
, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx
++);
2242 else if (section
== meth_var_types
)
2243 sprintf (buf
, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx
++);
2245 ident
= get_identifier (buf
);
2247 decl
= build_decl (VAR_DECL
, ident
, build_array_type (char_type_node
, 0));
2248 DECL_EXTERNAL (decl
) = 1;
2249 TREE_PUBLIC (decl
) = 1;
2250 TREE_USED (decl
) = 1;
2251 TREE_READONLY (decl
) = 1;
2252 TREE_CONSTANT (decl
) = 1;
2253 DECL_CONTEXT (decl
) = 0;
2254 DECL_ARTIFICIAL (decl
) = 1;
2256 make_decl_rtl (decl
, 0);
2257 pushdecl_top_level (decl
);
2264 objc_declare_alias (alias_ident
, class_ident
)
2268 if (is_class_name (class_ident
) != class_ident
)
2269 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident
));
2270 else if (is_class_name (alias_ident
))
2271 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident
));
2273 alias_chain
= tree_cons (class_ident
, alias_ident
, alias_chain
);
2277 objc_declare_class (ident_list
)
2282 for (list
= ident_list
; list
; list
= TREE_CHAIN (list
))
2284 tree ident
= TREE_VALUE (list
);
2287 if ((decl
= lookup_name (ident
)))
2289 error ("`%s' redeclared as different kind of symbol",
2290 IDENTIFIER_POINTER (ident
));
2291 error_with_decl (decl
, "previous declaration of `%s'");
2294 if (! is_class_name (ident
))
2296 tree record
= xref_tag (RECORD_TYPE
, ident
);
2297 TREE_STATIC_TEMPLATE (record
) = 1;
2298 class_chain
= tree_cons (NULL_TREE
, ident
, class_chain
);
2304 is_class_name (ident
)
2309 if (lookup_interface (ident
))
2312 for (chain
= class_chain
; chain
; chain
= TREE_CHAIN (chain
))
2314 if (ident
== TREE_VALUE (chain
))
2318 for (chain
= alias_chain
; chain
; chain
= TREE_CHAIN (chain
))
2320 if (ident
== TREE_VALUE (chain
))
2321 return TREE_PURPOSE (chain
);
2328 lookup_interface (ident
)
2333 for (chain
= interface_chain
; chain
; chain
= TREE_CHAIN (chain
))
2335 if (ident
== CLASS_NAME (chain
))
2342 objc_copy_list (list
, head
)
2346 tree newlist
= NULL_TREE
, tail
= NULL_TREE
;
2350 tail
= copy_node (list
);
2352 /* The following statement fixes a bug when inheriting instance
2353 variables that are declared to be bitfields. finish_struct
2354 expects to find the width of the bitfield in DECL_INITIAL. */
2355 if (DECL_BIT_FIELD (tail
) && DECL_INITIAL (tail
) == 0)
2356 DECL_INITIAL (tail
) = DECL_SIZE (tail
);
2358 newlist
= chainon (newlist
, tail
);
2359 list
= TREE_CHAIN (list
);
2366 /* Used by: build_private_template, get_class_ivars, and
2367 continue_class. COPY is 1 when called from @defs. In this case
2368 copy all fields. Otherwise don't copy leaf ivars since we rely on
2369 them being side-effected exactly once by finish_struct. */
2372 build_ivar_chain (interface
, copy
)
2376 tree my_name
, super_name
, ivar_chain
;
2378 my_name
= CLASS_NAME (interface
);
2379 super_name
= CLASS_SUPER_NAME (interface
);
2381 /* Possibly copy leaf ivars. */
2383 objc_copy_list (CLASS_IVARS (interface
), &ivar_chain
);
2385 ivar_chain
= CLASS_IVARS (interface
);
2390 tree super_interface
= lookup_interface (super_name
);
2392 if (!super_interface
)
2394 /* fatal did not work with 2 args...should fix */
2395 error ("cannot find interface declaration for `%s', superclass of `%s'",
2396 IDENTIFIER_POINTER (super_name
),
2397 IDENTIFIER_POINTER (my_name
));
2398 exit (FATAL_EXIT_CODE
);
2401 if (super_interface
== interface
)
2402 fatal_error ("circular inheritance in interface declaration for `%s'",
2403 IDENTIFIER_POINTER (super_name
));
2405 interface
= super_interface
;
2406 my_name
= CLASS_NAME (interface
);
2407 super_name
= CLASS_SUPER_NAME (interface
);
2409 op1
= CLASS_IVARS (interface
);
2412 tree head
, tail
= objc_copy_list (op1
, &head
);
2414 /* Prepend super class ivars...make a copy of the list, we
2415 do not want to alter the original. */
2416 TREE_CHAIN (tail
) = ivar_chain
;
2423 /* struct <classname> {
2424 struct objc_class *isa;
2429 build_private_template (class)
2434 if (CLASS_STATIC_TEMPLATE (class))
2436 uprivate_record
= CLASS_STATIC_TEMPLATE (class);
2437 ivar_context
= TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2441 uprivate_record
= start_struct (RECORD_TYPE
, CLASS_NAME (class));
2443 ivar_context
= build_ivar_chain (class, 0);
2445 finish_struct (uprivate_record
, ivar_context
, NULL_TREE
);
2447 CLASS_STATIC_TEMPLATE (class) = uprivate_record
;
2449 /* mark this record as class template - for class type checking */
2450 TREE_STATIC_TEMPLATE (uprivate_record
) = 1;
2454 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
2456 build1 (INDIRECT_REF
, NULL_TREE
,
2459 return ivar_context
;
2462 /* Begin code generation for protocols... */
2464 /* struct objc_protocol {
2465 char *protocol_name;
2466 struct objc_protocol **protocol_list;
2467 struct objc_method_desc *instance_methods;
2468 struct objc_method_desc *class_methods;
2472 build_protocol_template ()
2474 tree decl_specs
, field_decl
, field_decl_chain
;
2477 template = start_struct (RECORD_TYPE
, get_identifier (UTAG_PROTOCOL
));
2479 /* struct objc_class *isa; */
2481 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2482 get_identifier (UTAG_CLASS
)));
2483 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
2485 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2486 field_decl_chain
= field_decl
;
2488 /* char *protocol_name; */
2490 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
2492 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_name"));
2494 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2495 chainon (field_decl_chain
, field_decl
);
2497 /* struct objc_protocol **protocol_list; */
2499 decl_specs
= build_tree_list (NULL_TREE
, template);
2501 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
2502 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
2504 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2505 chainon (field_decl_chain
, field_decl
);
2507 /* struct objc_method_list *instance_methods; */
2510 = build_tree_list (NULL_TREE
,
2511 xref_tag (RECORD_TYPE
,
2512 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2514 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
2516 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2517 chainon (field_decl_chain
, field_decl
);
2519 /* struct objc_method_list *class_methods; */
2522 = build_tree_list (NULL_TREE
,
2523 xref_tag (RECORD_TYPE
,
2524 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2526 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
2528 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2529 chainon (field_decl_chain
, field_decl
);
2531 return finish_struct (template, field_decl_chain
, NULL_TREE
);
2535 build_descriptor_table_initializer (type
, entries
)
2539 tree initlist
= NULL_TREE
;
2543 tree eltlist
= NULL_TREE
;
2546 = tree_cons (NULL_TREE
,
2547 build_selector (METHOD_SEL_NAME (entries
)), NULL_TREE
);
2549 = tree_cons (NULL_TREE
,
2550 add_objc_string (METHOD_ENCODING (entries
),
2555 = tree_cons (NULL_TREE
,
2556 build_constructor (type
, nreverse (eltlist
)), initlist
);
2558 entries
= TREE_CHAIN (entries
);
2562 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
2565 /* struct objc_method_prototype_list {
2567 struct objc_method_prototype {
2574 build_method_prototype_list_template (list_type
, size
)
2578 tree objc_ivar_list_record
;
2579 tree decl_specs
, field_decl
, field_decl_chain
;
2581 /* Generate an unnamed struct definition. */
2583 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
2585 /* int method_count; */
2587 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
2588 field_decl
= get_identifier ("method_count");
2591 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2592 field_decl_chain
= field_decl
;
2594 /* struct objc_method method_list[]; */
2596 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
2597 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
2598 build_int_2 (size
, 0));
2601 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2602 chainon (field_decl_chain
, field_decl
);
2604 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
2606 return objc_ivar_list_record
;
2610 build_method_prototype_template ()
2613 tree decl_specs
, field_decl
, field_decl_chain
;
2616 = start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD_PROTOTYPE
));
2618 /* struct objc_selector *_cmd; */
2619 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
2620 get_identifier (TAG_SELECTOR
)), NULL_TREE
);
2621 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
2624 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2625 field_decl_chain
= field_decl
;
2627 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
2629 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_types"));
2631 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2632 chainon (field_decl_chain
, field_decl
);
2634 finish_struct (proto_record
, field_decl_chain
, NULL_TREE
);
2636 return proto_record
;
2639 /* True if last call to forwarding_offset yielded a register offset. */
2640 static int offset_is_register
;
2643 forwarding_offset (parm
)
2646 int offset_in_bytes
;
2648 if (GET_CODE (DECL_INCOMING_RTL (parm
)) == MEM
)
2650 rtx addr
= XEXP (DECL_INCOMING_RTL (parm
), 0);
2652 /* ??? Here we assume that the parm address is indexed
2653 off the frame pointer or arg pointer.
2654 If that is not true, we produce meaningless results,
2655 but do not crash. */
2656 if (GET_CODE (addr
) == PLUS
2657 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
2658 offset_in_bytes
= INTVAL (XEXP (addr
, 1));
2660 offset_in_bytes
= 0;
2662 offset_in_bytes
+= OBJC_FORWARDING_STACK_OFFSET
;
2663 offset_is_register
= 0;
2665 else if (GET_CODE (DECL_INCOMING_RTL (parm
)) == REG
)
2667 int regno
= REGNO (DECL_INCOMING_RTL (parm
));
2668 offset_in_bytes
= apply_args_register_offset (regno
);
2669 offset_is_register
= 1;
2674 /* This is the case where the parm is passed as an int or double
2675 and it is converted to a char, short or float and stored back
2676 in the parmlist. In this case, describe the parm
2677 with the variable's declared type, and adjust the address
2678 if the least significant bytes (which we are using) are not
2680 if (BYTES_BIG_ENDIAN
&& TREE_TYPE (parm
) != DECL_ARG_TYPE (parm
))
2681 offset_in_bytes
+= (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm
)))
2682 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm
))));
2684 return offset_in_bytes
;
2688 encode_method_prototype (method_decl
, func_decl
)
2695 HOST_WIDE_INT max_parm_end
= 0;
2699 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2700 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl
)));
2703 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
2704 obstack_object_size (&util_obstack
),
2705 OBJC_ENCODE_INLINE_DEFS
);
2708 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
2709 parms
= TREE_CHAIN (parms
))
2711 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
2712 + int_size_in_bytes (TREE_TYPE (parms
)));
2714 if (!offset_is_register
&& max_parm_end
< parm_end
)
2715 max_parm_end
= parm_end
;
2718 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
2720 sprintf (buf
, "%d", stack_size
);
2721 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2723 user_args
= METHOD_SEL_ARGS (method_decl
);
2725 /* Argument types. */
2726 for (parms
= DECL_ARGUMENTS (func_decl
), i
= 0; parms
;
2727 parms
= TREE_CHAIN (parms
), i
++)
2729 /* Process argument qualifiers for user supplied arguments. */
2732 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args
)));
2733 user_args
= TREE_CHAIN (user_args
);
2737 encode_type (TREE_TYPE (parms
),
2738 obstack_object_size (&util_obstack
),
2739 OBJC_ENCODE_INLINE_DEFS
);
2741 /* Compute offset. */
2742 sprintf (buf
, "%d", forwarding_offset (parms
));
2744 /* Indicate register. */
2745 if (offset_is_register
)
2746 obstack_1grow (&util_obstack
, '+');
2748 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2751 obstack_1grow (&util_obstack
, '\0');
2752 result
= get_identifier (obstack_finish (&util_obstack
));
2753 obstack_free (&util_obstack
, util_firstobj
);
2758 generate_descriptor_table (type
, name
, size
, list
, proto
)
2765 tree sc_spec
, decl_specs
, decl
, initlist
;
2767 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2768 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
2770 decl
= start_decl (synth_id_with_class_suffix (name
, proto
),
2771 decl_specs
, 1, NULL_TREE
);
2772 DECL_CONTEXT (decl
) = NULL_TREE
;
2774 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
2775 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
2777 finish_decl (decl
, build_constructor (type
, nreverse (initlist
)),
2784 generate_method_descriptors (protocol
)
2787 tree initlist
, chain
, method_list_template
;
2788 tree cast
, variable_length_type
;
2791 if (!objc_method_prototype_template
)
2792 objc_method_prototype_template
= build_method_prototype_template ();
2794 cast
= build_tree_list (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2795 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
))),
2797 variable_length_type
= groktypename (cast
);
2799 chain
= PROTOCOL_CLS_METHODS (protocol
);
2802 size
= list_length (chain
);
2804 method_list_template
2805 = build_method_prototype_list_template (objc_method_prototype_template
,
2809 = build_descriptor_table_initializer (objc_method_prototype_template
,
2812 UOBJC_CLASS_METHODS_decl
2813 = generate_descriptor_table (method_list_template
,
2814 "_OBJC_PROTOCOL_CLASS_METHODS",
2815 size
, initlist
, protocol
);
2816 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
2819 UOBJC_CLASS_METHODS_decl
= 0;
2821 chain
= PROTOCOL_NST_METHODS (protocol
);
2824 size
= list_length (chain
);
2826 method_list_template
2827 = build_method_prototype_list_template (objc_method_prototype_template
,
2830 = build_descriptor_table_initializer (objc_method_prototype_template
,
2833 UOBJC_INSTANCE_METHODS_decl
2834 = generate_descriptor_table (method_list_template
,
2835 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2836 size
, initlist
, protocol
);
2837 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
2840 UOBJC_INSTANCE_METHODS_decl
= 0;
2843 /* Generate a temporary FUNCTION_DECL node to be used in
2844 hack_method_prototype below. */
2847 build_tmp_function_decl ()
2849 tree decl_specs
, expr_decl
, parms
;
2853 /* struct objc_object *objc_xxx (id, SEL, ...); */
2855 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
2856 push_parm_decl (build_tree_list
2857 (build_tree_list (decl_specs
,
2858 build1 (INDIRECT_REF
, NULL_TREE
,
2862 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2863 get_identifier (TAG_SELECTOR
)));
2864 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
);
2866 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, expr_decl
),
2868 parms
= get_parm_info (0);
2871 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
2872 sprintf (buffer
, "__objc_tmp_%x", xxx
++);
2873 expr_decl
= build_nt (CALL_EXPR
, get_identifier (buffer
), parms
, NULL_TREE
);
2874 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
2876 return define_decl (expr_decl
, decl_specs
);
2879 /* Generate the prototypes for protocol methods. This is used to
2880 generate method encodings for these.
2882 NST_METHODS is the method to generate a _DECL node for TMP_DECL is
2883 a decl node to be used. This is also where the return value is
2887 hack_method_prototype (nst_methods
, tmp_decl
)
2894 /* Hack to avoid problem with static typing of self arg. */
2895 TREE_SET_CODE (nst_methods
, CLASS_METHOD_DECL
);
2896 start_method_def (nst_methods
);
2897 TREE_SET_CODE (nst_methods
, INSTANCE_METHOD_DECL
);
2899 if (METHOD_ADD_ARGS (nst_methods
) == objc_ellipsis_node
)
2900 parms
= get_parm_info (0); /* we have a `, ...' */
2902 parms
= get_parm_info (1); /* place a `void_at_end' */
2904 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2906 /* Usually called from store_parm_decls -> init_function_start. */
2908 DECL_ARGUMENTS (tmp_decl
) = TREE_PURPOSE (parms
);
2910 if (current_function_decl
)
2912 current_function_decl
= tmp_decl
;
2915 /* Code taken from start_function. */
2916 tree restype
= TREE_TYPE (TREE_TYPE (tmp_decl
));
2917 /* Promote the value to int before returning it. */
2918 if (TREE_CODE (restype
) == INTEGER_TYPE
2919 && TYPE_PRECISION (restype
) < TYPE_PRECISION (integer_type_node
))
2920 restype
= integer_type_node
;
2921 DECL_RESULT (tmp_decl
) = build_decl (RESULT_DECL
, 0, restype
);
2924 for (parm
= DECL_ARGUMENTS (tmp_decl
); parm
; parm
= TREE_CHAIN (parm
))
2925 DECL_CONTEXT (parm
) = tmp_decl
;
2927 init_function_start (tmp_decl
, "objc-act", 0);
2929 /* Typically called from expand_function_start for function definitions. */
2930 assign_parms (tmp_decl
);
2932 /* install return type */
2933 TREE_TYPE (TREE_TYPE (tmp_decl
)) = groktypename (TREE_TYPE (nst_methods
));
2935 current_function_decl
= NULL
;
2939 generate_protocol_references (plist
)
2944 /* Forward declare protocols referenced. */
2945 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
2947 tree proto
= TREE_VALUE (lproto
);
2949 if (TREE_CODE (proto
) == PROTOCOL_INTERFACE_TYPE
2950 && PROTOCOL_NAME (proto
))
2952 if (! PROTOCOL_FORWARD_DECL (proto
))
2953 build_protocol_reference (proto
);
2955 if (PROTOCOL_LIST (proto
))
2956 generate_protocol_references (PROTOCOL_LIST (proto
));
2962 generate_protocols ()
2964 tree p
, tmp_decl
, encoding
;
2965 tree sc_spec
, decl_specs
, decl
;
2966 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
2969 tmp_decl
= build_tmp_function_decl ();
2971 if (! objc_protocol_template
)
2972 objc_protocol_template
= build_protocol_template ();
2974 /* If a protocol was directly referenced, pull in indirect references. */
2975 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
2976 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
2977 generate_protocol_references (PROTOCOL_LIST (p
));
2979 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
2981 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
2982 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
2984 /* If protocol wasn't referenced, don't generate any code. */
2985 if (! PROTOCOL_FORWARD_DECL (p
))
2988 /* Make sure we link in the Protocol class. */
2989 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
2993 if (! METHOD_ENCODING (nst_methods
))
2995 hack_method_prototype (nst_methods
, tmp_decl
);
2996 encoding
= encode_method_prototype (nst_methods
, tmp_decl
);
2997 METHOD_ENCODING (nst_methods
) = encoding
;
2999 nst_methods
= TREE_CHAIN (nst_methods
);
3004 if (! METHOD_ENCODING (cls_methods
))
3006 hack_method_prototype (cls_methods
, tmp_decl
);
3007 encoding
= encode_method_prototype (cls_methods
, tmp_decl
);
3008 METHOD_ENCODING (cls_methods
) = encoding
;
3011 cls_methods
= TREE_CHAIN (cls_methods
);
3013 generate_method_descriptors (p
);
3015 if (PROTOCOL_LIST (p
))
3016 refs_decl
= generate_protocol_list (p
);
3020 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3022 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
],
3024 decl_specs
= tree_cons (NULL_TREE
, objc_protocol_template
, sc_spec
);
3026 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
),
3027 decl_specs
, 1, NULL_TREE
);
3029 DECL_CONTEXT (decl
) = NULL_TREE
;
3031 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
3037 (build_tree_list (build_tree_list (NULL_TREE
,
3038 objc_protocol_template
),
3039 build1 (INDIRECT_REF
, NULL_TREE
,
3040 build1 (INDIRECT_REF
, NULL_TREE
,
3043 refs_expr
= build_unary_op (ADDR_EXPR
, refs_decl
, 0);
3044 TREE_TYPE (refs_expr
) = cast_type2
;
3047 refs_expr
= build_int_2 (0, 0);
3049 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3050 by generate_method_descriptors, which is called above. */
3051 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
3052 protocol_name_expr
, refs_expr
,
3053 UOBJC_INSTANCE_METHODS_decl
,
3054 UOBJC_CLASS_METHODS_decl
);
3055 finish_decl (decl
, initlist
, NULL_TREE
);
3057 /* Mark the decl as used to avoid "defined but not used" warning. */
3058 TREE_USED (decl
) = 1;
3063 build_protocol_initializer (type
, protocol_name
, protocol_list
,
3064 instance_methods
, class_methods
)
3068 tree instance_methods
;
3071 tree initlist
= NULL_TREE
, expr
;
3074 cast_type
= groktypename
3076 (build_tree_list (NULL_TREE
,
3077 xref_tag (RECORD_TYPE
,
3078 get_identifier (UTAG_CLASS
))),
3079 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
3081 /* Filling the "isa" in with one allows the runtime system to
3082 detect that the version change...should remove before final release. */
3084 expr
= build_int_2 (PROTOCOL_VERSION
, 0);
3085 TREE_TYPE (expr
) = cast_type
;
3086 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3087 initlist
= tree_cons (NULL_TREE
, protocol_name
, initlist
);
3088 initlist
= tree_cons (NULL_TREE
, protocol_list
, initlist
);
3090 if (!instance_methods
)
3091 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3094 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
3095 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3099 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3102 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
3103 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3106 return build_constructor (type
, nreverse (initlist
));
3109 /* struct objc_category {
3110 char *category_name;
3112 struct objc_method_list *instance_methods;
3113 struct objc_method_list *class_methods;
3114 struct objc_protocol_list *protocols;
3118 build_category_template ()
3120 tree decl_specs
, field_decl
, field_decl_chain
;
3122 objc_category_template
= start_struct (RECORD_TYPE
,
3123 get_identifier (UTAG_CATEGORY
));
3124 /* char *category_name; */
3126 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3128 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("category_name"));
3130 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3131 field_decl_chain
= field_decl
;
3133 /* char *class_name; */
3135 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3136 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_name"));
3138 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3139 chainon (field_decl_chain
, field_decl
);
3141 /* struct objc_method_list *instance_methods; */
3143 decl_specs
= build_tree_list (NULL_TREE
,
3144 xref_tag (RECORD_TYPE
,
3145 get_identifier (UTAG_METHOD_LIST
)));
3147 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
3149 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3150 chainon (field_decl_chain
, field_decl
);
3152 /* struct objc_method_list *class_methods; */
3154 decl_specs
= build_tree_list (NULL_TREE
,
3155 xref_tag (RECORD_TYPE
,
3156 get_identifier (UTAG_METHOD_LIST
)));
3158 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
3160 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3161 chainon (field_decl_chain
, field_decl
);
3163 /* struct objc_protocol **protocol_list; */
3165 decl_specs
= build_tree_list (NULL_TREE
,
3166 xref_tag (RECORD_TYPE
,
3167 get_identifier (UTAG_PROTOCOL
)));
3169 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3170 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3172 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3173 chainon (field_decl_chain
, field_decl
);
3175 finish_struct (objc_category_template
, field_decl_chain
, NULL_TREE
);
3178 /* struct objc_selector {
3184 build_selector_template ()
3187 tree decl_specs
, field_decl
, field_decl_chain
;
3189 objc_selector_template
3190 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SELECTOR
));
3194 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3195 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3197 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3198 field_decl_chain
= field_decl
;
3200 /* char *sel_type; */
3202 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3203 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_type"));
3205 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3206 chainon (field_decl_chain
, field_decl
);
3208 finish_struct (objc_selector_template
, field_decl_chain
, NULL_TREE
);
3211 /* struct objc_class {
3212 struct objc_class *isa;
3213 struct objc_class *super_class;
3218 struct objc_ivar_list *ivars;
3219 struct objc_method_list *methods;
3220 if (flag_next_runtime)
3221 struct objc_cache *cache;
3223 struct sarray *dtable;
3224 struct objc_class *subclass_list;
3225 struct objc_class *sibling_class;
3227 struct objc_protocol_list *protocols;
3228 void *gc_object_type;
3232 build_class_template ()
3234 tree decl_specs
, field_decl
, field_decl_chain
;
3237 = start_struct (RECORD_TYPE
, get_identifier (UTAG_CLASS
));
3239 /* struct objc_class *isa; */
3241 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3242 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
3244 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3245 field_decl_chain
= field_decl
;
3247 /* struct objc_class *super_class; */
3249 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3251 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("super_class"));
3253 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3254 chainon (field_decl_chain
, field_decl
);
3258 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3259 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
3261 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3262 chainon (field_decl_chain
, field_decl
);
3266 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3267 field_decl
= get_identifier ("version");
3269 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3270 chainon (field_decl_chain
, field_decl
);
3274 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3275 field_decl
= get_identifier ("info");
3277 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3278 chainon (field_decl_chain
, field_decl
);
3280 /* long instance_size; */
3282 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3283 field_decl
= get_identifier ("instance_size");
3285 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3286 chainon (field_decl_chain
, field_decl
);
3288 /* struct objc_ivar_list *ivars; */
3290 decl_specs
= build_tree_list (NULL_TREE
,
3291 xref_tag (RECORD_TYPE
,
3292 get_identifier (UTAG_IVAR_LIST
)));
3293 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivars"));
3295 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3296 chainon (field_decl_chain
, field_decl
);
3298 /* struct objc_method_list *methods; */
3300 decl_specs
= build_tree_list (NULL_TREE
,
3301 xref_tag (RECORD_TYPE
,
3302 get_identifier (UTAG_METHOD_LIST
)));
3303 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("methods"));
3305 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3306 chainon (field_decl_chain
, field_decl
);
3308 if (flag_next_runtime
)
3310 /* struct objc_cache *cache; */
3312 decl_specs
= build_tree_list (NULL_TREE
,
3313 xref_tag (RECORD_TYPE
,
3314 get_identifier ("objc_cache")));
3315 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("cache"));
3316 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3317 decl_specs
, NULL_TREE
);
3318 chainon (field_decl_chain
, field_decl
);
3322 /* struct sarray *dtable; */
3324 decl_specs
= build_tree_list (NULL_TREE
,
3325 xref_tag (RECORD_TYPE
,
3326 get_identifier ("sarray")));
3327 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("dtable"));
3328 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3329 decl_specs
, NULL_TREE
);
3330 chainon (field_decl_chain
, field_decl
);
3332 /* struct objc_class *subclass_list; */
3334 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3336 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("subclass_list"));
3337 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3338 decl_specs
, NULL_TREE
);
3339 chainon (field_decl_chain
, field_decl
);
3341 /* struct objc_class *sibling_class; */
3343 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3345 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sibling_class"));
3346 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3347 decl_specs
, NULL_TREE
);
3348 chainon (field_decl_chain
, field_decl
);
3351 /* struct objc_protocol **protocol_list; */
3353 decl_specs
= build_tree_list (NULL_TREE
,
3354 xref_tag (RECORD_TYPE
,
3355 get_identifier (UTAG_PROTOCOL
)));
3357 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3359 = build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3360 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3361 decl_specs
, NULL_TREE
);
3362 chainon (field_decl_chain
, field_decl
);
3366 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3367 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3369 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3370 chainon (field_decl_chain
, field_decl
);
3372 /* void *gc_object_type; */
3374 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3375 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("gc_object_type"));
3377 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3378 chainon (field_decl_chain
, field_decl
);
3380 finish_struct (objc_class_template
, field_decl_chain
, NULL_TREE
);
3383 /* Generate appropriate forward declarations for an implementation. */
3386 synth_forward_declarations ()
3388 tree sc_spec
, decl_specs
, an_id
;
3390 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3392 an_id
= synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context
);
3394 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
3395 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
3396 UOBJC_CLASS_decl
= define_decl (an_id
, decl_specs
);
3397 TREE_USED (UOBJC_CLASS_decl
) = 1;
3398 DECL_ARTIFICIAL (UOBJC_CLASS_decl
) = 1;
3400 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3402 an_id
= synth_id_with_class_suffix ("_OBJC_METACLASS",
3403 objc_implementation_context
);
3405 UOBJC_METACLASS_decl
= define_decl (an_id
, decl_specs
);
3406 TREE_USED (UOBJC_METACLASS_decl
) = 1;
3407 DECL_ARTIFICIAL(UOBJC_METACLASS_decl
) = 1;
3409 /* Pre-build the following entities - for speed/convenience. */
3411 an_id
= get_identifier ("super_class");
3412 ucls_super_ref
= build_component_ref (UOBJC_CLASS_decl
, an_id
);
3413 uucls_super_ref
= build_component_ref (UOBJC_METACLASS_decl
, an_id
);
3417 error_with_ivar (message
, decl
, rawdecl
)
3418 const char *message
;
3422 diagnostic_count_diagnostic (global_dc
, DK_ERROR
);
3424 diagnostic_report_current_function (global_dc
);
3426 error_with_file_and_line (DECL_SOURCE_FILE (decl
),
3427 DECL_SOURCE_LINE (decl
),
3429 message
, gen_declaration (rawdecl
, errbuf
));
3433 #define USERTYPE(t) \
3434 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3435 || TREE_CODE (t) == ENUMERAL_TYPE)
3438 check_ivars (inter
, imp
)
3442 tree intdecls
= CLASS_IVARS (inter
);
3443 tree impdecls
= CLASS_IVARS (imp
);
3444 tree rawintdecls
= CLASS_RAW_IVARS (inter
);
3445 tree rawimpdecls
= CLASS_RAW_IVARS (imp
);
3451 if (intdecls
== 0 && impdecls
== 0)
3453 if (intdecls
== 0 || impdecls
== 0)
3455 error ("inconsistent instance variable specification");
3459 t1
= TREE_TYPE (intdecls
); t2
= TREE_TYPE (impdecls
);
3461 if (!comptypes (t1
, t2
))
3463 if (DECL_NAME (intdecls
) == DECL_NAME (impdecls
))
3465 error_with_ivar ("conflicting instance variable type",
3466 impdecls
, rawimpdecls
);
3467 error_with_ivar ("previous declaration of",
3468 intdecls
, rawintdecls
);
3470 else /* both the type and the name don't match */
3472 error ("inconsistent instance variable specification");
3477 else if (DECL_NAME (intdecls
) != DECL_NAME (impdecls
))
3479 error_with_ivar ("conflicting instance variable name",
3480 impdecls
, rawimpdecls
);
3481 error_with_ivar ("previous declaration of",
3482 intdecls
, rawintdecls
);
3485 intdecls
= TREE_CHAIN (intdecls
);
3486 impdecls
= TREE_CHAIN (impdecls
);
3487 rawintdecls
= TREE_CHAIN (rawintdecls
);
3488 rawimpdecls
= TREE_CHAIN (rawimpdecls
);
3492 /* Set super_type to the data type node for struct objc_super *,
3493 first defining struct objc_super itself.
3494 This needs to be done just once per compilation. */
3497 build_super_template ()
3499 tree record
, decl_specs
, field_decl
, field_decl_chain
;
3501 record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_SUPER
));
3503 /* struct objc_object *self; */
3505 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3506 field_decl
= get_identifier ("self");
3507 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3508 field_decl
= grokfield (input_filename
, lineno
,
3509 field_decl
, decl_specs
, NULL_TREE
);
3510 field_decl_chain
= field_decl
;
3512 /* struct objc_class *class; */
3514 decl_specs
= get_identifier (UTAG_CLASS
);
3515 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
3516 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class"));
3518 field_decl
= grokfield (input_filename
, lineno
,
3519 field_decl
, decl_specs
, NULL_TREE
);
3520 chainon (field_decl_chain
, field_decl
);
3522 finish_struct (record
, field_decl_chain
, NULL_TREE
);
3524 /* `struct objc_super *' */
3525 super_type
= groktypename (build_tree_list (build_tree_list (NULL_TREE
,
3527 build1 (INDIRECT_REF
,
3528 NULL_TREE
, NULL_TREE
)));
3532 /* struct objc_ivar {
3539 build_ivar_template ()
3541 tree objc_ivar_id
, objc_ivar_record
;
3542 tree decl_specs
, field_decl
, field_decl_chain
;
3544 objc_ivar_id
= get_identifier (UTAG_IVAR
);
3545 objc_ivar_record
= start_struct (RECORD_TYPE
, objc_ivar_id
);
3547 /* char *ivar_name; */
3549 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3550 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_name"));
3552 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3553 decl_specs
, NULL_TREE
);
3554 field_decl_chain
= field_decl
;
3556 /* char *ivar_type; */
3558 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3559 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_type"));
3561 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3562 decl_specs
, NULL_TREE
);
3563 chainon (field_decl_chain
, field_decl
);
3565 /* int ivar_offset; */
3567 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3568 field_decl
= get_identifier ("ivar_offset");
3570 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3571 decl_specs
, NULL_TREE
);
3572 chainon (field_decl_chain
, field_decl
);
3574 finish_struct (objc_ivar_record
, field_decl_chain
, NULL_TREE
);
3576 return objc_ivar_record
;
3581 struct objc_ivar ivar_list[ivar_count];
3585 build_ivar_list_template (list_type
, size
)
3589 tree objc_ivar_list_record
;
3590 tree decl_specs
, field_decl
, field_decl_chain
;
3592 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3594 /* int ivar_count; */
3596 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3597 field_decl
= get_identifier ("ivar_count");
3599 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3600 decl_specs
, NULL_TREE
);
3601 field_decl_chain
= field_decl
;
3603 /* struct objc_ivar ivar_list[]; */
3605 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3606 field_decl
= build_nt (ARRAY_REF
, get_identifier ("ivar_list"),
3607 build_int_2 (size
, 0));
3609 field_decl
= grokfield (input_filename
, lineno
,
3610 field_decl
, decl_specs
, NULL_TREE
);
3611 chainon (field_decl_chain
, field_decl
);
3613 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3615 return objc_ivar_list_record
;
3621 struct objc_method method_list[method_count];
3625 build_method_list_template (list_type
, size
)
3629 tree objc_ivar_list_record
;
3630 tree decl_specs
, field_decl
, field_decl_chain
;
3632 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3634 /* int method_next; */
3639 xref_tag (RECORD_TYPE
,
3640 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
3642 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_next"));
3643 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3644 decl_specs
, NULL_TREE
);
3645 field_decl_chain
= field_decl
;
3647 /* int method_count; */
3649 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3650 field_decl
= get_identifier ("method_count");
3652 field_decl
= grokfield (input_filename
, lineno
,
3653 field_decl
, decl_specs
, NULL_TREE
);
3654 chainon (field_decl_chain
, field_decl
);
3656 /* struct objc_method method_list[]; */
3658 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3659 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
3660 build_int_2 (size
, 0));
3662 field_decl
= grokfield (input_filename
, lineno
,
3663 field_decl
, decl_specs
, NULL_TREE
);
3664 chainon (field_decl_chain
, field_decl
);
3666 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3668 return objc_ivar_list_record
;
3672 build_ivar_list_initializer (type
, field_decl
)
3676 tree initlist
= NULL_TREE
;
3680 tree ivar
= NULL_TREE
;
3683 if (DECL_NAME (field_decl
))
3684 ivar
= tree_cons (NULL_TREE
,
3685 add_objc_string (DECL_NAME (field_decl
),
3689 /* Unnamed bit-field ivar (yuck). */
3690 ivar
= tree_cons (NULL_TREE
, build_int_2 (0, 0), ivar
);
3693 encode_field_decl (field_decl
,
3694 obstack_object_size (&util_obstack
),
3695 OBJC_ENCODE_DONT_INLINE_DEFS
);
3697 /* Null terminate string. */
3698 obstack_1grow (&util_obstack
, 0);
3702 add_objc_string (get_identifier (obstack_finish (&util_obstack
)),
3705 obstack_free (&util_obstack
, util_firstobj
);
3708 ivar
= tree_cons (NULL_TREE
, byte_position (field_decl
), ivar
);
3709 initlist
= tree_cons (NULL_TREE
,
3710 build_constructor (type
, nreverse (ivar
)),
3713 field_decl
= TREE_CHAIN (field_decl
);
3717 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3721 generate_ivars_list (type
, name
, size
, list
)
3727 tree sc_spec
, decl_specs
, decl
, initlist
;
3729 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3730 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
3732 decl
= start_decl (synth_id_with_class_suffix (name
, objc_implementation_context
),
3733 decl_specs
, 1, NULL_TREE
);
3735 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
3736 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3739 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3746 generate_ivar_lists ()
3748 tree initlist
, ivar_list_template
, chain
;
3749 tree cast
, variable_length_type
;
3752 generating_instance_variables
= 1;
3754 if (!objc_ivar_template
)
3755 objc_ivar_template
= build_ivar_template ();
3759 (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3760 get_identifier (UTAG_IVAR_LIST
))),
3762 variable_length_type
= groktypename (cast
);
3764 /* Only generate class variables for the root of the inheritance
3765 hierarchy since these will be the same for every class. */
3767 if (CLASS_SUPER_NAME (implementation_template
) == NULL_TREE
3768 && (chain
= TYPE_FIELDS (objc_class_template
)))
3770 size
= list_length (chain
);
3772 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3773 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3775 UOBJC_CLASS_VARIABLES_decl
3776 = generate_ivars_list (ivar_list_template
, "_OBJC_CLASS_VARIABLES",
3778 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl
) = variable_length_type
;
3781 UOBJC_CLASS_VARIABLES_decl
= 0;
3783 chain
= CLASS_IVARS (implementation_template
);
3786 size
= list_length (chain
);
3787 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3788 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3790 UOBJC_INSTANCE_VARIABLES_decl
3791 = generate_ivars_list (ivar_list_template
, "_OBJC_INSTANCE_VARIABLES",
3793 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl
) = variable_length_type
;
3796 UOBJC_INSTANCE_VARIABLES_decl
= 0;
3798 generating_instance_variables
= 0;
3802 build_dispatch_table_initializer (type
, entries
)
3806 tree initlist
= NULL_TREE
;
3810 tree elemlist
= NULL_TREE
;
3812 elemlist
= tree_cons (NULL_TREE
,
3813 build_selector (METHOD_SEL_NAME (entries
)),
3816 /* Generate the method encoding if we don't have one already. */
3817 if (! METHOD_ENCODING (entries
))
3818 METHOD_ENCODING (entries
) =
3819 encode_method_def (METHOD_DEFINITION (entries
));
3821 elemlist
= tree_cons (NULL_TREE
,
3822 add_objc_string (METHOD_ENCODING (entries
),
3826 elemlist
= tree_cons (NULL_TREE
,
3827 build_unary_op (ADDR_EXPR
,
3828 METHOD_DEFINITION (entries
), 1),
3831 initlist
= tree_cons (NULL_TREE
,
3832 build_constructor (type
, nreverse (elemlist
)),
3835 entries
= TREE_CHAIN (entries
);
3839 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3842 /* To accomplish method prototyping without generating all kinds of
3843 inane warnings, the definition of the dispatch table entries were
3846 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3848 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3851 build_method_template ()
3854 tree decl_specs
, field_decl
, field_decl_chain
;
3856 _SLT_record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD
));
3858 /* struct objc_selector *_cmd; */
3859 decl_specs
= tree_cons (NULL_TREE
,
3860 xref_tag (RECORD_TYPE
,
3861 get_identifier (TAG_SELECTOR
)),
3863 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
3865 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3866 decl_specs
, NULL_TREE
);
3867 field_decl_chain
= field_decl
;
3869 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
3870 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
,
3871 get_identifier ("method_types"));
3872 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3873 decl_specs
, NULL_TREE
);
3874 chainon (field_decl_chain
, field_decl
);
3878 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_VOID
], NULL_TREE
);
3879 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_imp"));
3880 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3881 decl_specs
, NULL_TREE
);
3882 chainon (field_decl_chain
, field_decl
);
3884 finish_struct (_SLT_record
, field_decl_chain
, NULL_TREE
);
3891 generate_dispatch_table (type
, name
, size
, list
)
3897 tree sc_spec
, decl_specs
, decl
, initlist
;
3899 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3900 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
3902 decl
= start_decl (synth_id_with_class_suffix (name
, objc_implementation_context
),
3903 decl_specs
, 1, NULL_TREE
);
3905 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
3906 initlist
= tree_cons (NULL_TREE
, build_int_2 (size
, 0), initlist
);
3907 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3910 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3917 generate_dispatch_tables ()
3919 tree initlist
, chain
, method_list_template
;
3920 tree cast
, variable_length_type
;
3923 if (!objc_method_template
)
3924 objc_method_template
= build_method_template ();
3928 (build_tree_list (NULL_TREE
,
3929 xref_tag (RECORD_TYPE
,
3930 get_identifier (UTAG_METHOD_LIST
))),
3933 variable_length_type
= groktypename (cast
);
3935 chain
= CLASS_CLS_METHODS (objc_implementation_context
);
3938 size
= list_length (chain
);
3940 method_list_template
3941 = build_method_list_template (objc_method_template
, size
);
3943 = build_dispatch_table_initializer (objc_method_template
, chain
);
3945 UOBJC_CLASS_METHODS_decl
3946 = generate_dispatch_table (method_list_template
,
3947 ((TREE_CODE (objc_implementation_context
)
3948 == CLASS_IMPLEMENTATION_TYPE
)
3949 ? "_OBJC_CLASS_METHODS"
3950 : "_OBJC_CATEGORY_CLASS_METHODS"),
3952 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
3955 UOBJC_CLASS_METHODS_decl
= 0;
3957 chain
= CLASS_NST_METHODS (objc_implementation_context
);
3960 size
= list_length (chain
);
3962 method_list_template
3963 = build_method_list_template (objc_method_template
, size
);
3965 = build_dispatch_table_initializer (objc_method_template
, chain
);
3967 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
3968 UOBJC_INSTANCE_METHODS_decl
3969 = generate_dispatch_table (method_list_template
,
3970 "_OBJC_INSTANCE_METHODS",
3973 /* We have a category. */
3974 UOBJC_INSTANCE_METHODS_decl
3975 = generate_dispatch_table (method_list_template
,
3976 "_OBJC_CATEGORY_INSTANCE_METHODS",
3978 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
3981 UOBJC_INSTANCE_METHODS_decl
= 0;
3985 generate_protocol_list (i_or_p
)
3988 tree initlist
, decl_specs
, sc_spec
;
3989 tree refs_decl
, expr_decl
, lproto
, e
, plist
;
3993 if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
3994 || TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
3995 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
3996 else if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
3997 plist
= PROTOCOL_LIST (i_or_p
);
4001 cast_type
= groktypename
4003 (build_tree_list (NULL_TREE
,
4004 xref_tag (RECORD_TYPE
,
4005 get_identifier (UTAG_PROTOCOL
))),
4006 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
4009 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4010 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
4011 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
4014 /* Build initializer. */
4015 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), NULL_TREE
);
4017 e
= build_int_2 (size
, 0);
4018 TREE_TYPE (e
) = cast_type
;
4019 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4021 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4023 tree pval
= TREE_VALUE (lproto
);
4025 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
4026 && PROTOCOL_FORWARD_DECL (pval
))
4028 e
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (pval
), 0);
4029 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4033 /* static struct objc_protocol *refs[n]; */
4035 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4036 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
4037 get_identifier (UTAG_PROTOCOL
)),
4040 if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4041 expr_decl
= build_nt (ARRAY_REF
,
4042 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4044 build_int_2 (size
+ 2, 0));
4045 else if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
)
4046 expr_decl
= build_nt (ARRAY_REF
,
4047 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4049 build_int_2 (size
+ 2, 0));
4050 else if (TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4052 = build_nt (ARRAY_REF
,
4053 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4055 build_int_2 (size
+ 2, 0));
4059 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
4061 refs_decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
4062 DECL_CONTEXT (refs_decl
) = NULL_TREE
;
4064 finish_decl (refs_decl
, build_constructor (TREE_TYPE (refs_decl
),
4065 nreverse (initlist
)),
4072 build_category_initializer (type
, cat_name
, class_name
,
4073 instance_methods
, class_methods
, protocol_list
)
4077 tree instance_methods
;
4081 tree initlist
= NULL_TREE
, expr
;
4083 initlist
= tree_cons (NULL_TREE
, cat_name
, initlist
);
4084 initlist
= tree_cons (NULL_TREE
, class_name
, initlist
);
4086 if (!instance_methods
)
4087 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4090 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
4091 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4094 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4097 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
4098 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4101 /* protocol_list = */
4103 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4106 tree cast_type2
= groktypename
4108 (build_tree_list (NULL_TREE
,
4109 xref_tag (RECORD_TYPE
,
4110 get_identifier (UTAG_PROTOCOL
))),
4111 build1 (INDIRECT_REF
, NULL_TREE
,
4112 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4114 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4115 TREE_TYPE (expr
) = cast_type2
;
4116 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4119 return build_constructor (type
, nreverse (initlist
));
4122 /* struct objc_class {
4123 struct objc_class *isa;
4124 struct objc_class *super_class;
4129 struct objc_ivar_list *ivars;
4130 struct objc_method_list *methods;
4131 if (flag_next_runtime)
4132 struct objc_cache *cache;
4134 struct sarray *dtable;
4135 struct objc_class *subclass_list;
4136 struct objc_class *sibling_class;
4138 struct objc_protocol_list *protocols;
4139 void *gc_object_type;
4143 build_shared_structure_initializer (type
, isa
, super
, name
, size
, status
,
4144 dispatch_table
, ivar_list
, protocol_list
)
4151 tree dispatch_table
;
4155 tree initlist
= NULL_TREE
, expr
;
4158 initlist
= tree_cons (NULL_TREE
, isa
, initlist
);
4161 initlist
= tree_cons (NULL_TREE
, super
, initlist
);
4164 initlist
= tree_cons (NULL_TREE
, default_conversion (name
), initlist
);
4167 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4170 initlist
= tree_cons (NULL_TREE
, build_int_2 (status
, 0), initlist
);
4172 /* instance_size = */
4173 initlist
= tree_cons (NULL_TREE
, size
, initlist
);
4175 /* objc_ivar_list = */
4177 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4180 expr
= build_unary_op (ADDR_EXPR
, ivar_list
, 0);
4181 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4184 /* objc_method_list = */
4185 if (!dispatch_table
)
4186 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4189 expr
= build_unary_op (ADDR_EXPR
, dispatch_table
, 0);
4190 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4193 if (flag_next_runtime
)
4194 /* method_cache = */
4195 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4199 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4201 /* subclass_list = */
4202 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4204 /* sibling_class = */
4205 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4208 /* protocol_list = */
4209 if (! protocol_list
)
4210 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4216 (build_tree_list (NULL_TREE
,
4217 xref_tag (RECORD_TYPE
,
4218 get_identifier (UTAG_PROTOCOL
))),
4219 build1 (INDIRECT_REF
, NULL_TREE
,
4220 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4222 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4223 TREE_TYPE (expr
) = cast_type2
;
4224 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4227 /* gc_object_type = NULL */
4228 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4230 return build_constructor (type
, nreverse (initlist
));
4233 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4236 generate_category (cat
)
4239 tree sc_spec
, decl_specs
, decl
;
4240 tree initlist
, cat_name_expr
, class_name_expr
;
4241 tree protocol_decl
, category
;
4243 add_class_reference (CLASS_NAME (cat
));
4244 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
4246 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
4248 category
= CLASS_CATEGORY_LIST (implementation_template
);
4250 /* find the category interface from the class it is associated with */
4253 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
4255 category
= CLASS_CATEGORY_LIST (category
);
4258 if (category
&& CLASS_PROTOCOL_LIST (category
))
4260 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
4261 protocol_decl
= generate_protocol_list (category
);
4266 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4267 decl_specs
= tree_cons (NULL_TREE
, objc_category_template
, sc_spec
);
4269 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4270 objc_implementation_context
),
4271 decl_specs
, 1, NULL_TREE
);
4273 initlist
= build_category_initializer (TREE_TYPE (decl
),
4274 cat_name_expr
, class_name_expr
,
4275 UOBJC_INSTANCE_METHODS_decl
,
4276 UOBJC_CLASS_METHODS_decl
,
4279 TREE_USED (decl
) = 1;
4280 finish_decl (decl
, initlist
, NULL_TREE
);
4283 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4284 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4287 generate_shared_structures ()
4289 tree sc_spec
, decl_specs
, decl
;
4290 tree name_expr
, super_expr
, root_expr
;
4291 tree my_root_id
= NULL_TREE
, my_super_id
= NULL_TREE
;
4292 tree cast_type
, initlist
, protocol_decl
;
4294 my_super_id
= CLASS_SUPER_NAME (implementation_template
);
4297 add_class_reference (my_super_id
);
4299 /* Compute "my_root_id" - this is required for code generation.
4300 the "isa" for all meta class structures points to the root of
4301 the inheritance hierarchy (e.g. "__Object")... */
4302 my_root_id
= my_super_id
;
4305 tree my_root_int
= lookup_interface (my_root_id
);
4307 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
4308 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
4315 /* No super class. */
4316 my_root_id
= CLASS_NAME (implementation_template
);
4319 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
4320 objc_class_template
),
4321 build1 (INDIRECT_REF
,
4322 NULL_TREE
, NULL_TREE
)));
4324 name_expr
= add_objc_string (CLASS_NAME (implementation_template
),
4327 /* Install class `isa' and `super' pointers at runtime. */
4330 super_expr
= add_objc_string (my_super_id
, class_names
);
4331 super_expr
= build_c_cast (cast_type
, super_expr
); /* cast! */
4334 super_expr
= build_int_2 (0, 0);
4336 root_expr
= add_objc_string (my_root_id
, class_names
);
4337 root_expr
= build_c_cast (cast_type
, root_expr
); /* cast! */
4339 if (CLASS_PROTOCOL_LIST (implementation_template
))
4341 generate_protocol_references
4342 (CLASS_PROTOCOL_LIST (implementation_template
));
4343 protocol_decl
= generate_protocol_list (implementation_template
);
4348 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4350 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
4351 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
4353 decl
= start_decl (DECL_NAME (UOBJC_METACLASS_decl
), decl_specs
, 1,
4357 = build_shared_structure_initializer
4359 root_expr
, super_expr
, name_expr
,
4360 convert (integer_type_node
, TYPE_SIZE_UNIT (objc_class_template
)),
4362 UOBJC_CLASS_METHODS_decl
,
4363 UOBJC_CLASS_VARIABLES_decl
,
4366 finish_decl (decl
, initlist
, NULL_TREE
);
4368 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4370 decl
= start_decl (DECL_NAME (UOBJC_CLASS_decl
), decl_specs
, 1,
4374 = build_shared_structure_initializer
4376 build_unary_op (ADDR_EXPR
, UOBJC_METACLASS_decl
, 0),
4377 super_expr
, name_expr
,
4378 convert (integer_type_node
,
4379 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4380 (implementation_template
))),
4382 UOBJC_INSTANCE_METHODS_decl
,
4383 UOBJC_INSTANCE_VARIABLES_decl
,
4386 finish_decl (decl
, initlist
, NULL_TREE
);
4390 synth_id_with_class_suffix (preamble
, ctxt
)
4391 const char *preamble
;
4395 if (TREE_CODE (ctxt
) == CLASS_IMPLEMENTATION_TYPE
4396 || TREE_CODE (ctxt
) == CLASS_INTERFACE_TYPE
)
4398 const char *const class_name
4399 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
4400 string
= (char *) alloca (strlen (preamble
) + strlen (class_name
) + 3);
4401 sprintf (string
, "%s_%s", preamble
,
4402 IDENTIFIER_POINTER (CLASS_NAME (ctxt
)));
4404 else if (TREE_CODE (ctxt
) == CATEGORY_IMPLEMENTATION_TYPE
4405 || TREE_CODE (ctxt
) == CATEGORY_INTERFACE_TYPE
)
4407 /* We have a category. */
4408 const char *const class_name
4409 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
4410 const char *const class_super_name
4411 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
));
4412 string
= (char *) alloca (strlen (preamble
)
4413 + strlen (class_name
)
4414 + strlen (class_super_name
)
4416 sprintf (string
, "%s_%s_%s", preamble
, class_name
, class_super_name
);
4418 else if (TREE_CODE (ctxt
) == PROTOCOL_INTERFACE_TYPE
)
4420 const char *protocol_name
= IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt
));
4422 = (char *) alloca (strlen (preamble
) + strlen (protocol_name
) + 3);
4423 sprintf (string
, "%s_%s", preamble
, protocol_name
);
4428 return get_identifier (string
);
4432 is_objc_type_qualifier (node
)
4435 return (TREE_CODE (node
) == IDENTIFIER_NODE
4436 && (node
== ridpointers
[(int) RID_CONST
]
4437 || node
== ridpointers
[(int) RID_VOLATILE
]
4438 || node
== ridpointers
[(int) RID_IN
]
4439 || node
== ridpointers
[(int) RID_OUT
]
4440 || node
== ridpointers
[(int) RID_INOUT
]
4441 || node
== ridpointers
[(int) RID_BYCOPY
]
4442 || node
== ridpointers
[(int) RID_BYREF
]
4443 || node
== ridpointers
[(int) RID_ONEWAY
]));
4446 /* If type is empty or only type qualifiers are present, add default
4447 type of id (otherwise grokdeclarator will default to int). */
4450 adjust_type_for_id_default (type
)
4453 tree declspecs
, chain
;
4456 return build_tree_list (build_tree_list (NULL_TREE
, objc_object_reference
),
4457 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4459 declspecs
= TREE_PURPOSE (type
);
4461 /* Determine if a typespec is present. */
4462 for (chain
= declspecs
;
4464 chain
= TREE_CHAIN (chain
))
4466 if (!is_objc_type_qualifier (TREE_VALUE (chain
)))
4470 return build_tree_list (tree_cons (NULL_TREE
, objc_object_reference
,
4472 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4477 selector ':' '(' typename ')' identifier
4480 Transform an Objective-C keyword argument into
4481 the C equivalent parameter declarator.
4483 In: key_name, an "identifier_node" (optional).
4484 arg_type, a "tree_list" (optional).
4485 arg_name, an "identifier_node".
4487 Note: It would be really nice to strongly type the preceding
4488 arguments in the function prototype; however, then I
4489 could not use the "accessor" macros defined in "tree.h".
4491 Out: an instance of "keyword_decl". */
4494 build_keyword_decl (key_name
, arg_type
, arg_name
)
4501 /* If no type is specified, default to "id". */
4502 arg_type
= adjust_type_for_id_default (arg_type
);
4504 keyword_decl
= make_node (KEYWORD_DECL
);
4506 TREE_TYPE (keyword_decl
) = arg_type
;
4507 KEYWORD_ARG_NAME (keyword_decl
) = arg_name
;
4508 KEYWORD_KEY_NAME (keyword_decl
) = key_name
;
4510 return keyword_decl
;
4513 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4516 build_keyword_selector (selector
)
4520 tree key_chain
, key_name
;
4523 /* Scan the selector to see how much space we'll need. */
4524 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4526 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4527 key_name
= KEYWORD_KEY_NAME (key_chain
);
4528 else if (TREE_CODE (selector
) == TREE_LIST
)
4529 key_name
= TREE_PURPOSE (key_chain
);
4534 len
+= IDENTIFIER_LENGTH (key_name
) + 1;
4536 /* Just a ':' arg. */
4540 buf
= (char *) alloca (len
+ 1);
4541 /* Start the buffer out as an empty string. */
4544 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4546 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4547 key_name
= KEYWORD_KEY_NAME (key_chain
);
4548 else if (TREE_CODE (selector
) == TREE_LIST
)
4549 key_name
= TREE_PURPOSE (key_chain
);
4554 strcat (buf
, IDENTIFIER_POINTER (key_name
));
4558 return get_identifier (buf
);
4561 /* Used for declarations and definitions. */
4564 build_method_decl (code
, ret_type
, selector
, add_args
)
4565 enum tree_code code
;
4572 /* If no type is specified, default to "id". */
4573 ret_type
= adjust_type_for_id_default (ret_type
);
4575 method_decl
= make_node (code
);
4576 TREE_TYPE (method_decl
) = ret_type
;
4578 /* If we have a keyword selector, create an identifier_node that
4579 represents the full selector name (`:' included)... */
4580 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4582 METHOD_SEL_NAME (method_decl
) = build_keyword_selector (selector
);
4583 METHOD_SEL_ARGS (method_decl
) = selector
;
4584 METHOD_ADD_ARGS (method_decl
) = add_args
;
4588 METHOD_SEL_NAME (method_decl
) = selector
;
4589 METHOD_SEL_ARGS (method_decl
) = NULL_TREE
;
4590 METHOD_ADD_ARGS (method_decl
) = NULL_TREE
;
4596 #define METHOD_DEF 0
4597 #define METHOD_REF 1
4599 /* Used by `build_objc_method_call' and `comp_method_types'. Return
4600 an argument list for method METH. CONTEXT is either METHOD_DEF or
4601 METHOD_REF, saying whether we are trying to define a method or call
4602 one. SUPERFLAG says this is for a send to super; this makes a
4603 difference for the NeXT calling sequence in which the lookup and
4604 the method call are done together. */
4607 get_arg_type_list (meth
, context
, superflag
)
4614 /* Receiver type. */
4615 if (flag_next_runtime
&& superflag
)
4616 arglist
= build_tree_list (NULL_TREE
, super_type
);
4617 else if (context
== METHOD_DEF
)
4618 arglist
= build_tree_list (NULL_TREE
, TREE_TYPE (self_decl
));
4620 arglist
= build_tree_list (NULL_TREE
, id_type
);
4622 /* Selector type - will eventually change to `int'. */
4623 chainon (arglist
, build_tree_list (NULL_TREE
, selector_type
));
4625 /* Build a list of argument types. */
4626 for (akey
= METHOD_SEL_ARGS (meth
); akey
; akey
= TREE_CHAIN (akey
))
4628 tree arg_decl
= groktypename_in_parm_context (TREE_TYPE (akey
));
4629 chainon (arglist
, build_tree_list (NULL_TREE
, TREE_TYPE (arg_decl
)));
4632 if (METHOD_ADD_ARGS (meth
) == objc_ellipsis_node
)
4633 /* We have a `, ...' immediately following the selector,
4634 finalize the arglist...simulate get_parm_info (0). */
4636 else if (METHOD_ADD_ARGS (meth
))
4638 /* we have a variable length selector */
4639 tree add_arg_list
= TREE_CHAIN (METHOD_ADD_ARGS (meth
));
4640 chainon (arglist
, add_arg_list
);
4643 /* finalize the arglist...simulate get_parm_info (1) */
4644 chainon (arglist
, build_tree_list (NULL_TREE
, void_type_node
));
4650 check_duplicates (hsh
)
4653 tree meth
= NULL_TREE
;
4661 /* We have two methods with the same name and different types. */
4663 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
) ? '-' : '+';
4665 warning ("multiple declarations for method `%s'",
4666 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
4668 warn_with_method ("using", type
, meth
);
4669 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
4670 warn_with_method ("also found", type
, loop
->value
);
4676 /* If RECEIVER is a class reference, return the identifier node for
4677 the referenced class. RECEIVER is created by get_class_reference,
4678 so we check the exact form created depending on which runtimes are
4682 receiver_is_class_object (receiver
)
4685 tree chain
, exp
, arg
;
4687 /* The receiver is 'self' in the context of a class method. */
4688 if (objc_method_context
4689 && receiver
== self_decl
4690 && TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
4692 return CLASS_NAME (objc_implementation_context
);
4695 if (flag_next_runtime
)
4697 /* The receiver is a variable created by
4698 build_class_reference_decl. */
4699 if (TREE_CODE (receiver
) == VAR_DECL
4700 && TREE_TYPE (receiver
) == objc_class_type
)
4701 /* Look up the identifier. */
4702 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
4703 if (TREE_PURPOSE (chain
) == receiver
)
4704 return TREE_VALUE (chain
);
4708 /* The receiver is a function call that returns an id. Check if
4709 it is a call to objc_getClass, if so, pick up the class name. */
4710 if (TREE_CODE (receiver
) == CALL_EXPR
4711 && (exp
= TREE_OPERAND (receiver
, 0))
4712 && TREE_CODE (exp
) == ADDR_EXPR
4713 && (exp
= TREE_OPERAND (exp
, 0))
4714 && TREE_CODE (exp
) == FUNCTION_DECL
4715 && exp
== objc_get_class_decl
4716 /* We have a call to objc_getClass! */
4717 && (arg
= TREE_OPERAND (receiver
, 1))
4718 && TREE_CODE (arg
) == TREE_LIST
4719 && (arg
= TREE_VALUE (arg
)))
4722 if (TREE_CODE (arg
) == ADDR_EXPR
4723 && (arg
= TREE_OPERAND (arg
, 0))
4724 && TREE_CODE (arg
) == STRING_CST
)
4725 /* Finally, we have the class name. */
4726 return get_identifier (TREE_STRING_POINTER (arg
));
4732 /* If we are currently building a message expr, this holds
4733 the identifier of the selector of the message. This is
4734 used when printing warnings about argument mismatches. */
4736 static tree building_objc_message_expr
= 0;
4739 maybe_building_objc_message_expr ()
4741 return building_objc_message_expr
;
4744 /* Construct an expression for sending a message.
4745 MESS has the object to send to in TREE_PURPOSE
4746 and the argument list (including selector) in TREE_VALUE.
4748 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4749 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4752 build_message_expr (mess
)
4755 tree receiver
= TREE_PURPOSE (mess
);
4757 tree args
= TREE_VALUE (mess
);
4758 tree method_params
= NULL_TREE
;
4760 if (TREE_CODE (receiver
) == ERROR_MARK
)
4761 return error_mark_node
;
4763 /* Obtain the full selector name. */
4764 if (TREE_CODE (args
) == IDENTIFIER_NODE
)
4765 /* A unary selector. */
4767 else if (TREE_CODE (args
) == TREE_LIST
)
4768 sel_name
= build_keyword_selector (args
);
4772 /* Build the parameter list to give to the method. */
4773 if (TREE_CODE (args
) == TREE_LIST
)
4775 tree chain
= args
, prev
= NULL_TREE
;
4777 /* We have a keyword selector--check for comma expressions. */
4780 tree element
= TREE_VALUE (chain
);
4782 /* We have a comma expression, must collapse... */
4783 if (TREE_CODE (element
) == TREE_LIST
)
4786 TREE_CHAIN (prev
) = element
;
4791 chain
= TREE_CHAIN (chain
);
4793 method_params
= args
;
4796 return finish_message_expr (receiver
, sel_name
, method_params
);
4799 /* The 'finish_message_expr' routine is called from within
4800 'build_message_expr' for non-template functions. In the case of
4801 C++ template functions, it is called from 'build_expr_from_tree'
4802 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
4805 finish_message_expr (receiver
, sel_name
, method_params
)
4806 tree receiver
, sel_name
, method_params
;
4808 tree method_prototype
= NULL_TREE
, class_ident
= NULL_TREE
;
4809 tree selector
, self_object
, retval
;
4810 int statically_typed
= 0, statically_allocated
= 0;
4812 /* Determine receiver type. */
4813 tree rtype
= TREE_TYPE (receiver
);
4814 int super
= IS_SUPER (rtype
);
4818 if (TREE_STATIC_TEMPLATE (rtype
))
4819 statically_allocated
= 1;
4820 else if (TREE_CODE (rtype
) == POINTER_TYPE
4821 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype
)))
4822 statically_typed
= 1;
4823 else if ((flag_next_runtime
4825 && (class_ident
= receiver_is_class_object (receiver
)))
4827 else if (! IS_ID (rtype
)
4828 /* Allow any type that matches objc_class_type. */
4829 && ! comptypes (rtype
, objc_class_type
))
4831 warning ("invalid receiver type `%s'",
4832 gen_declaration (rtype
, errbuf
));
4834 if (statically_allocated
)
4835 receiver
= build_unary_op (ADDR_EXPR
, receiver
, 0);
4837 /* Don't evaluate the receiver twice. */
4838 receiver
= save_expr (receiver
);
4839 self_object
= receiver
;
4842 /* If sending to `super', use current self as the object. */
4843 self_object
= self_decl
;
4845 /* Determine operation return type. */
4851 if (CLASS_SUPER_NAME (implementation_template
))
4854 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
4856 if (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
)
4857 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4859 method_prototype
= lookup_class_method_static (iface
, sel_name
);
4861 if (iface
&& !method_prototype
)
4862 warning ("`%s' does not respond to `%s'",
4863 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template
)),
4864 IDENTIFIER_POINTER (sel_name
));
4868 error ("no super class declared in interface for `%s'",
4869 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
4870 return error_mark_node
;
4874 else if (statically_allocated
)
4876 tree ctype
= TREE_TYPE (rtype
);
4877 tree iface
= lookup_interface (TYPE_NAME (rtype
));
4880 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4882 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
4884 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
4887 if (!method_prototype
)
4888 warning ("`%s' does not respond to `%s'",
4889 IDENTIFIER_POINTER (TYPE_NAME (rtype
)),
4890 IDENTIFIER_POINTER (sel_name
));
4892 else if (statically_typed
)
4894 tree ctype
= TREE_TYPE (rtype
);
4896 /* `self' is now statically_typed. All methods should be visible
4897 within the context of the implementation. */
4898 if (objc_implementation_context
4899 && CLASS_NAME (objc_implementation_context
) == TYPE_NAME (ctype
))
4902 = lookup_instance_method_static (implementation_template
,
4905 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
4907 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
4910 if (! method_prototype
4911 && implementation_template
!= objc_implementation_context
)
4912 /* The method is not published in the interface. Check
4915 = lookup_method (CLASS_NST_METHODS (objc_implementation_context
),
4922 if ((iface
= lookup_interface (TYPE_NAME (ctype
))))
4923 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4925 if (! method_prototype
)
4927 tree protocol_list
= TYPE_PROTOCOL_LIST (ctype
);
4930 = lookup_method_in_protocol_list (protocol_list
,
4935 if (!method_prototype
)
4936 warning ("`%s' does not respond to `%s'",
4937 IDENTIFIER_POINTER (TYPE_NAME (ctype
)),
4938 IDENTIFIER_POINTER (sel_name
));
4940 else if (class_ident
)
4942 if (objc_implementation_context
4943 && CLASS_NAME (objc_implementation_context
) == class_ident
)
4946 = lookup_class_method_static (implementation_template
, sel_name
);
4948 if (!method_prototype
4949 && implementation_template
!= objc_implementation_context
)
4950 /* The method is not published in the interface. Check
4953 = lookup_method (CLASS_CLS_METHODS (objc_implementation_context
),
4960 if ((iface
= lookup_interface (class_ident
)))
4961 method_prototype
= lookup_class_method_static (iface
, sel_name
);
4964 if (!method_prototype
)
4966 warning ("cannot find class (factory) method");
4967 warning ("return type for `%s' defaults to id",
4968 IDENTIFIER_POINTER (sel_name
));
4971 else if (IS_PROTOCOL_QUALIFIED_ID (rtype
))
4973 /* An anonymous object that has been qualified with a protocol. */
4975 tree protocol_list
= TYPE_PROTOCOL_LIST (rtype
);
4977 method_prototype
= lookup_method_in_protocol_list (protocol_list
,
4980 if (!method_prototype
)
4984 warning ("method `%s' not implemented by protocol",
4985 IDENTIFIER_POINTER (sel_name
));
4987 /* Try and find the method signature in the global pools. */
4989 if (!(hsh
= hash_lookup (nst_method_hash_list
, sel_name
)))
4990 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
4992 if (!(method_prototype
= check_duplicates (hsh
)))
4993 warning ("return type defaults to id");
5000 /* We think we have an instance...loophole: extern id Object; */
5001 hsh
= hash_lookup (nst_method_hash_list
, sel_name
);
5004 /* For various loopholes */
5005 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5007 method_prototype
= check_duplicates (hsh
);
5008 if (!method_prototype
)
5010 warning ("cannot find method");
5011 warning ("return type for `%s' defaults to id",
5012 IDENTIFIER_POINTER (sel_name
));
5016 /* Save the selector name for printing error messages. */
5017 building_objc_message_expr
= sel_name
;
5019 /* Build the parameters list for looking up the method.
5020 These are the object itself and the selector. */
5022 if (flag_typed_selectors
)
5023 selector
= build_typed_selector_reference (sel_name
, method_prototype
);
5025 selector
= build_selector_reference (sel_name
);
5027 retval
= build_objc_method_call (super
, method_prototype
,
5028 receiver
, self_object
,
5029 selector
, method_params
);
5031 building_objc_message_expr
= 0;
5036 /* Build a tree expression to send OBJECT the operation SELECTOR,
5037 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5038 assuming the method has prototype METHOD_PROTOTYPE.
5039 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5040 Use METHOD_PARAMS as list of args to pass to the method.
5041 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5044 build_objc_method_call (super_flag
, method_prototype
, lookup_object
, object
,
5045 selector
, method_params
)
5047 tree method_prototype
, lookup_object
, object
, selector
, method_params
;
5049 tree sender
= (super_flag
? umsg_super_decl
: umsg_decl
);
5050 tree rcv_p
= (super_flag
5051 ? build_pointer_type (xref_tag (RECORD_TYPE
,
5052 get_identifier (TAG_SUPER
)))
5055 if (flag_next_runtime
)
5057 if (! method_prototype
)
5059 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5060 tree_cons (NULL_TREE
, selector
,
5062 assemble_external (sender
);
5063 return build_function_call (sender
, method_params
);
5067 /* This is a real kludge, but it is used only for the Next.
5068 Clobber the data type of SENDER temporarily to accept
5069 all the arguments for this operation, and to return
5070 whatever this operation returns. */
5071 tree arglist
= NULL_TREE
, retval
, savarg
, savret
;
5072 tree ret_type
= groktypename (TREE_TYPE (method_prototype
));
5074 /* Save the proper contents of SENDER's data type. */
5075 savarg
= TYPE_ARG_TYPES (TREE_TYPE (sender
));
5076 savret
= TREE_TYPE (TREE_TYPE (sender
));
5078 /* Install this method's argument types. */
5079 arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5081 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = arglist
;
5083 /* Install this method's return type. */
5084 TREE_TYPE (TREE_TYPE (sender
)) = ret_type
;
5086 /* Call SENDER with all the parameters. This will do type
5087 checking using the arg types for this method. */
5088 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5089 tree_cons (NULL_TREE
, selector
,
5091 assemble_external (sender
);
5092 retval
= build_function_call (sender
, method_params
);
5094 /* Restore SENDER's return/argument types. */
5095 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = savarg
;
5096 TREE_TYPE (TREE_TYPE (sender
)) = savret
;
5102 /* This is the portable way.
5103 First call the lookup function to get a pointer to the method,
5104 then cast the pointer, then call it with the method arguments. */
5107 /* Avoid trouble since we may evaluate each of these twice. */
5108 object
= save_expr (object
);
5109 selector
= save_expr (selector
);
5111 lookup_object
= build_c_cast (rcv_p
, lookup_object
);
5113 assemble_external (sender
);
5115 = build_function_call (sender
,
5116 tree_cons (NULL_TREE
, lookup_object
,
5117 tree_cons (NULL_TREE
, selector
,
5120 /* If we have a method prototype, construct the data type this
5121 method needs, and cast what we got from SENDER into a pointer
5123 if (method_prototype
)
5125 tree arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5127 tree valtype
= groktypename (TREE_TYPE (method_prototype
));
5128 tree fake_function_type
= build_function_type (valtype
, arglist
);
5129 TREE_TYPE (method
) = build_pointer_type (fake_function_type
);
5133 = build_pointer_type (build_function_type (ptr_type_node
, NULL_TREE
));
5135 /* Pass the object to the method. */
5136 assemble_external (method
);
5137 return build_function_call (method
,
5138 tree_cons (NULL_TREE
, object
,
5139 tree_cons (NULL_TREE
, selector
,
5145 build_protocol_reference (p
)
5148 tree decl
, ident
, ptype
;
5150 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5152 ident
= synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
);
5154 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
5155 objc_protocol_template
),
5158 if (IDENTIFIER_GLOBAL_VALUE (ident
))
5159 decl
= IDENTIFIER_GLOBAL_VALUE (ident
); /* Set by pushdecl. */
5162 decl
= build_decl (VAR_DECL
, ident
, ptype
);
5163 DECL_EXTERNAL (decl
) = 1;
5164 TREE_PUBLIC (decl
) = 1;
5165 TREE_USED (decl
) = 1;
5166 DECL_ARTIFICIAL (decl
) = 1;
5168 make_decl_rtl (decl
, 0);
5169 pushdecl_top_level (decl
);
5172 PROTOCOL_FORWARD_DECL (p
) = decl
;
5176 build_protocol_expr (protoname
)
5180 tree p
= lookup_protocol (protoname
);
5184 error ("cannot find protocol declaration for `%s'",
5185 IDENTIFIER_POINTER (protoname
));
5186 return error_mark_node
;
5189 if (!PROTOCOL_FORWARD_DECL (p
))
5190 build_protocol_reference (p
);
5192 expr
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
5194 TREE_TYPE (expr
) = protocol_type
;
5200 build_selector_expr (selnamelist
)
5205 /* Obtain the full selector name. */
5206 if (TREE_CODE (selnamelist
) == IDENTIFIER_NODE
)
5207 /* A unary selector. */
5208 selname
= selnamelist
;
5209 else if (TREE_CODE (selnamelist
) == TREE_LIST
)
5210 selname
= build_keyword_selector (selnamelist
);
5214 if (flag_typed_selectors
)
5215 return build_typed_selector_reference (selname
, 0);
5217 return build_selector_reference (selname
);
5221 build_encode_expr (type
)
5227 encode_type (type
, obstack_object_size (&util_obstack
),
5228 OBJC_ENCODE_INLINE_DEFS
);
5229 obstack_1grow (&util_obstack
, 0); /* null terminate string */
5230 string
= obstack_finish (&util_obstack
);
5232 /* Synthesize a string that represents the encoded struct/union. */
5233 result
= my_build_string (strlen (string
) + 1, string
);
5234 obstack_free (&util_obstack
, util_firstobj
);
5239 build_ivar_reference (id
)
5242 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
5244 /* Historically, a class method that produced objects (factory
5245 method) would assign `self' to the instance that it
5246 allocated. This would effectively turn the class method into
5247 an instance method. Following this assignment, the instance
5248 variables could be accessed. That practice, while safe,
5249 violates the simple rule that a class method should not refer
5250 to an instance variable. It's better to catch the cases
5251 where this is done unknowingly than to support the above
5253 warning ("instance variable `%s' accessed in class method",
5254 IDENTIFIER_POINTER (id
));
5255 TREE_TYPE (self_decl
) = instance_type
; /* cast */
5258 return build_component_ref (build_indirect_ref (self_decl
, "->"), id
);
5261 /* Compute a hash value for a given method SEL_NAME. */
5264 hash_func (sel_name
)
5267 const unsigned char *s
5268 = (const unsigned char *)IDENTIFIER_POINTER (sel_name
);
5272 h
= h
* 67 + *s
++ - 113;
5279 nst_method_hash_list
= (hash
*) ggc_calloc (SIZEHASHTABLE
, sizeof (hash
));
5280 cls_method_hash_list
= (hash
*) ggc_calloc (SIZEHASHTABLE
, sizeof (hash
));
5283 /* WARNING!!!! hash_enter is called with a method, and will peek
5284 inside to find its selector! But hash_lookup is given a selector
5285 directly, and looks for the selector that's inside the found
5286 entry's key (method) for comparison. */
5289 hash_enter (hashlist
, method
)
5294 int slot
= hash_func (METHOD_SEL_NAME (method
)) % SIZEHASHTABLE
;
5296 obj
= (hash
) ggc_alloc (sizeof (struct hashed_entry
));
5298 obj
->next
= hashlist
[slot
];
5301 hashlist
[slot
] = obj
; /* append to front */
5305 hash_lookup (hashlist
, sel_name
)
5311 target
= hashlist
[hash_func (sel_name
) % SIZEHASHTABLE
];
5315 if (sel_name
== METHOD_SEL_NAME (target
->key
))
5318 target
= target
->next
;
5324 hash_add_attr (entry
, value
)
5330 obj
= (attr
) ggc_alloc (sizeof (struct hashed_attribute
));
5331 obj
->next
= entry
->list
;
5334 entry
->list
= obj
; /* append to front */
5338 lookup_method (mchain
, method
)
5344 if (TREE_CODE (method
) == IDENTIFIER_NODE
)
5347 key
= METHOD_SEL_NAME (method
);
5351 if (METHOD_SEL_NAME (mchain
) == key
)
5353 mchain
= TREE_CHAIN (mchain
);
5359 lookup_instance_method_static (interface
, ident
)
5363 tree inter
= interface
;
5364 tree chain
= CLASS_NST_METHODS (inter
);
5365 tree meth
= NULL_TREE
;
5369 if ((meth
= lookup_method (chain
, ident
)))
5372 if (CLASS_CATEGORY_LIST (inter
))
5374 tree category
= CLASS_CATEGORY_LIST (inter
);
5375 chain
= CLASS_NST_METHODS (category
);
5379 if ((meth
= lookup_method (chain
, ident
)))
5382 /* Check for instance methods in protocols in categories. */
5383 if (CLASS_PROTOCOL_LIST (category
))
5385 if ((meth
= (lookup_method_in_protocol_list
5386 (CLASS_PROTOCOL_LIST (category
), ident
, 0))))
5390 if ((category
= CLASS_CATEGORY_LIST (category
)))
5391 chain
= CLASS_NST_METHODS (category
);
5396 if (CLASS_PROTOCOL_LIST (inter
))
5398 if ((meth
= (lookup_method_in_protocol_list
5399 (CLASS_PROTOCOL_LIST (inter
), ident
, 0))))
5403 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5404 chain
= CLASS_NST_METHODS (inter
);
5412 lookup_class_method_static (interface
, ident
)
5416 tree inter
= interface
;
5417 tree chain
= CLASS_CLS_METHODS (inter
);
5418 tree meth
= NULL_TREE
;
5419 tree root_inter
= NULL_TREE
;
5423 if ((meth
= lookup_method (chain
, ident
)))
5426 if (CLASS_CATEGORY_LIST (inter
))
5428 tree category
= CLASS_CATEGORY_LIST (inter
);
5429 chain
= CLASS_CLS_METHODS (category
);
5433 if ((meth
= lookup_method (chain
, ident
)))
5436 /* Check for class methods in protocols in categories. */
5437 if (CLASS_PROTOCOL_LIST (category
))
5439 if ((meth
= (lookup_method_in_protocol_list
5440 (CLASS_PROTOCOL_LIST (category
), ident
, 1))))
5444 if ((category
= CLASS_CATEGORY_LIST (category
)))
5445 chain
= CLASS_CLS_METHODS (category
);
5450 /* Check for class methods in protocols. */
5451 if (CLASS_PROTOCOL_LIST (inter
))
5453 if ((meth
= (lookup_method_in_protocol_list
5454 (CLASS_PROTOCOL_LIST (inter
), ident
, 1))))
5459 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5460 chain
= CLASS_CLS_METHODS (inter
);
5464 /* If no class (factory) method was found, check if an _instance_
5465 method of the same name exists in the root class. This is what
5466 the Objective-C runtime will do. */
5467 return lookup_instance_method_static (root_inter
, ident
);
5471 add_class_method (class, method
)
5478 if (!(mth
= lookup_method (CLASS_CLS_METHODS (class), method
)))
5480 /* put method on list in reverse order */
5481 TREE_CHAIN (method
) = CLASS_CLS_METHODS (class);
5482 CLASS_CLS_METHODS (class) = method
;
5486 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5487 error ("duplicate definition of class method `%s'",
5488 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5491 /* Check types; if different, complain. */
5492 if (!comp_proto_with_proto (method
, mth
))
5493 error ("duplicate declaration of class method `%s'",
5494 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5498 if (!(hsh
= hash_lookup (cls_method_hash_list
, METHOD_SEL_NAME (method
))))
5500 /* Install on a global chain. */
5501 hash_enter (cls_method_hash_list
, method
);
5505 /* Check types; if different, add to a list. */
5506 if (!comp_proto_with_proto (method
, hsh
->key
))
5507 hash_add_attr (hsh
, method
);
5513 add_instance_method (class, method
)
5520 if (!(mth
= lookup_method (CLASS_NST_METHODS (class), method
)))
5522 /* Put method on list in reverse order. */
5523 TREE_CHAIN (method
) = CLASS_NST_METHODS (class);
5524 CLASS_NST_METHODS (class) = method
;
5528 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5529 error ("duplicate definition of instance method `%s'",
5530 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5533 /* Check types; if different, complain. */
5534 if (!comp_proto_with_proto (method
, mth
))
5535 error ("duplicate declaration of instance method `%s'",
5536 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5540 if (!(hsh
= hash_lookup (nst_method_hash_list
, METHOD_SEL_NAME (method
))))
5542 /* Install on a global chain. */
5543 hash_enter (nst_method_hash_list
, method
);
5547 /* Check types; if different, add to a list. */
5548 if (!comp_proto_with_proto (method
, hsh
->key
))
5549 hash_add_attr (hsh
, method
);
5558 /* Put interfaces on list in reverse order. */
5559 TREE_CHAIN (class) = interface_chain
;
5560 interface_chain
= class;
5561 return interface_chain
;
5565 add_category (class, category
)
5569 /* Put categories on list in reverse order. */
5570 tree cat
= CLASS_CATEGORY_LIST (class);
5574 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
5575 warning ("duplicate interface declaration for category `%s(%s)'",
5576 IDENTIFIER_POINTER (CLASS_NAME (class)),
5577 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category
)));
5578 cat
= CLASS_CATEGORY_LIST (cat
);
5581 CLASS_CATEGORY_LIST (category
) = CLASS_CATEGORY_LIST (class);
5582 CLASS_CATEGORY_LIST (class) = category
;
5585 /* Called after parsing each instance variable declaration. Necessary to
5586 preserve typedefs and implement public/private...
5588 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5591 add_instance_variable (class, public, declarator
, declspecs
, width
)
5598 tree field_decl
, raw_decl
;
5600 raw_decl
= build_tree_list (declspecs
, declarator
);
5602 if (CLASS_RAW_IVARS (class))
5603 chainon (CLASS_RAW_IVARS (class), raw_decl
);
5605 CLASS_RAW_IVARS (class) = raw_decl
;
5607 field_decl
= grokfield (input_filename
, lineno
,
5608 declarator
, declspecs
, width
);
5610 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5614 TREE_PUBLIC (field_decl
) = 0;
5615 TREE_PRIVATE (field_decl
) = 0;
5616 TREE_PROTECTED (field_decl
) = 1;
5620 TREE_PUBLIC (field_decl
) = 1;
5621 TREE_PRIVATE (field_decl
) = 0;
5622 TREE_PROTECTED (field_decl
) = 0;
5626 TREE_PUBLIC (field_decl
) = 0;
5627 TREE_PRIVATE (field_decl
) = 1;
5628 TREE_PROTECTED (field_decl
) = 0;
5633 if (CLASS_IVARS (class))
5634 chainon (CLASS_IVARS (class), field_decl
);
5636 CLASS_IVARS (class) = field_decl
;
5642 is_ivar (decl_chain
, ident
)
5646 for ( ; decl_chain
; decl_chain
= TREE_CHAIN (decl_chain
))
5647 if (DECL_NAME (decl_chain
) == ident
)
5652 /* True if the ivar is private and we are not in its implementation. */
5658 if (TREE_PRIVATE (decl
)
5659 && ! is_ivar (CLASS_IVARS (implementation_template
), DECL_NAME (decl
)))
5661 error ("instance variable `%s' is declared private",
5662 IDENTIFIER_POINTER (DECL_NAME (decl
)));
5669 /* We have an instance variable reference;, check to see if it is public. */
5672 is_public (expr
, identifier
)
5676 tree basetype
= TREE_TYPE (expr
);
5677 enum tree_code code
= TREE_CODE (basetype
);
5680 if (code
== RECORD_TYPE
)
5682 if (TREE_STATIC_TEMPLATE (basetype
))
5684 if (!lookup_interface (TYPE_NAME (basetype
)))
5686 error ("cannot find interface declaration for `%s'",
5687 IDENTIFIER_POINTER (TYPE_NAME (basetype
)));
5691 if ((decl
= is_ivar (TYPE_FIELDS (basetype
), identifier
)))
5693 if (TREE_PUBLIC (decl
))
5696 /* Important difference between the Stepstone translator:
5697 all instance variables should be public within the context
5698 of the implementation. */
5699 if (objc_implementation_context
5700 && (((TREE_CODE (objc_implementation_context
)
5701 == CLASS_IMPLEMENTATION_TYPE
)
5702 || (TREE_CODE (objc_implementation_context
)
5703 == CATEGORY_IMPLEMENTATION_TYPE
))
5704 && (CLASS_NAME (objc_implementation_context
)
5705 == TYPE_NAME (basetype
))))
5706 return ! is_private (decl
);
5708 error ("instance variable `%s' is declared %s",
5709 IDENTIFIER_POINTER (identifier
),
5710 TREE_PRIVATE (decl
) ? "private" : "protected");
5715 else if (objc_implementation_context
&& (basetype
== objc_object_reference
))
5717 TREE_TYPE (expr
) = uprivate_record
;
5718 warning ("static access to object of type `id'");
5725 /* Implement @defs (<classname>) within struct bodies. */
5728 get_class_ivars (interface
)
5731 /* Make sure we copy the leaf ivars in case @defs is used in a local
5732 context. Otherwise finish_struct will overwrite the layout info
5733 using temporary storage. */
5734 return build_ivar_chain (interface
, 1);
5737 /* Make sure all entries in CHAIN are also in LIST. */
5740 check_methods (chain
, list
, mtype
)
5749 if (!lookup_method (list
, chain
))
5753 if (TREE_CODE (objc_implementation_context
)
5754 == CLASS_IMPLEMENTATION_TYPE
)
5755 warning ("incomplete implementation of class `%s'",
5756 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
)));
5757 else if (TREE_CODE (objc_implementation_context
)
5758 == CATEGORY_IMPLEMENTATION_TYPE
)
5759 warning ("incomplete implementation of category `%s'",
5760 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
5764 warning ("method definition for `%c%s' not found",
5765 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
5768 chain
= TREE_CHAIN (chain
);
5774 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
5777 conforms_to_protocol (class, protocol
)
5781 if (TREE_CODE (protocol
) == PROTOCOL_INTERFACE_TYPE
)
5783 tree p
= CLASS_PROTOCOL_LIST (class);
5784 while (p
&& TREE_VALUE (p
) != protocol
)
5789 tree super
= (CLASS_SUPER_NAME (class)
5790 ? lookup_interface (CLASS_SUPER_NAME (class))
5792 int tmp
= super
? conforms_to_protocol (super
, protocol
) : 0;
5801 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5802 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5805 check_methods_accessible (chain
, context
, mtype
)
5812 tree base_context
= context
;
5816 context
= base_context
;
5820 list
= CLASS_CLS_METHODS (context
);
5822 list
= CLASS_NST_METHODS (context
);
5824 if (lookup_method (list
, chain
))
5827 else if (TREE_CODE (context
) == CLASS_IMPLEMENTATION_TYPE
5828 || TREE_CODE (context
) == CLASS_INTERFACE_TYPE
)
5829 context
= (CLASS_SUPER_NAME (context
)
5830 ? lookup_interface (CLASS_SUPER_NAME (context
))
5833 else if (TREE_CODE (context
) == CATEGORY_IMPLEMENTATION_TYPE
5834 || TREE_CODE (context
) == CATEGORY_INTERFACE_TYPE
)
5835 context
= (CLASS_NAME (context
)
5836 ? lookup_interface (CLASS_NAME (context
))
5842 if (context
== NULL_TREE
)
5846 if (TREE_CODE (objc_implementation_context
)
5847 == CLASS_IMPLEMENTATION_TYPE
)
5848 warning ("incomplete implementation of class `%s'",
5850 (CLASS_NAME (objc_implementation_context
)));
5851 else if (TREE_CODE (objc_implementation_context
)
5852 == CATEGORY_IMPLEMENTATION_TYPE
)
5853 warning ("incomplete implementation of category `%s'",
5855 (CLASS_SUPER_NAME (objc_implementation_context
)));
5858 warning ("method definition for `%c%s' not found",
5859 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
5862 chain
= TREE_CHAIN (chain
); /* next method... */
5867 /* Check whether the current interface (accessible via
5868 'objc_implementation_context') actually implements protocol P, along
5869 with any protocols that P inherits. */
5872 check_protocol (p
, type
, name
)
5877 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
5881 /* Ensure that all protocols have bodies! */
5882 if (flag_warn_protocol
)
5884 f1
= check_methods (PROTOCOL_CLS_METHODS (p
),
5885 CLASS_CLS_METHODS (objc_implementation_context
),
5887 f2
= check_methods (PROTOCOL_NST_METHODS (p
),
5888 CLASS_NST_METHODS (objc_implementation_context
),
5893 f1
= check_methods_accessible (PROTOCOL_CLS_METHODS (p
),
5894 objc_implementation_context
,
5896 f2
= check_methods_accessible (PROTOCOL_NST_METHODS (p
),
5897 objc_implementation_context
,
5902 warning ("%s `%s' does not fully implement the `%s' protocol",
5903 type
, name
, IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
5906 /* Check protocols recursively. */
5907 if (PROTOCOL_LIST (p
))
5909 tree subs
= PROTOCOL_LIST (p
);
5911 lookup_interface (CLASS_SUPER_NAME (implementation_template
));
5915 tree sub
= TREE_VALUE (subs
);
5917 /* If the superclass does not conform to the protocols
5918 inherited by P, then we must! */
5919 if (!super_class
|| !conforms_to_protocol (super_class
, sub
))
5920 check_protocol (sub
, type
, name
);
5921 subs
= TREE_CHAIN (subs
);
5926 /* Check whether the current interface (accessible via
5927 'objc_implementation_context') actually implements the protocols listed
5931 check_protocols (proto_list
, type
, name
)
5936 for ( ; proto_list
; proto_list
= TREE_CHAIN (proto_list
))
5938 tree p
= TREE_VALUE (proto_list
);
5940 check_protocol (p
, type
, name
);
5944 /* Make sure that the class CLASS_NAME is defined
5945 CODE says which kind of thing CLASS_NAME ought to be.
5946 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
5947 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
5950 start_class (code
, class_name
, super_name
, protocol_list
)
5951 enum tree_code code
;
5958 if (objc_implementation_context
)
5960 warning ("`@end' missing in implementation context");
5961 finish_class (objc_implementation_context
);
5962 objc_ivar_chain
= NULL_TREE
;
5963 objc_implementation_context
= NULL_TREE
;
5966 class = make_node (code
);
5967 TYPE_BINFO (class) = make_tree_vec (5);
5969 CLASS_NAME (class) = class_name
;
5970 CLASS_SUPER_NAME (class) = super_name
;
5971 CLASS_CLS_METHODS (class) = NULL_TREE
;
5973 if (! is_class_name (class_name
) && (decl
= lookup_name (class_name
)))
5975 error ("`%s' redeclared as different kind of symbol",
5976 IDENTIFIER_POINTER (class_name
));
5977 error_with_decl (decl
, "previous declaration of `%s'");
5980 if (code
== CLASS_IMPLEMENTATION_TYPE
)
5985 for (chain
= implemented_classes
; chain
; chain
= TREE_CHAIN (chain
))
5986 if (TREE_VALUE (chain
) == class_name
)
5988 error ("reimplementation of class `%s'",
5989 IDENTIFIER_POINTER (class_name
));
5990 return error_mark_node
;
5992 implemented_classes
= tree_cons (NULL_TREE
, class_name
,
5993 implemented_classes
);
5996 /* Pre-build the following entities - for speed/convenience. */
5998 self_id
= get_identifier ("self");
6000 ucmd_id
= get_identifier ("_cmd");
6003 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6004 if (!objc_super_template
)
6005 objc_super_template
= build_super_template ();
6007 /* Reset for multiple classes per file. */
6010 objc_implementation_context
= class;
6012 /* Lookup the interface for this implementation. */
6014 if (!(implementation_template
= lookup_interface (class_name
)))
6016 warning ("cannot find interface declaration for `%s'",
6017 IDENTIFIER_POINTER (class_name
));
6018 add_class (implementation_template
= objc_implementation_context
);
6021 /* If a super class has been specified in the implementation,
6022 insure it conforms to the one specified in the interface. */
6025 && (super_name
!= CLASS_SUPER_NAME (implementation_template
)))
6027 tree previous_name
= CLASS_SUPER_NAME (implementation_template
);
6028 const char *const name
=
6029 previous_name
? IDENTIFIER_POINTER (previous_name
) : "";
6030 error ("conflicting super class name `%s'",
6031 IDENTIFIER_POINTER (super_name
));
6032 error ("previous declaration of `%s'", name
);
6035 else if (! super_name
)
6037 CLASS_SUPER_NAME (objc_implementation_context
)
6038 = CLASS_SUPER_NAME (implementation_template
);
6042 else if (code
== CLASS_INTERFACE_TYPE
)
6044 if (lookup_interface (class_name
))
6045 warning ("duplicate interface declaration for class `%s'",
6046 IDENTIFIER_POINTER (class_name
));
6051 CLASS_PROTOCOL_LIST (class)
6052 = lookup_and_install_protocols (protocol_list
);
6055 else if (code
== CATEGORY_INTERFACE_TYPE
)
6057 tree class_category_is_assoc_with
;
6059 /* For a category, class_name is really the name of the class that
6060 the following set of methods will be associated with. We must
6061 find the interface so that can derive the objects template. */
6063 if (!(class_category_is_assoc_with
= lookup_interface (class_name
)))
6065 error ("cannot find interface declaration for `%s'",
6066 IDENTIFIER_POINTER (class_name
));
6067 exit (FATAL_EXIT_CODE
);
6070 add_category (class_category_is_assoc_with
, class);
6073 CLASS_PROTOCOL_LIST (class)
6074 = lookup_and_install_protocols (protocol_list
);
6077 else if (code
== CATEGORY_IMPLEMENTATION_TYPE
)
6079 /* Pre-build the following entities for speed/convenience. */
6081 self_id
= get_identifier ("self");
6083 ucmd_id
= get_identifier ("_cmd");
6086 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6087 if (!objc_super_template
)
6088 objc_super_template
= build_super_template ();
6090 /* Reset for multiple classes per file. */
6093 objc_implementation_context
= class;
6095 /* For a category, class_name is really the name of the class that
6096 the following set of methods will be associated with. We must
6097 find the interface so that can derive the objects template. */
6099 if (!(implementation_template
= lookup_interface (class_name
)))
6101 error ("cannot find interface declaration for `%s'",
6102 IDENTIFIER_POINTER (class_name
));
6103 exit (FATAL_EXIT_CODE
);
6110 continue_class (class)
6113 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6114 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6116 struct imp_entry
*imp_entry
;
6119 /* Check consistency of the instance variables. */
6121 if (CLASS_IVARS (class))
6122 check_ivars (implementation_template
, class);
6124 /* code generation */
6126 ivar_context
= build_private_template (implementation_template
);
6128 if (!objc_class_template
)
6129 build_class_template ();
6131 imp_entry
= (struct imp_entry
*) ggc_alloc (sizeof (struct imp_entry
));
6133 imp_entry
->next
= imp_list
;
6134 imp_entry
->imp_context
= class;
6135 imp_entry
->imp_template
= implementation_template
;
6137 synth_forward_declarations ();
6138 imp_entry
->class_decl
= UOBJC_CLASS_decl
;
6139 imp_entry
->meta_decl
= UOBJC_METACLASS_decl
;
6141 /* Append to front and increment count. */
6142 imp_list
= imp_entry
;
6143 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6148 return ivar_context
;
6151 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6153 tree record
= xref_tag (RECORD_TYPE
, CLASS_NAME (class));
6155 if (!TYPE_FIELDS (record
))
6157 finish_struct (record
, build_ivar_chain (class, 0), NULL_TREE
);
6158 CLASS_STATIC_TEMPLATE (class) = record
;
6160 /* Mark this record as a class template for static typing. */
6161 TREE_STATIC_TEMPLATE (record
) = 1;
6168 return error_mark_node
;
6171 /* This is called once we see the "@end" in an interface/implementation. */
6174 finish_class (class)
6177 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6179 /* All code generation is done in finish_objc. */
6181 if (implementation_template
!= objc_implementation_context
)
6183 /* Ensure that all method listed in the interface contain bodies. */
6184 check_methods (CLASS_CLS_METHODS (implementation_template
),
6185 CLASS_CLS_METHODS (objc_implementation_context
), '+');
6186 check_methods (CLASS_NST_METHODS (implementation_template
),
6187 CLASS_NST_METHODS (objc_implementation_context
), '-');
6189 if (CLASS_PROTOCOL_LIST (implementation_template
))
6190 check_protocols (CLASS_PROTOCOL_LIST (implementation_template
),
6192 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
)));
6196 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6198 tree category
= CLASS_CATEGORY_LIST (implementation_template
);
6200 /* Find the category interface from the class it is associated with. */
6203 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category
))
6205 category
= CLASS_CATEGORY_LIST (category
);
6210 /* Ensure all method listed in the interface contain bodies. */
6211 check_methods (CLASS_CLS_METHODS (category
),
6212 CLASS_CLS_METHODS (objc_implementation_context
), '+');
6213 check_methods (CLASS_NST_METHODS (category
),
6214 CLASS_NST_METHODS (objc_implementation_context
), '-');
6216 if (CLASS_PROTOCOL_LIST (category
))
6217 check_protocols (CLASS_PROTOCOL_LIST (category
),
6219 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
6223 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6226 const char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (class));
6227 char *string
= (char *) alloca (strlen (class_name
) + 3);
6229 /* extern struct objc_object *_<my_name>; */
6231 sprintf (string
, "_%s", class_name
);
6233 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
6234 decl_specs
= tree_cons (NULL_TREE
, objc_object_reference
, decl_specs
);
6235 define_decl (build1 (INDIRECT_REF
, NULL_TREE
, get_identifier (string
)),
6241 add_protocol (protocol
)
6244 /* Put protocol on list in reverse order. */
6245 TREE_CHAIN (protocol
) = protocol_chain
;
6246 protocol_chain
= protocol
;
6247 return protocol_chain
;
6251 lookup_protocol (ident
)
6256 for (chain
= protocol_chain
; chain
; chain
= TREE_CHAIN (chain
))
6257 if (ident
== PROTOCOL_NAME (chain
))
6263 /* This function forward declares the protocols named by NAMES. If
6264 they are already declared or defined, the function has no effect. */
6267 objc_declare_protocols (names
)
6272 for (list
= names
; list
; list
= TREE_CHAIN (list
))
6274 tree name
= TREE_VALUE (list
);
6276 if (lookup_protocol (name
) == NULL_TREE
)
6278 tree protocol
= make_node (PROTOCOL_INTERFACE_TYPE
);
6280 TYPE_BINFO (protocol
) = make_tree_vec (2);
6281 PROTOCOL_NAME (protocol
) = name
;
6282 PROTOCOL_LIST (protocol
) = NULL_TREE
;
6283 add_protocol (protocol
);
6284 PROTOCOL_DEFINED (protocol
) = 0;
6285 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6291 start_protocol (code
, name
, list
)
6292 enum tree_code code
;
6298 /* This is as good a place as any. Need to invoke
6299 push_tag_toplevel. */
6300 if (!objc_protocol_template
)
6301 objc_protocol_template
= build_protocol_template ();
6303 protocol
= lookup_protocol (name
);
6307 protocol
= make_node (code
);
6308 TYPE_BINFO (protocol
) = make_tree_vec (2);
6310 PROTOCOL_NAME (protocol
) = name
;
6311 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
6312 add_protocol (protocol
);
6313 PROTOCOL_DEFINED (protocol
) = 1;
6314 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6316 check_protocol_recursively (protocol
, list
);
6318 else if (! PROTOCOL_DEFINED (protocol
))
6320 PROTOCOL_DEFINED (protocol
) = 1;
6321 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
6323 check_protocol_recursively (protocol
, list
);
6327 warning ("duplicate declaration for protocol `%s'",
6328 IDENTIFIER_POINTER (name
));
6334 finish_protocol (protocol
)
6335 tree protocol ATTRIBUTE_UNUSED
;
6340 /* "Encode" a data type into a string, which grows in util_obstack.
6341 ??? What is the FORMAT? Someone please document this! */
6344 encode_type_qualifiers (declspecs
)
6349 for (spec
= declspecs
; spec
; spec
= TREE_CHAIN (spec
))
6351 if (ridpointers
[(int) RID_CONST
] == TREE_VALUE (spec
))
6352 obstack_1grow (&util_obstack
, 'r');
6353 else if (ridpointers
[(int) RID_IN
] == TREE_VALUE (spec
))
6354 obstack_1grow (&util_obstack
, 'n');
6355 else if (ridpointers
[(int) RID_INOUT
] == TREE_VALUE (spec
))
6356 obstack_1grow (&util_obstack
, 'N');
6357 else if (ridpointers
[(int) RID_OUT
] == TREE_VALUE (spec
))
6358 obstack_1grow (&util_obstack
, 'o');
6359 else if (ridpointers
[(int) RID_BYCOPY
] == TREE_VALUE (spec
))
6360 obstack_1grow (&util_obstack
, 'O');
6361 else if (ridpointers
[(int) RID_BYREF
] == TREE_VALUE (spec
))
6362 obstack_1grow (&util_obstack
, 'R');
6363 else if (ridpointers
[(int) RID_ONEWAY
] == TREE_VALUE (spec
))
6364 obstack_1grow (&util_obstack
, 'V');
6368 /* Encode a pointer type. */
6371 encode_pointer (type
, curtype
, format
)
6376 tree pointer_to
= TREE_TYPE (type
);
6378 if (TREE_CODE (pointer_to
) == RECORD_TYPE
)
6380 if (TYPE_NAME (pointer_to
)
6381 && TREE_CODE (TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
)
6383 const char *name
= IDENTIFIER_POINTER (TYPE_NAME (pointer_to
));
6385 if (strcmp (name
, TAG_OBJECT
) == 0) /* '@' */
6387 obstack_1grow (&util_obstack
, '@');
6390 else if (TREE_STATIC_TEMPLATE (pointer_to
))
6392 if (generating_instance_variables
)
6394 obstack_1grow (&util_obstack
, '@');
6395 obstack_1grow (&util_obstack
, '"');
6396 obstack_grow (&util_obstack
, name
, strlen (name
));
6397 obstack_1grow (&util_obstack
, '"');
6402 obstack_1grow (&util_obstack
, '@');
6406 else if (strcmp (name
, TAG_CLASS
) == 0) /* '#' */
6408 obstack_1grow (&util_obstack
, '#');
6411 else if (strcmp (name
, TAG_SELECTOR
) == 0) /* ':' */
6413 obstack_1grow (&util_obstack
, ':');
6418 else if (TREE_CODE (pointer_to
) == INTEGER_TYPE
6419 && TYPE_MODE (pointer_to
) == QImode
)
6421 obstack_1grow (&util_obstack
, '*');
6425 /* We have a type that does not get special treatment. */
6427 /* NeXT extension */
6428 obstack_1grow (&util_obstack
, '^');
6429 encode_type (pointer_to
, curtype
, format
);
6433 encode_array (type
, curtype
, format
)
6438 tree an_int_cst
= TYPE_SIZE (type
);
6439 tree array_of
= TREE_TYPE (type
);
6442 /* An incomplete array is treated like a pointer. */
6443 if (an_int_cst
== NULL
)
6445 encode_pointer (type
, curtype
, format
);
6449 sprintf (buffer
, "[%ld",
6450 (long) (TREE_INT_CST_LOW (an_int_cst
)
6451 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
6453 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6454 encode_type (array_of
, curtype
, format
);
6455 obstack_1grow (&util_obstack
, ']');
6460 encode_aggregate_within (type
, curtype
, format
, left
, right
)
6467 /* The RECORD_TYPE may in fact be a typedef! For purposes
6468 of encoding, we need the real underlying enchilada. */
6469 if (TYPE_MAIN_VARIANT (type
))
6470 type
= TYPE_MAIN_VARIANT (type
);
6472 if (obstack_object_size (&util_obstack
) > 0
6473 && *(obstack_next_free (&util_obstack
) - 1) == '^')
6475 tree name
= TYPE_NAME (type
);
6477 /* we have a reference; this is a NeXT extension. */
6479 if (obstack_object_size (&util_obstack
) - curtype
== 1
6480 && format
== OBJC_ENCODE_INLINE_DEFS
)
6482 /* Output format of struct for first level only. */
6483 tree fields
= TYPE_FIELDS (type
);
6485 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6487 obstack_1grow (&util_obstack
, left
);
6488 obstack_grow (&util_obstack
,
6489 IDENTIFIER_POINTER (name
),
6490 strlen (IDENTIFIER_POINTER (name
)));
6491 obstack_1grow (&util_obstack
, '=');
6495 obstack_1grow (&util_obstack
, left
);
6496 obstack_grow (&util_obstack
, "?=", 2);
6499 for ( ; fields
; fields
= TREE_CHAIN (fields
))
6500 encode_field_decl (fields
, curtype
, format
);
6502 obstack_1grow (&util_obstack
, right
);
6505 else if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6507 obstack_1grow (&util_obstack
, left
);
6508 obstack_grow (&util_obstack
,
6509 IDENTIFIER_POINTER (name
),
6510 strlen (IDENTIFIER_POINTER (name
)));
6511 obstack_1grow (&util_obstack
, right
);
6516 /* We have an untagged structure or a typedef. */
6517 obstack_1grow (&util_obstack
, left
);
6518 obstack_1grow (&util_obstack
, '?');
6519 obstack_1grow (&util_obstack
, right
);
6525 tree name
= TYPE_NAME (type
);
6526 tree fields
= TYPE_FIELDS (type
);
6528 if (format
== OBJC_ENCODE_INLINE_DEFS
6529 || generating_instance_variables
)
6531 obstack_1grow (&util_obstack
, left
);
6532 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6533 obstack_grow (&util_obstack
,
6534 IDENTIFIER_POINTER (name
),
6535 strlen (IDENTIFIER_POINTER (name
)));
6537 obstack_1grow (&util_obstack
, '?');
6539 obstack_1grow (&util_obstack
, '=');
6541 for (; fields
; fields
= TREE_CHAIN (fields
))
6543 if (generating_instance_variables
)
6545 tree fname
= DECL_NAME (fields
);
6547 obstack_1grow (&util_obstack
, '"');
6548 if (fname
&& TREE_CODE (fname
) == IDENTIFIER_NODE
)
6550 obstack_grow (&util_obstack
,
6551 IDENTIFIER_POINTER (fname
),
6552 strlen (IDENTIFIER_POINTER (fname
)));
6555 obstack_1grow (&util_obstack
, '"');
6558 encode_field_decl (fields
, curtype
, format
);
6561 obstack_1grow (&util_obstack
, right
);
6566 obstack_1grow (&util_obstack
, left
);
6567 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6568 obstack_grow (&util_obstack
,
6569 IDENTIFIER_POINTER (name
),
6570 strlen (IDENTIFIER_POINTER (name
)));
6572 /* We have an untagged structure or a typedef. */
6573 obstack_1grow (&util_obstack
, '?');
6575 obstack_1grow (&util_obstack
, right
);
6581 encode_aggregate (type
, curtype
, format
)
6586 enum tree_code code
= TREE_CODE (type
);
6592 encode_aggregate_within(type
, curtype
, format
, '{', '}');
6597 encode_aggregate_within(type
, curtype
, format
, '(', ')');
6602 obstack_1grow (&util_obstack
, 'i');
6610 /* Support bitfields. The current version of Objective-C does not support
6611 them. The string will consist of one or more "b:n"'s where n is an
6612 integer describing the width of the bitfield. Currently, classes in
6613 the kit implement a method "-(char *)describeBitfieldStruct:" that
6614 simulates this. If they do not implement this method, the archiver
6615 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6616 according to the GNU compiler. After looking at the "kit", it appears
6617 that all classes currently rely on this default behavior, rather than
6618 hand generating this string (which is tedious). */
6621 encode_bitfield (width
)
6625 sprintf (buffer
, "b%d", width
);
6626 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6629 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6632 encode_type (type
, curtype
, format
)
6637 enum tree_code code
= TREE_CODE (type
);
6639 if (code
== INTEGER_TYPE
)
6641 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6643 /* Unsigned integer types. */
6645 if (TYPE_MODE (type
) == QImode
)
6646 obstack_1grow (&util_obstack
, 'C');
6647 else if (TYPE_MODE (type
) == HImode
)
6648 obstack_1grow (&util_obstack
, 'S');
6649 else if (TYPE_MODE (type
) == SImode
)
6651 if (type
== long_unsigned_type_node
)
6652 obstack_1grow (&util_obstack
, 'L');
6654 obstack_1grow (&util_obstack
, 'I');
6656 else if (TYPE_MODE (type
) == DImode
)
6657 obstack_1grow (&util_obstack
, 'Q');
6661 /* Signed integer types. */
6663 if (TYPE_MODE (type
) == QImode
)
6664 obstack_1grow (&util_obstack
, 'c');
6665 else if (TYPE_MODE (type
) == HImode
)
6666 obstack_1grow (&util_obstack
, 's');
6667 else if (TYPE_MODE (type
) == SImode
)
6669 if (type
== long_integer_type_node
)
6670 obstack_1grow (&util_obstack
, 'l');
6672 obstack_1grow (&util_obstack
, 'i');
6675 else if (TYPE_MODE (type
) == DImode
)
6676 obstack_1grow (&util_obstack
, 'q');
6680 else if (code
== REAL_TYPE
)
6682 /* Floating point types. */
6684 if (TYPE_MODE (type
) == SFmode
)
6685 obstack_1grow (&util_obstack
, 'f');
6686 else if (TYPE_MODE (type
) == DFmode
6687 || TYPE_MODE (type
) == TFmode
)
6688 obstack_1grow (&util_obstack
, 'd');
6691 else if (code
== VOID_TYPE
)
6692 obstack_1grow (&util_obstack
, 'v');
6694 else if (code
== ARRAY_TYPE
)
6695 encode_array (type
, curtype
, format
);
6697 else if (code
== POINTER_TYPE
)
6698 encode_pointer (type
, curtype
, format
);
6700 else if (code
== RECORD_TYPE
|| code
== UNION_TYPE
|| code
== ENUMERAL_TYPE
)
6701 encode_aggregate (type
, curtype
, format
);
6703 else if (code
== FUNCTION_TYPE
) /* '?' */
6704 obstack_1grow (&util_obstack
, '?');
6708 encode_complete_bitfield (int position
, tree type
, int size
)
6710 enum tree_code code
= TREE_CODE (type
);
6712 char charType
= '?';
6714 if (code
== INTEGER_TYPE
)
6716 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6718 /* Unsigned integer types. */
6720 if (TYPE_MODE (type
) == QImode
)
6722 else if (TYPE_MODE (type
) == HImode
)
6724 else if (TYPE_MODE (type
) == SImode
)
6726 if (type
== long_unsigned_type_node
)
6731 else if (TYPE_MODE (type
) == DImode
)
6736 /* Signed integer types. */
6738 if (TYPE_MODE (type
) == QImode
)
6740 else if (TYPE_MODE (type
) == HImode
)
6742 else if (TYPE_MODE (type
) == SImode
)
6744 if (type
== long_integer_type_node
)
6750 else if (TYPE_MODE (type
) == DImode
)
6754 else if (code
== ENUMERAL_TYPE
)
6759 sprintf (buffer
, "b%d%c%d", position
, charType
, size
);
6760 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6764 encode_field_decl (field_decl
, curtype
, format
)
6771 type
= TREE_TYPE (field_decl
);
6773 /* If this field is obviously a bitfield, or is a bitfield that has been
6774 clobbered to look like a ordinary integer mode, go ahead and generate
6775 the bitfield typing information. */
6776 if (flag_next_runtime
)
6778 if (DECL_BIT_FIELD (field_decl
))
6779 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl
), 1));
6781 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6785 if (DECL_BIT_FIELD (field_decl
))
6786 encode_complete_bitfield (int_bit_position (field_decl
),
6787 DECL_BIT_FIELD_TYPE (field_decl
),
6788 tree_low_cst (DECL_SIZE (field_decl
), 1));
6790 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6795 expr_last (complex_expr
)
6801 while ((next
= TREE_OPERAND (complex_expr
, 0)))
6802 complex_expr
= next
;
6804 return complex_expr
;
6807 /* Transform a method definition into a function definition as follows:
6808 - synthesize the first two arguments, "self" and "_cmd". */
6811 start_method_def (method
)
6816 /* Required to implement _msgSuper. */
6817 objc_method_context
= method
;
6818 UOBJC_SUPER_decl
= NULL_TREE
;
6820 /* Must be called BEFORE start_function. */
6823 /* Generate prototype declarations for arguments..."new-style". */
6825 if (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
)
6826 decl_specs
= build_tree_list (NULL_TREE
, uprivate_record
);
6828 /* Really a `struct objc_class *'. However, we allow people to
6829 assign to self, which changes its type midstream. */
6830 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
6832 push_parm_decl (build_tree_list
6833 (build_tree_list (decl_specs
,
6834 build1 (INDIRECT_REF
, NULL_TREE
, self_id
)),
6837 decl_specs
= build_tree_list (NULL_TREE
,
6838 xref_tag (RECORD_TYPE
,
6839 get_identifier (TAG_SELECTOR
)));
6840 push_parm_decl (build_tree_list
6841 (build_tree_list (decl_specs
,
6842 build1 (INDIRECT_REF
, NULL_TREE
, ucmd_id
)),
6845 /* Generate argument declarations if a keyword_decl. */
6846 if (METHOD_SEL_ARGS (method
))
6848 tree arglist
= METHOD_SEL_ARGS (method
);
6851 tree arg_spec
= TREE_PURPOSE (TREE_TYPE (arglist
));
6852 tree arg_decl
= TREE_VALUE (TREE_TYPE (arglist
));
6856 tree last_expr
= expr_last (arg_decl
);
6858 /* Unite the abstract decl with its name. */
6859 TREE_OPERAND (last_expr
, 0) = KEYWORD_ARG_NAME (arglist
);
6860 push_parm_decl (build_tree_list
6861 (build_tree_list (arg_spec
, arg_decl
),
6864 /* Unhook: restore the abstract declarator. */
6865 TREE_OPERAND (last_expr
, 0) = NULL_TREE
;
6869 push_parm_decl (build_tree_list
6870 (build_tree_list (arg_spec
,
6871 KEYWORD_ARG_NAME (arglist
)),
6874 arglist
= TREE_CHAIN (arglist
);
6879 if (METHOD_ADD_ARGS (method
) != NULL_TREE
6880 && METHOD_ADD_ARGS (method
) != objc_ellipsis_node
)
6882 /* We have a variable length selector - in "prototype" format. */
6883 tree akey
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
6886 /* This must be done prior to calling pushdecl. pushdecl is
6887 going to change our chain on us. */
6888 tree nextkey
= TREE_CHAIN (akey
);
6896 warn_with_method (message
, mtype
, method
)
6897 const char *message
;
6901 if (!diagnostic_count_diagnostic (global_dc
, DK_WARNING
))
6904 diagnostic_report_current_function (global_dc
);
6906 /* Add a readable method name to the warning. */
6907 warning_with_file_and_line (DECL_SOURCE_FILE (method
),
6908 DECL_SOURCE_LINE (method
),
6911 gen_method_decl (method
, errbuf
));
6914 /* Return 1 if METHOD is consistent with PROTO. */
6917 comp_method_with_proto (method
, proto
)
6920 /* Create a function template node at most once. */
6921 if (!function1_template
)
6922 function1_template
= make_node (FUNCTION_TYPE
);
6924 /* Install argument types - normally set by build_function_type. */
6925 TYPE_ARG_TYPES (function1_template
) = get_arg_type_list (proto
, METHOD_DEF
, 0);
6927 /* install return type */
6928 TREE_TYPE (function1_template
) = groktypename (TREE_TYPE (proto
));
6930 return comptypes (TREE_TYPE (METHOD_DEFINITION (method
)), function1_template
);
6933 /* Return 1 if PROTO1 is consistent with PROTO2. */
6936 comp_proto_with_proto (proto0
, proto1
)
6937 tree proto0
, proto1
;
6939 /* Create a couple of function_template nodes at most once. */
6940 if (!function1_template
)
6941 function1_template
= make_node (FUNCTION_TYPE
);
6942 if (!function2_template
)
6943 function2_template
= make_node (FUNCTION_TYPE
);
6945 /* Install argument types; normally set by build_function_type. */
6946 TYPE_ARG_TYPES (function1_template
) = get_arg_type_list (proto0
, METHOD_REF
, 0);
6947 TYPE_ARG_TYPES (function2_template
) = get_arg_type_list (proto1
, METHOD_REF
, 0);
6949 /* Install return type. */
6950 TREE_TYPE (function1_template
) = groktypename (TREE_TYPE (proto0
));
6951 TREE_TYPE (function2_template
) = groktypename (TREE_TYPE (proto1
));
6953 return comptypes (function1_template
, function2_template
);
6956 /* - Generate an identifier for the function. the format is "_n_cls",
6957 where 1 <= n <= nMethods, and cls is the name the implementation we
6959 - Install the return type from the method declaration.
6960 - If we have a prototype, check for type consistency. */
6963 really_start_method (method
, parmlist
)
6964 tree method
, parmlist
;
6966 tree sc_spec
, ret_spec
, ret_decl
, decl_specs
;
6967 tree method_decl
, method_id
;
6968 const char *sel_name
, *class_name
, *cat_name
;
6971 /* Synth the storage class & assemble the return type. */
6972 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
6973 ret_spec
= TREE_PURPOSE (TREE_TYPE (method
));
6974 decl_specs
= chainon (sc_spec
, ret_spec
);
6976 sel_name
= IDENTIFIER_POINTER (METHOD_SEL_NAME (method
));
6977 class_name
= IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
6978 cat_name
= ((TREE_CODE (objc_implementation_context
)
6979 == CLASS_IMPLEMENTATION_TYPE
)
6981 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
6984 /* Make sure this is big enough for any plausible method label. */
6985 buf
= (char *) alloca (50 + strlen (sel_name
) + strlen (class_name
)
6986 + (cat_name
? strlen (cat_name
) : 0));
6988 OBJC_GEN_METHOD_LABEL (buf
, TREE_CODE (method
) == INSTANCE_METHOD_DECL
,
6989 class_name
, cat_name
, sel_name
, method_slot
);
6991 method_id
= get_identifier (buf
);
6993 method_decl
= build_nt (CALL_EXPR
, method_id
, parmlist
, NULL_TREE
);
6995 /* Check the declarator portion of the return type for the method. */
6996 if ((ret_decl
= TREE_VALUE (TREE_TYPE (method
))))
6998 /* Unite the complex decl (specified in the abstract decl) with the
6999 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7000 tree save_expr
= expr_last (ret_decl
);
7002 TREE_OPERAND (save_expr
, 0) = method_decl
;
7003 method_decl
= ret_decl
;
7005 /* Fool the parser into thinking it is starting a function. */
7006 start_function (decl_specs
, method_decl
, NULL_TREE
);
7008 /* Unhook: this has the effect of restoring the abstract declarator. */
7009 TREE_OPERAND (save_expr
, 0) = NULL_TREE
;
7014 TREE_VALUE (TREE_TYPE (method
)) = method_decl
;
7016 /* Fool the parser into thinking it is starting a function. */
7017 start_function (decl_specs
, method_decl
, NULL_TREE
);
7019 /* Unhook: this has the effect of restoring the abstract declarator. */
7020 TREE_VALUE (TREE_TYPE (method
)) = NULL_TREE
;
7023 METHOD_DEFINITION (method
) = current_function_decl
;
7025 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7027 if (implementation_template
!= objc_implementation_context
)
7031 if (TREE_CODE (method
) == INSTANCE_METHOD_DECL
)
7032 proto
= lookup_instance_method_static (implementation_template
,
7033 METHOD_SEL_NAME (method
));
7035 proto
= lookup_class_method_static (implementation_template
,
7036 METHOD_SEL_NAME (method
));
7038 if (proto
&& ! comp_method_with_proto (method
, proto
))
7040 char type
= (TREE_CODE (method
) == INSTANCE_METHOD_DECL
? '-' : '+');
7042 warn_with_method ("conflicting types for", type
, method
);
7043 warn_with_method ("previous declaration of", type
, proto
);
7048 /* The following routine is always called...this "architecture" is to
7049 accommodate "old-style" variable length selectors.
7051 - a:a b:b // prototype ; id c; id d; // old-style. */
7054 continue_method_def ()
7058 if (METHOD_ADD_ARGS (objc_method_context
) == objc_ellipsis_node
)
7059 /* We have a `, ...' immediately following the selector. */
7060 parmlist
= get_parm_info (0);
7062 parmlist
= get_parm_info (1); /* place a `void_at_end' */
7064 /* Set self_decl from the first argument...this global is used by
7065 build_ivar_reference calling build_indirect_ref. */
7066 self_decl
= TREE_PURPOSE (parmlist
);
7069 really_start_method (objc_method_context
, parmlist
);
7070 store_parm_decls ();
7073 /* Called by the parser, from the `pushlevel' production. */
7078 if (!UOBJC_SUPER_decl
)
7080 UOBJC_SUPER_decl
= start_decl (get_identifier (UTAG_SUPER
),
7081 build_tree_list (NULL_TREE
,
7082 objc_super_template
),
7085 finish_decl (UOBJC_SUPER_decl
, NULL_TREE
, NULL_TREE
);
7087 /* This prevents `unused variable' warnings when compiling with -Wall. */
7088 TREE_USED (UOBJC_SUPER_decl
) = 1;
7089 DECL_ARTIFICIAL (UOBJC_SUPER_decl
) = 1;
7093 /* _n_Method (id self, SEL sel, ...)
7095 struct objc_super _S;
7096 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7100 get_super_receiver ()
7102 if (objc_method_context
)
7104 tree super_expr
, super_expr_list
;
7106 /* Set receiver to self. */
7107 super_expr
= build_component_ref (UOBJC_SUPER_decl
, self_id
);
7108 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, self_decl
);
7109 super_expr_list
= build_tree_list (NULL_TREE
, super_expr
);
7111 /* Set class to begin searching. */
7112 super_expr
= build_component_ref (UOBJC_SUPER_decl
,
7113 get_identifier ("class"));
7115 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
7117 /* [_cls, __cls]Super are "pre-built" in
7118 synth_forward_declarations. */
7120 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
,
7121 ((TREE_CODE (objc_method_context
)
7122 == INSTANCE_METHOD_DECL
)
7124 : uucls_super_ref
));
7128 /* We have a category. */
7130 tree super_name
= CLASS_SUPER_NAME (implementation_template
);
7133 /* Barf if super used in a category of Object. */
7136 error ("no super class declared in interface for `%s'",
7137 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
7138 return error_mark_node
;
7141 if (flag_next_runtime
)
7143 super_class
= get_class_reference (super_name
);
7144 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
7146 = build_component_ref (build_indirect_ref (super_class
, "->"),
7147 get_identifier ("isa"));
7151 add_class_reference (super_name
);
7152 super_class
= (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
7153 ? objc_get_class_decl
: objc_get_meta_class_decl
);
7154 assemble_external (super_class
);
7156 = build_function_call
7160 my_build_string (IDENTIFIER_LENGTH (super_name
) + 1,
7161 IDENTIFIER_POINTER (super_name
))));
7164 TREE_TYPE (super_class
) = TREE_TYPE (ucls_super_ref
);
7165 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, super_class
);
7168 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7170 super_expr
= build_unary_op (ADDR_EXPR
, UOBJC_SUPER_decl
, 0);
7171 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7173 return build_compound_expr (super_expr_list
);
7177 error ("[super ...] must appear in a method context");
7178 return error_mark_node
;
7183 encode_method_def (func_decl
)
7188 HOST_WIDE_INT max_parm_end
= 0;
7193 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
7194 obstack_object_size (&util_obstack
),
7195 OBJC_ENCODE_INLINE_DEFS
);
7198 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7199 parms
= TREE_CHAIN (parms
))
7201 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
7202 + int_size_in_bytes (TREE_TYPE (parms
)));
7204 if (! offset_is_register
&& parm_end
> max_parm_end
)
7205 max_parm_end
= parm_end
;
7208 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
7210 sprintf (buffer
, "%d", stack_size
);
7211 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7213 /* Argument types. */
7214 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7215 parms
= TREE_CHAIN (parms
))
7218 encode_type (TREE_TYPE (parms
),
7219 obstack_object_size (&util_obstack
),
7220 OBJC_ENCODE_INLINE_DEFS
);
7222 /* Compute offset. */
7223 sprintf (buffer
, "%d", forwarding_offset (parms
));
7225 /* Indicate register. */
7226 if (offset_is_register
)
7227 obstack_1grow (&util_obstack
, '+');
7229 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7232 /* Null terminate string. */
7233 obstack_1grow (&util_obstack
, 0);
7234 result
= get_identifier (obstack_finish (&util_obstack
));
7235 obstack_free (&util_obstack
, util_firstobj
);
7240 objc_expand_function_end ()
7242 METHOD_ENCODING (objc_method_context
) = encode_method_def (current_function_decl
);
7246 finish_method_def ()
7248 lang_expand_function_end
= objc_expand_function_end
;
7249 finish_function (0, 1);
7250 lang_expand_function_end
= NULL
;
7252 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7253 since the optimizer may find "may be used before set" errors. */
7254 objc_method_context
= NULL_TREE
;
7259 lang_report_error_function (decl
)
7262 if (objc_method_context
)
7264 fprintf (stderr
, "In method `%s'\n",
7265 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context
)));
7275 is_complex_decl (type
)
7278 return (TREE_CODE (type
) == ARRAY_TYPE
7279 || TREE_CODE (type
) == FUNCTION_TYPE
7280 || (TREE_CODE (type
) == POINTER_TYPE
&& ! IS_ID (type
)));
7284 /* Code to convert a decl node into text for a declaration in C. */
7286 static char tmpbuf
[256];
7289 adorn_decl (decl
, str
)
7293 enum tree_code code
= TREE_CODE (decl
);
7295 if (code
== ARRAY_REF
)
7297 tree an_int_cst
= TREE_OPERAND (decl
, 1);
7299 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_CST
)
7300 sprintf (str
+ strlen (str
), "[%ld]",
7301 (long) TREE_INT_CST_LOW (an_int_cst
));
7306 else if (code
== ARRAY_TYPE
)
7308 tree an_int_cst
= TYPE_SIZE (decl
);
7309 tree array_of
= TREE_TYPE (decl
);
7311 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_TYPE
)
7312 sprintf (str
+ strlen (str
), "[%ld]",
7313 (long) (TREE_INT_CST_LOW (an_int_cst
)
7314 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
7319 else if (code
== CALL_EXPR
)
7321 tree chain
= TREE_PURPOSE (TREE_OPERAND (decl
, 1));
7326 gen_declaration_1 (chain
, str
);
7327 chain
= TREE_CHAIN (chain
);
7334 else if (code
== FUNCTION_TYPE
)
7336 tree chain
= TYPE_ARG_TYPES (decl
);
7339 while (chain
&& TREE_VALUE (chain
) != void_type_node
)
7341 gen_declaration_1 (TREE_VALUE (chain
), str
);
7342 chain
= TREE_CHAIN (chain
);
7343 if (chain
&& TREE_VALUE (chain
) != void_type_node
)
7349 else if (code
== INDIRECT_REF
)
7351 strcpy (tmpbuf
, "*");
7352 if (TREE_TYPE (decl
) && TREE_CODE (TREE_TYPE (decl
)) == TREE_LIST
)
7356 for (chain
= nreverse (copy_list (TREE_TYPE (decl
)));
7358 chain
= TREE_CHAIN (chain
))
7360 if (TREE_CODE (TREE_VALUE (chain
)) == IDENTIFIER_NODE
)
7362 strcat (tmpbuf
, " ");
7363 strcat (tmpbuf
, IDENTIFIER_POINTER (TREE_VALUE (chain
)));
7367 strcat (tmpbuf
, " ");
7369 strcat (tmpbuf
, str
);
7370 strcpy (str
, tmpbuf
);
7373 else if (code
== POINTER_TYPE
)
7375 strcpy (tmpbuf
, "*");
7376 if (TREE_READONLY (decl
) || TYPE_VOLATILE (decl
))
7378 if (TREE_READONLY (decl
))
7379 strcat (tmpbuf
, " const");
7380 if (TYPE_VOLATILE (decl
))
7381 strcat (tmpbuf
, " volatile");
7383 strcat (tmpbuf
, " ");
7385 strcat (tmpbuf
, str
);
7386 strcpy (str
, tmpbuf
);
7391 gen_declarator (decl
, buf
, name
)
7398 enum tree_code code
= TREE_CODE (decl
);
7408 op
= TREE_OPERAND (decl
, 0);
7410 /* We have a pointer to a function or array...(*)(), (*)[] */
7411 if ((code
== ARRAY_REF
|| code
== CALL_EXPR
)
7412 && op
&& TREE_CODE (op
) == INDIRECT_REF
)
7415 str
= gen_declarator (op
, buf
, name
);
7419 strcpy (tmpbuf
, "(");
7420 strcat (tmpbuf
, str
);
7421 strcat (tmpbuf
, ")");
7422 strcpy (str
, tmpbuf
);
7425 adorn_decl (decl
, str
);
7434 /* This clause is done iteratively rather than recursively. */
7437 op
= (is_complex_decl (TREE_TYPE (decl
))
7438 ? TREE_TYPE (decl
) : NULL_TREE
);
7440 adorn_decl (decl
, str
);
7442 /* We have a pointer to a function or array...(*)(), (*)[] */
7443 if (code
== POINTER_TYPE
7444 && op
&& (TREE_CODE (op
) == FUNCTION_TYPE
7445 || TREE_CODE (op
) == ARRAY_TYPE
))
7447 strcpy (tmpbuf
, "(");
7448 strcat (tmpbuf
, str
);
7449 strcat (tmpbuf
, ")");
7450 strcpy (str
, tmpbuf
);
7453 decl
= (is_complex_decl (TREE_TYPE (decl
))
7454 ? TREE_TYPE (decl
) : NULL_TREE
);
7457 while (decl
&& (code
= TREE_CODE (decl
)))
7462 case IDENTIFIER_NODE
:
7463 /* Will only happen if we are processing a "raw" expr-decl. */
7464 strcpy (buf
, IDENTIFIER_POINTER (decl
));
7475 /* We have an abstract declarator or a _DECL node. */
7483 gen_declspecs (declspecs
, buf
, raw
)
7492 for (chain
= nreverse (copy_list (declspecs
));
7493 chain
; chain
= TREE_CHAIN (chain
))
7495 tree aspec
= TREE_VALUE (chain
);
7497 if (TREE_CODE (aspec
) == IDENTIFIER_NODE
)
7498 strcat (buf
, IDENTIFIER_POINTER (aspec
));
7499 else if (TREE_CODE (aspec
) == RECORD_TYPE
)
7501 if (TYPE_NAME (aspec
))
7503 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7505 if (! TREE_STATIC_TEMPLATE (aspec
))
7506 strcat (buf
, "struct ");
7507 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7512 tree chain
= protocol_list
;
7519 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7520 chain
= TREE_CHAIN (chain
);
7529 strcat (buf
, "untagged struct");
7532 else if (TREE_CODE (aspec
) == UNION_TYPE
)
7534 if (TYPE_NAME (aspec
))
7536 if (! TREE_STATIC_TEMPLATE (aspec
))
7537 strcat (buf
, "union ");
7538 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7541 strcat (buf
, "untagged union");
7544 else if (TREE_CODE (aspec
) == ENUMERAL_TYPE
)
7546 if (TYPE_NAME (aspec
))
7548 if (! TREE_STATIC_TEMPLATE (aspec
))
7549 strcat (buf
, "enum ");
7550 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7553 strcat (buf
, "untagged enum");
7556 else if (TREE_CODE (aspec
) == TYPE_DECL
&& DECL_NAME (aspec
))
7557 strcat (buf
, IDENTIFIER_POINTER (DECL_NAME (aspec
)));
7559 else if (IS_ID (aspec
))
7561 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7566 tree chain
= protocol_list
;
7573 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7574 chain
= TREE_CHAIN (chain
);
7581 if (TREE_CHAIN (chain
))
7587 /* Type qualifiers. */
7588 if (TREE_READONLY (declspecs
))
7589 strcat (buf
, "const ");
7590 if (TYPE_VOLATILE (declspecs
))
7591 strcat (buf
, "volatile ");
7593 switch (TREE_CODE (declspecs
))
7595 /* Type specifiers. */
7598 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7600 /* Signed integer types. */
7602 if (declspecs
== short_integer_type_node
)
7603 strcat (buf
, "short int ");
7604 else if (declspecs
== integer_type_node
)
7605 strcat (buf
, "int ");
7606 else if (declspecs
== long_integer_type_node
)
7607 strcat (buf
, "long int ");
7608 else if (declspecs
== long_long_integer_type_node
)
7609 strcat (buf
, "long long int ");
7610 else if (declspecs
== signed_char_type_node
7611 || declspecs
== char_type_node
)
7612 strcat (buf
, "char ");
7614 /* Unsigned integer types. */
7616 else if (declspecs
== short_unsigned_type_node
)
7617 strcat (buf
, "unsigned short ");
7618 else if (declspecs
== unsigned_type_node
)
7619 strcat (buf
, "unsigned int ");
7620 else if (declspecs
== long_unsigned_type_node
)
7621 strcat (buf
, "unsigned long ");
7622 else if (declspecs
== long_long_unsigned_type_node
)
7623 strcat (buf
, "unsigned long long ");
7624 else if (declspecs
== unsigned_char_type_node
)
7625 strcat (buf
, "unsigned char ");
7629 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7631 if (declspecs
== float_type_node
)
7632 strcat (buf
, "float ");
7633 else if (declspecs
== double_type_node
)
7634 strcat (buf
, "double ");
7635 else if (declspecs
== long_double_type_node
)
7636 strcat (buf
, "long double ");
7640 if (TYPE_NAME (declspecs
)
7641 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7643 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7645 if (! TREE_STATIC_TEMPLATE (declspecs
))
7646 strcat (buf
, "struct ");
7647 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7651 tree chain
= protocol_list
;
7658 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7659 chain
= TREE_CHAIN (chain
);
7668 strcat (buf
, "untagged struct");
7674 if (TYPE_NAME (declspecs
)
7675 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7677 strcat (buf
, "union ");
7678 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7683 strcat (buf
, "untagged union ");
7687 if (TYPE_NAME (declspecs
)
7688 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7690 strcat (buf
, "enum ");
7691 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7696 strcat (buf
, "untagged enum ");
7700 strcat (buf
, "void ");
7705 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7710 tree chain
= protocol_list
;
7717 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7718 chain
= TREE_CHAIN (chain
);
7734 /* Given a tree node, produce a printable description of it in the given
7735 buffer, overwriting the buffer. */
7738 gen_declaration (atype_or_adecl
, buf
)
7739 tree atype_or_adecl
;
7743 gen_declaration_1 (atype_or_adecl
, buf
);
7747 /* Given a tree node, append a printable description to the end of the
7751 gen_declaration_1 (atype_or_adecl
, buf
)
7752 tree atype_or_adecl
;
7757 if (TREE_CODE (atype_or_adecl
) == TREE_LIST
)
7759 tree declspecs
; /* "identifier_node", "record_type" */
7760 tree declarator
; /* "array_ref", "indirect_ref", "call_expr"... */
7762 /* We have a "raw", abstract declarator (typename). */
7763 declarator
= TREE_VALUE (atype_or_adecl
);
7764 declspecs
= TREE_PURPOSE (atype_or_adecl
);
7766 gen_declspecs (declspecs
, buf
, 1);
7770 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7777 tree declspecs
; /* "integer_type", "real_type", "record_type"... */
7778 tree declarator
; /* "array_type", "function_type", "pointer_type". */
7780 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7781 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7782 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7783 atype
= TREE_TYPE (atype_or_adecl
);
7785 /* Assume we have a *_type node. */
7786 atype
= atype_or_adecl
;
7788 if (is_complex_decl (atype
))
7792 /* Get the declaration specifier; it is at the end of the list. */
7793 declarator
= chain
= atype
;
7795 chain
= TREE_TYPE (chain
); /* not TREE_CHAIN (chain); */
7796 while (is_complex_decl (chain
));
7803 declarator
= NULL_TREE
;
7806 gen_declspecs (declspecs
, buf
, 0);
7808 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7809 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7810 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7812 const char *const decl_name
=
7813 (DECL_NAME (atype_or_adecl
)
7814 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl
)) : "");
7819 strcat (buf
, gen_declarator (declarator
, declbuf
, decl_name
));
7822 else if (decl_name
[0])
7825 strcat (buf
, decl_name
);
7828 else if (declarator
)
7831 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7836 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7838 /* Given a method tree, put a printable description into the given
7839 buffer (overwriting) and return a pointer to the buffer. */
7842 gen_method_decl (method
, buf
)
7849 if (RAW_TYPESPEC (method
) != objc_object_reference
)
7852 gen_declaration_1 (TREE_TYPE (method
), buf
);
7856 chain
= METHOD_SEL_ARGS (method
);
7859 /* We have a chain of keyword_decls. */
7862 if (KEYWORD_KEY_NAME (chain
))
7863 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain
)));
7866 if (RAW_TYPESPEC (chain
) != objc_object_reference
)
7869 gen_declaration_1 (TREE_TYPE (chain
), buf
);
7873 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain
)));
7874 if ((chain
= TREE_CHAIN (chain
)))
7879 if (METHOD_ADD_ARGS (method
) == objc_ellipsis_node
)
7880 strcat (buf
, ", ...");
7881 else if (METHOD_ADD_ARGS (method
))
7883 /* We have a tree list node as generate by get_parm_info. */
7884 chain
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
7886 /* Know we have a chain of parm_decls. */
7890 gen_declaration_1 (chain
, buf
);
7891 chain
= TREE_CHAIN (chain
);
7897 /* We have a unary selector. */
7898 strcat (buf
, IDENTIFIER_POINTER (METHOD_SEL_NAME (method
)));
7906 dump_interface (fp
, chain
)
7910 char *buf
= (char *) xmalloc (256);
7911 const char *my_name
= IDENTIFIER_POINTER (CLASS_NAME (chain
));
7912 tree ivar_decls
= CLASS_RAW_IVARS (chain
);
7913 tree nst_methods
= CLASS_NST_METHODS (chain
);
7914 tree cls_methods
= CLASS_CLS_METHODS (chain
);
7916 fprintf (fp
, "\n@interface %s", my_name
);
7918 if (CLASS_SUPER_NAME (chain
))
7920 const char *super_name
= IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain
));
7921 fprintf (fp
, " : %s\n", super_name
);
7928 fprintf (fp
, "{\n");
7931 fprintf (fp
, "\t%s;\n", gen_declaration (ivar_decls
, buf
));
7932 ivar_decls
= TREE_CHAIN (ivar_decls
);
7935 fprintf (fp
, "}\n");
7940 fprintf (fp
, "- %s;\n", gen_method_decl (nst_methods
, buf
));
7941 nst_methods
= TREE_CHAIN (nst_methods
);
7946 fprintf (fp
, "+ %s;\n", gen_method_decl (cls_methods
, buf
));
7947 cls_methods
= TREE_CHAIN (cls_methods
);
7949 fprintf (fp
, "\n@end");
7952 /* Demangle function for Objective-C */
7954 objc_demangle (mangled
)
7955 const char *mangled
;
7957 char *demangled
, *cp
;
7959 if (mangled
[0] == '_' &&
7960 (mangled
[1] == 'i' || mangled
[1] == 'c') &&
7963 cp
= demangled
= xmalloc(strlen(mangled
) + 2);
7964 if (mangled
[1] == 'i')
7965 *cp
++ = '-'; /* for instance method */
7967 *cp
++ = '+'; /* for class method */
7968 *cp
++ = '['; /* opening left brace */
7969 strcpy(cp
, mangled
+3); /* tack on the rest of the mangled name */
7970 while (*cp
&& *cp
== '_')
7971 cp
++; /* skip any initial underbars in class name */
7972 cp
= strchr(cp
, '_'); /* find first non-initial underbar */
7975 free(demangled
); /* not mangled name */
7978 if (cp
[1] == '_') /* easy case: no category name */
7980 *cp
++ = ' '; /* replace two '_' with one ' ' */
7981 strcpy(cp
, mangled
+ (cp
- demangled
) + 2);
7985 *cp
++ = '('; /* less easy case: category name */
7986 cp
= strchr(cp
, '_');
7989 free(demangled
); /* not mangled name */
7993 *cp
++ = ' '; /* overwriting 1st char of method name... */
7994 strcpy(cp
, mangled
+ (cp
- demangled
)); /* get it back */
7996 while (*cp
&& *cp
== '_')
7997 cp
++; /* skip any initial underbars in method name */
8000 *cp
= ':'; /* replace remaining '_' with ':' */
8001 *cp
++ = ']'; /* closing right brace */
8002 *cp
++ = 0; /* string terminator */
8006 return mangled
; /* not an objc mangled name */
8010 objc_printable_name (decl
, kind
)
8012 int kind ATTRIBUTE_UNUSED
;
8014 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl
)));
8020 gcc_obstack_init (&util_obstack
);
8021 util_firstobj
= (char *) obstack_finish (&util_obstack
);
8023 errbuf
= (char *) xmalloc (BUFSIZE
);
8025 synth_module_prologue ();
8031 struct imp_entry
*impent
;
8033 /* The internally generated initializers appear to have missing braces.
8034 Don't warn about this. */
8035 int save_warn_missing_braces
= warn_missing_braces
;
8036 warn_missing_braces
= 0;
8038 /* A missing @end may not be detected by the parser. */
8039 if (objc_implementation_context
)
8041 warning ("`@end' missing in implementation context");
8042 finish_class (objc_implementation_context
);
8043 objc_ivar_chain
= NULL_TREE
;
8044 objc_implementation_context
= NULL_TREE
;
8047 generate_forward_declaration_to_string_table ();
8049 #ifdef OBJC_PROLOGUE
8053 /* Process the static instances here because initialization of objc_symtab
8055 if (objc_static_instances
)
8056 generate_static_references ();
8058 if (imp_list
|| class_names_chain
8059 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8060 generate_objc_symtab_decl ();
8062 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8064 objc_implementation_context
= impent
->imp_context
;
8065 implementation_template
= impent
->imp_template
;
8067 UOBJC_CLASS_decl
= impent
->class_decl
;
8068 UOBJC_METACLASS_decl
= impent
->meta_decl
;
8070 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
8072 /* all of the following reference the string pool... */
8073 generate_ivar_lists ();
8074 generate_dispatch_tables ();
8075 generate_shared_structures ();
8079 generate_dispatch_tables ();
8080 generate_category (objc_implementation_context
);
8084 /* If we are using an array of selectors, we must always
8085 finish up the array decl even if no selectors were used. */
8086 if (! flag_next_runtime
|| sel_ref_chain
)
8087 build_selector_translation_table ();
8090 generate_protocols ();
8092 if (objc_implementation_context
|| class_names_chain
|| objc_static_instances
8093 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8095 /* Arrange for ObjC data structures to be initialized at run time. */
8096 rtx init_sym
= build_module_descriptor ();
8097 if (init_sym
&& targetm
.have_ctors_dtors
)
8098 (* targetm
.asm_out
.constructor
) (init_sym
, DEFAULT_INIT_PRIORITY
);
8101 /* Dump the class references. This forces the appropriate classes
8102 to be linked into the executable image, preserving unix archive
8103 semantics. This can be removed when we move to a more dynamically
8104 linked environment. */
8106 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
8108 handle_class_ref (chain
);
8109 if (TREE_PURPOSE (chain
))
8110 generate_classref_translation_entry (chain
);
8113 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8114 handle_impent (impent
);
8116 /* Dump the string table last. */
8118 generate_strings ();
8120 if (flag_gen_declaration
)
8122 add_class (objc_implementation_context
);
8123 dump_interface (gen_declaration_file
, objc_implementation_context
);
8131 /* Run through the selector hash tables and print a warning for any
8132 selector which has multiple methods. */
8134 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8135 for (hsh
= cls_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8138 tree meth
= hsh
->key
;
8139 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8143 warning ("potential selector conflict for method `%s'",
8144 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8145 warn_with_method ("found", type
, meth
);
8146 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8147 warn_with_method ("found", type
, loop
->value
);
8150 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8151 for (hsh
= nst_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8154 tree meth
= hsh
->key
;
8155 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8159 warning ("potential selector conflict for method `%s'",
8160 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8161 warn_with_method ("found", type
, meth
);
8162 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8163 warn_with_method ("found", type
, loop
->value
);
8167 warn_missing_braces
= save_warn_missing_braces
;
8170 /* Subroutines of finish_objc. */
8173 generate_classref_translation_entry (chain
)
8176 tree expr
, name
, decl_specs
, decl
, sc_spec
;
8179 type
= TREE_TYPE (TREE_PURPOSE (chain
));
8181 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
8182 expr
= build_c_cast (type
, expr
); /* cast! */
8184 name
= DECL_NAME (TREE_PURPOSE (chain
));
8186 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
8188 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8189 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
8191 /* The decl that is returned from start_decl is the one that we
8192 forward declared in build_class_reference. */
8193 decl
= start_decl (name
, decl_specs
, 1, NULL_TREE
);
8194 DECL_CONTEXT (decl
) = NULL_TREE
;
8195 finish_decl (decl
, expr
, NULL_TREE
);
8200 handle_class_ref (chain
)
8203 const char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
8204 char *string
= (char *) alloca (strlen (name
) + 30);
8208 sprintf (string
, "%sobjc_class_name_%s",
8209 (flag_next_runtime
? "." : "__"), name
);
8211 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8212 if (flag_next_runtime
)
8214 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file
, string
);
8219 /* Make a decl for this name, so we can use its address in a tree. */
8220 decl
= build_decl (VAR_DECL
, get_identifier (string
), char_type_node
);
8221 DECL_EXTERNAL (decl
) = 1;
8222 TREE_PUBLIC (decl
) = 1;
8225 rest_of_decl_compilation (decl
, 0, 0, 0);
8227 /* Make a decl for the address. */
8228 sprintf (string
, "%sobjc_class_ref_%s",
8229 (flag_next_runtime
? "." : "__"), name
);
8230 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
8231 decl
= build_decl (VAR_DECL
, get_identifier (string
), string_type_node
);
8232 DECL_INITIAL (decl
) = exp
;
8233 TREE_STATIC (decl
) = 1;
8234 TREE_USED (decl
) = 1;
8237 rest_of_decl_compilation (decl
, 0, 0, 0);
8241 handle_impent (impent
)
8242 struct imp_entry
*impent
;
8246 objc_implementation_context
= impent
->imp_context
;
8247 implementation_template
= impent
->imp_template
;
8249 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
8251 const char *const class_name
=
8252 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8254 string
= (char *) alloca (strlen (class_name
) + 30);
8256 sprintf (string
, "%sobjc_class_name_%s",
8257 (flag_next_runtime
? "." : "__"), class_name
);
8259 else if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
8261 const char *const class_name
=
8262 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8263 const char *const class_super_name
=
8264 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
8266 string
= (char *) alloca (strlen (class_name
)
8267 + strlen (class_super_name
) + 30);
8269 /* Do the same for categories. Even though no references to
8270 these symbols are generated automatically by the compiler, it
8271 gives you a handle to pull them into an archive by hand. */
8272 sprintf (string
, "*%sobjc_category_name_%s_%s",
8273 (flag_next_runtime
? "." : "__"), class_name
, class_super_name
);
8278 #ifdef ASM_DECLARE_CLASS_REFERENCE
8279 if (flag_next_runtime
)
8281 ASM_DECLARE_CLASS_REFERENCE (asm_out_file
, string
);
8289 init
= build_int_2 (0, 0);
8290 TREE_TYPE (init
) = c_common_type_for_size (BITS_PER_WORD
, 1);
8291 decl
= build_decl (VAR_DECL
, get_identifier (string
), TREE_TYPE (init
));
8292 TREE_PUBLIC (decl
) = 1;
8293 TREE_READONLY (decl
) = 1;
8294 TREE_USED (decl
) = 1;
8295 TREE_CONSTANT (decl
) = 1;
8296 DECL_CONTEXT (decl
) = 0;
8297 DECL_ARTIFICIAL (decl
) = 1;
8298 DECL_INITIAL (decl
) = init
;
8299 assemble_variable (decl
, 1, 0, 0);
8303 /* Look up ID as an instance variable. */
8305 lookup_objc_ivar (id
)
8310 if (objc_receiver_context
&& !strcmp (IDENTIFIER_POINTER (id
), "super"))
8311 /* we have a message to super */
8312 return get_super_receiver ();
8313 else if (objc_method_context
&& (decl
= is_ivar (objc_ivar_chain
, id
)))
8315 if (is_private (decl
))
8316 return error_mark_node
;
8318 return build_ivar_reference (id
);
8324 #include "gtype-objc.h"