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 /* This obstack is used to accumulate the encoding of a data type. */
94 static struct obstack util_obstack
;
95 /* This points to the beginning of obstack contents,
96 so we can free the whole contents. */
99 /* for encode_method_def */
102 /* The version identifies which language generation and runtime
103 the module (file) was compiled for, and is recorded in the
104 module descriptor. */
106 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
107 #define PROTOCOL_VERSION 2
109 /* (Decide if these can ever be validly changed.) */
110 #define OBJC_ENCODE_INLINE_DEFS 0
111 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
113 /*** Private Interface (procedures) ***/
115 /* Used by compile_file. */
117 static void init_objc
PARAMS ((void));
118 static void finish_objc
PARAMS ((void));
120 /* Code generation. */
122 static void synth_module_prologue
PARAMS ((void));
123 static tree build_constructor
PARAMS ((tree
, tree
));
124 static rtx build_module_descriptor
PARAMS ((void));
125 static tree init_module_descriptor
PARAMS ((tree
));
126 static tree build_objc_method_call
PARAMS ((int, tree
, tree
,
128 static void generate_strings
PARAMS ((void));
129 static tree get_proto_encoding
PARAMS ((tree
));
130 static void build_selector_translation_table
PARAMS ((void));
131 static tree build_ivar_chain
PARAMS ((tree
, int));
133 static tree objc_add_static_instance
PARAMS ((tree
, tree
));
135 static tree build_ivar_template
PARAMS ((void));
136 static tree build_method_template
PARAMS ((void));
137 static tree build_private_template
PARAMS ((tree
));
138 static void build_class_template
PARAMS ((void));
139 static void build_selector_template
PARAMS ((void));
140 static void build_category_template
PARAMS ((void));
141 static tree build_super_template
PARAMS ((void));
142 static tree build_category_initializer
PARAMS ((tree
, tree
, tree
,
144 static tree build_protocol_initializer
PARAMS ((tree
, tree
, tree
,
147 static void synth_forward_declarations
PARAMS ((void));
148 static void generate_ivar_lists
PARAMS ((void));
149 static void generate_dispatch_tables
PARAMS ((void));
150 static void generate_shared_structures
PARAMS ((void));
151 static tree generate_protocol_list
PARAMS ((tree
));
152 static void generate_forward_declaration_to_string_table
PARAMS ((void));
153 static void build_protocol_reference
PARAMS ((tree
));
155 static tree build_keyword_selector
PARAMS ((tree
));
156 static tree synth_id_with_class_suffix
PARAMS ((const char *, tree
));
158 static void generate_static_references
PARAMS ((void));
159 static int check_methods_accessible
PARAMS ((tree
, tree
,
161 static void encode_aggregate_within
PARAMS ((tree
, int, int,
163 static const char *objc_demangle
PARAMS ((const char *));
164 static void objc_expand_function_end
PARAMS ((void));
166 /* Hash tables to manage the global pool of method prototypes. */
168 hash
*nst_method_hash_list
= 0;
169 hash
*cls_method_hash_list
= 0;
171 static size_t hash_func
PARAMS ((tree
));
172 static void hash_init
PARAMS ((void));
173 static void hash_enter
PARAMS ((hash
*, tree
));
174 static hash hash_lookup
PARAMS ((hash
*, tree
));
175 static void hash_add_attr
PARAMS ((hash
, tree
));
176 static tree lookup_method
PARAMS ((tree
, tree
));
177 static tree lookup_instance_method_static
PARAMS ((tree
, tree
));
178 static tree lookup_class_method_static
PARAMS ((tree
, tree
));
179 static tree add_class
PARAMS ((tree
));
180 static void add_category
PARAMS ((tree
, tree
));
184 class_names
, /* class, category, protocol, module names */
185 meth_var_names
, /* method and variable names */
186 meth_var_types
/* method and variable type descriptors */
189 static tree add_objc_string
PARAMS ((tree
,
190 enum string_section
));
191 static tree get_objc_string_decl
PARAMS ((tree
,
192 enum string_section
));
193 static tree build_objc_string_decl
PARAMS ((enum string_section
));
194 static tree build_selector_reference_decl
PARAMS ((void));
196 /* Protocol additions. */
198 static tree add_protocol
PARAMS ((tree
));
199 static tree lookup_protocol
PARAMS ((tree
));
200 static void check_protocol_recursively
PARAMS ((tree
, tree
));
201 static tree lookup_and_install_protocols
PARAMS ((tree
));
205 static void encode_type_qualifiers
PARAMS ((tree
));
206 static void encode_pointer
PARAMS ((tree
, int, int));
207 static void encode_array
PARAMS ((tree
, int, int));
208 static void encode_aggregate
PARAMS ((tree
, int, int));
209 static void encode_bitfield
PARAMS ((int));
210 static void encode_type
PARAMS ((tree
, int, int));
211 static void encode_field_decl
PARAMS ((tree
, int, int));
213 static void really_start_method
PARAMS ((tree
, tree
));
214 static int comp_method_with_proto
PARAMS ((tree
, tree
));
215 static int comp_proto_with_proto
PARAMS ((tree
, tree
));
216 static tree get_arg_type_list
PARAMS ((tree
, int, int));
217 static tree expr_last
PARAMS ((tree
));
219 /* Utilities for debugging and error diagnostics. */
221 static void warn_with_method
PARAMS ((const char *, int, tree
));
222 static void error_with_ivar
PARAMS ((const char *, tree
, tree
));
223 static char *gen_method_decl
PARAMS ((tree
, char *));
224 static char *gen_declaration
PARAMS ((tree
, char *));
225 static void gen_declaration_1
PARAMS ((tree
, char *));
226 static char *gen_declarator
PARAMS ((tree
, char *,
228 static int is_complex_decl
PARAMS ((tree
));
229 static void adorn_decl
PARAMS ((tree
, char *));
230 static void dump_interface
PARAMS ((FILE *, tree
));
232 /* Everything else. */
234 static tree define_decl
PARAMS ((tree
, tree
));
235 static tree lookup_method_in_protocol_list
PARAMS ((tree
, tree
, int));
236 static tree lookup_protocol_in_reflist
PARAMS ((tree
, tree
));
237 static tree create_builtin_decl
PARAMS ((enum tree_code
,
238 tree
, const char *));
239 static void setup_string_decl
PARAMS ((void));
240 static void build_string_class_template
PARAMS ((void));
241 static tree my_build_string
PARAMS ((int, const char *));
242 static void build_objc_symtab_template
PARAMS ((void));
243 static tree init_def_list
PARAMS ((tree
));
244 static tree init_objc_symtab
PARAMS ((tree
));
245 static void forward_declare_categories
PARAMS ((void));
246 static void generate_objc_symtab_decl
PARAMS ((void));
247 static tree build_selector
PARAMS ((tree
));
248 static tree build_typed_selector_reference
PARAMS ((tree
, tree
));
249 static tree build_selector_reference
PARAMS ((tree
));
250 static tree build_class_reference_decl
PARAMS ((void));
251 static void add_class_reference
PARAMS ((tree
));
252 static tree objc_copy_list
PARAMS ((tree
, tree
*));
253 static tree build_protocol_template
PARAMS ((void));
254 static tree build_descriptor_table_initializer
PARAMS ((tree
, tree
));
255 static tree build_method_prototype_list_template
PARAMS ((tree
, int));
256 static tree build_method_prototype_template
PARAMS ((void));
257 static int forwarding_offset
PARAMS ((tree
));
258 static tree encode_method_prototype
PARAMS ((tree
, tree
));
259 static tree generate_descriptor_table
PARAMS ((tree
, const char *,
261 static void generate_method_descriptors
PARAMS ((tree
));
262 static tree build_tmp_function_decl
PARAMS ((void));
263 static void hack_method_prototype
PARAMS ((tree
, tree
));
264 static void generate_protocol_references
PARAMS ((tree
));
265 static void generate_protocols
PARAMS ((void));
266 static void check_ivars
PARAMS ((tree
, tree
));
267 static tree build_ivar_list_template
PARAMS ((tree
, int));
268 static tree build_method_list_template
PARAMS ((tree
, int));
269 static tree build_ivar_list_initializer
PARAMS ((tree
, tree
));
270 static tree generate_ivars_list
PARAMS ((tree
, const char *,
272 static tree build_dispatch_table_initializer
PARAMS ((tree
, tree
));
273 static tree generate_dispatch_table
PARAMS ((tree
, const char *,
275 static tree build_shared_structure_initializer
PARAMS ((tree
, tree
, tree
, tree
,
276 tree
, int, tree
, tree
,
278 static void generate_category
PARAMS ((tree
));
279 static int is_objc_type_qualifier
PARAMS ((tree
));
280 static tree adjust_type_for_id_default
PARAMS ((tree
));
281 static tree check_duplicates
PARAMS ((hash
));
282 static tree receiver_is_class_object
PARAMS ((tree
));
283 static int check_methods
PARAMS ((tree
, tree
, int));
284 static int conforms_to_protocol
PARAMS ((tree
, tree
));
285 static void check_protocol
PARAMS ((tree
, const char *,
287 static void check_protocols
PARAMS ((tree
, const char *,
289 static tree encode_method_def
PARAMS ((tree
));
290 static void gen_declspecs
PARAMS ((tree
, char *, int));
291 static void generate_classref_translation_entry
PARAMS ((tree
));
292 static void handle_class_ref
PARAMS ((tree
));
293 static void generate_struct_by_value_array
PARAMS ((void))
295 static void encode_complete_bitfield
PARAMS ((int, tree
, int));
297 /*** Private Interface (data) ***/
299 /* Reserved tag definitions. */
302 #define TAG_OBJECT "objc_object"
303 #define TAG_CLASS "objc_class"
304 #define TAG_SUPER "objc_super"
305 #define TAG_SELECTOR "objc_selector"
307 #define UTAG_CLASS "_objc_class"
308 #define UTAG_IVAR "_objc_ivar"
309 #define UTAG_IVAR_LIST "_objc_ivar_list"
310 #define UTAG_METHOD "_objc_method"
311 #define UTAG_METHOD_LIST "_objc_method_list"
312 #define UTAG_CATEGORY "_objc_category"
313 #define UTAG_MODULE "_objc_module"
314 #define UTAG_SYMTAB "_objc_symtab"
315 #define UTAG_SUPER "_objc_super"
316 #define UTAG_SELECTOR "_objc_selector"
318 #define UTAG_PROTOCOL "_objc_protocol"
319 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
320 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
322 /* Note that the string object global name is only needed for the
324 #define STRING_OBJECT_GLOBAL_NAME "_NSConstantStringClassReference"
326 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
328 static const char *TAG_GETCLASS
;
329 static const char *TAG_GETMETACLASS
;
330 static const char *TAG_MSGSEND
;
331 static const char *TAG_MSGSENDSUPER
;
332 static const char *TAG_EXECCLASS
;
333 static const char *default_constant_string_class_name
;
335 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
336 tree objc_global_trees
[OCTI_MAX
];
338 static void handle_impent
PARAMS ((struct imp_entry
*));
340 struct imp_entry
*imp_list
= 0;
341 int imp_count
= 0; /* `@implementation' */
342 int cat_count
= 0; /* `@category' */
344 static int method_slot
= 0; /* Used by start_method_def, */
348 static char *errbuf
; /* Buffer for error diagnostics */
350 /* Data imported from tree.c. */
352 extern enum debug_info_type write_symbols
;
354 /* Data imported from toplev.c. */
356 extern const char *dump_base_name
;
358 static int flag_typed_selectors
;
360 FILE *gen_declaration_file
;
362 /* Tells "encode_pointer/encode_aggregate" whether we are generating
363 type descriptors for instance variables (as opposed to methods).
364 Type descriptors for instance variables contain more information
365 than methods (for static typing and embedded structures). */
367 static int generating_instance_variables
= 0;
369 /* Some platforms pass small structures through registers versus
370 through an invisible pointer. Determine at what size structure is
371 the transition point between the two possibilities. */
374 generate_struct_by_value_array ()
377 tree field_decl
, field_decl_chain
;
379 int aggregate_in_mem
[32];
382 /* Presumably no platform passes 32 byte structures in a register. */
383 for (i
= 1; i
< 32; i
++)
387 /* Create an unnamed struct that has `i' character components */
388 type
= start_struct (RECORD_TYPE
, NULL_TREE
);
390 strcpy (buffer
, "c1");
391 field_decl
= create_builtin_decl (FIELD_DECL
,
394 field_decl_chain
= field_decl
;
396 for (j
= 1; j
< i
; j
++)
398 sprintf (buffer
, "c%d", j
+ 1);
399 field_decl
= create_builtin_decl (FIELD_DECL
,
402 chainon (field_decl_chain
, field_decl
);
404 finish_struct (type
, field_decl_chain
, NULL_TREE
);
406 aggregate_in_mem
[i
] = aggregate_value_p (type
);
407 if (!aggregate_in_mem
[i
])
411 /* We found some structures that are returned in registers instead of memory
412 so output the necessary data. */
415 for (i
= 31; i
>= 0; i
--)
416 if (!aggregate_in_mem
[i
])
418 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i
);
420 /* The first member of the structure is always 0 because we don't handle
421 structures with 0 members */
422 printf ("static int struct_forward_array[] = {\n 0");
424 for (j
= 1; j
<= i
; j
++)
425 printf (", %d", aggregate_in_mem
[j
]);
434 const char *filename
;
436 filename
= c_objc_common_init (filename
);
437 if (filename
== NULL
)
440 /* Force the line number back to 0; check_newline will have
441 raised it to 1, which will make the builtin functions appear
442 not to be built in. */
445 /* If gen_declaration desired, open the output file. */
446 if (flag_gen_declaration
)
448 register char * const dumpname
= concat (dump_base_name
, ".decl", NULL
);
449 gen_declaration_file
= fopen (dumpname
, "w");
450 if (gen_declaration_file
== 0)
451 fatal_io_error ("can't open %s", dumpname
);
455 if (flag_next_runtime
)
457 TAG_GETCLASS
= "objc_getClass";
458 TAG_GETMETACLASS
= "objc_getMetaClass";
459 TAG_MSGSEND
= "objc_msgSend";
460 TAG_MSGSENDSUPER
= "objc_msgSendSuper";
461 TAG_EXECCLASS
= "__objc_execClass";
462 default_constant_string_class_name
= "NSConstantString";
466 TAG_GETCLASS
= "objc_get_class";
467 TAG_GETMETACLASS
= "objc_get_meta_class";
468 TAG_MSGSEND
= "objc_msg_lookup";
469 TAG_MSGSENDSUPER
= "objc_msg_lookup_super";
470 TAG_EXECCLASS
= "__objc_exec_class";
471 default_constant_string_class_name
= "NXConstantString";
472 flag_typed_selectors
= 1;
475 objc_ellipsis_node
= make_node (ERROR_MARK
);
479 if (print_struct_values
)
480 generate_struct_by_value_array ();
488 c_objc_common_finish_file ();
490 /* Finalize Objective-C runtime data. No need to generate tables
491 and code if only checking syntax. */
492 if (!flag_syntax_only
)
495 if (gen_declaration_file
)
496 fclose (gen_declaration_file
);
500 define_decl (declarator
, declspecs
)
504 tree decl
= start_decl (declarator
, declspecs
, 0, NULL_TREE
);
505 finish_decl (decl
, NULL_TREE
, NULL_TREE
);
509 /* Return 1 if LHS and RHS are compatible types for assignment or
510 various other operations. Return 0 if they are incompatible, and
511 return -1 if we choose to not decide. When the operation is
512 REFLEXIVE, check for compatibility in either direction.
514 For statically typed objects, an assignment of the form `a' = `b'
518 `a' and `b' are the same class type, or
519 `a' and `b' are of class types A and B such that B is a descendant of A. */
522 maybe_objc_comptypes (lhs
, rhs
, reflexive
)
526 return objc_comptypes (lhs
, rhs
, reflexive
);
530 lookup_method_in_protocol_list (rproto_list
, sel_name
, class_meth
)
538 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
540 p
= TREE_VALUE (rproto
);
542 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
544 if ((fnd
= lookup_method (class_meth
545 ? PROTOCOL_CLS_METHODS (p
)
546 : PROTOCOL_NST_METHODS (p
), sel_name
)))
548 else if (PROTOCOL_LIST (p
))
549 fnd
= lookup_method_in_protocol_list (PROTOCOL_LIST (p
),
550 sel_name
, class_meth
);
554 ; /* An identifier...if we could not find a protocol. */
565 lookup_protocol_in_reflist (rproto_list
, lproto
)
571 /* Make sure the protocol is supported by the object on the rhs. */
572 if (TREE_CODE (lproto
) == PROTOCOL_INTERFACE_TYPE
)
575 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
577 p
= TREE_VALUE (rproto
);
579 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
584 else if (PROTOCOL_LIST (p
))
585 fnd
= lookup_protocol_in_reflist (PROTOCOL_LIST (p
), lproto
);
594 ; /* An identifier...if we could not find a protocol. */
600 /* Return 1 if LHS and RHS are compatible types for assignment
601 or various other operations. Return 0 if they are incompatible,
602 and return -1 if we choose to not decide. When the operation
603 is REFLEXIVE, check for compatibility in either direction. */
606 objc_comptypes (lhs
, rhs
, reflexive
)
611 /* New clause for protocols. */
613 if (TREE_CODE (lhs
) == POINTER_TYPE
614 && TREE_CODE (TREE_TYPE (lhs
)) == RECORD_TYPE
615 && TREE_CODE (rhs
) == POINTER_TYPE
616 && TREE_CODE (TREE_TYPE (rhs
)) == RECORD_TYPE
)
618 int lhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (lhs
);
619 int rhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (rhs
);
623 tree lproto
, lproto_list
= TYPE_PROTOCOL_LIST (lhs
);
624 tree rproto
, rproto_list
;
629 rproto_list
= TYPE_PROTOCOL_LIST (rhs
);
631 /* Make sure the protocol is supported by the object
633 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
635 p
= TREE_VALUE (lproto
);
636 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
639 warning ("object does not conform to the `%s' protocol",
640 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
643 else if (TYPED_OBJECT (TREE_TYPE (rhs
)))
645 tree rname
= TYPE_NAME (TREE_TYPE (rhs
));
648 /* Make sure the protocol is supported by the object
650 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
652 p
= TREE_VALUE (lproto
);
654 rinter
= lookup_interface (rname
);
656 while (rinter
&& !rproto
)
660 rproto_list
= CLASS_PROTOCOL_LIST (rinter
);
661 /* If the underlying ObjC class does not have
662 protocols attached to it, perhaps there are
663 "one-off" protocols attached to the rhs?
664 E.g., 'id<MyProt> foo;'. */
666 rproto_list
= TYPE_PROTOCOL_LIST (TREE_TYPE (rhs
));
667 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
669 /* Check for protocols adopted by categories. */
670 cat
= CLASS_CATEGORY_LIST (rinter
);
671 while (cat
&& !rproto
)
673 rproto_list
= CLASS_PROTOCOL_LIST (cat
);
674 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
676 cat
= CLASS_CATEGORY_LIST (cat
);
679 rinter
= lookup_interface (CLASS_SUPER_NAME (rinter
));
683 warning ("class `%s' does not implement the `%s' protocol",
684 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs
))),
685 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
689 /* May change...based on whether there was any mismatch */
692 else if (rhs_is_proto
)
693 /* Lhs is not a protocol...warn if it is statically typed */
694 return (TYPED_OBJECT (TREE_TYPE (lhs
)) != 0);
697 /* Defer to comptypes. */
701 else if (TREE_CODE (lhs
) == RECORD_TYPE
&& TREE_CODE (rhs
) == RECORD_TYPE
)
702 ; /* Fall thru. This is the case we have been handling all along */
704 /* Defer to comptypes. */
707 /* `id' = `<class> *', `<class> *' = `id' */
709 if ((TYPE_NAME (lhs
) == objc_object_id
&& TYPED_OBJECT (rhs
))
710 || (TYPE_NAME (rhs
) == objc_object_id
&& TYPED_OBJECT (lhs
)))
713 /* `id' = `Class', `Class' = `id' */
715 else if ((TYPE_NAME (lhs
) == objc_object_id
716 && TYPE_NAME (rhs
) == objc_class_id
)
717 || (TYPE_NAME (lhs
) == objc_class_id
718 && TYPE_NAME (rhs
) == objc_object_id
))
721 /* `<class> *' = `<class> *' */
723 else if (TYPED_OBJECT (lhs
) && TYPED_OBJECT (rhs
))
725 tree lname
= TYPE_NAME (lhs
);
726 tree rname
= TYPE_NAME (rhs
);
732 /* If the left hand side is a super class of the right hand side,
734 for (inter
= lookup_interface (rname
); inter
;
735 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
736 if (lname
== CLASS_SUPER_NAME (inter
))
739 /* Allow the reverse when reflexive. */
741 for (inter
= lookup_interface (lname
); inter
;
742 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
743 if (rname
== CLASS_SUPER_NAME (inter
))
749 /* Defer to comptypes. */
753 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
756 objc_check_decl (decl
)
759 tree type
= TREE_TYPE (decl
);
761 if (TREE_CODE (type
) == RECORD_TYPE
762 && TREE_STATIC_TEMPLATE (type
)
763 && type
!= constant_string_type
)
764 error_with_decl (decl
, "`%s' cannot be statically allocated");
768 maybe_objc_check_decl (decl
)
771 objc_check_decl (decl
);
774 /* Implement static typing. At this point, we know we have an interface. */
777 get_static_reference (interface
, protocols
)
781 tree type
= xref_tag (RECORD_TYPE
, interface
);
785 tree t
, m
= TYPE_MAIN_VARIANT (type
);
787 t
= copy_node (type
);
788 TYPE_BINFO (t
) = make_tree_vec (2);
790 /* Add this type to the chain of variants of TYPE. */
791 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
792 TYPE_NEXT_VARIANT (m
) = t
;
794 /* Look up protocols and install in lang specific list. Note
795 that the protocol list can have a different lifetime than T! */
796 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
798 /* This forces a new pointer type to be created later
799 (in build_pointer_type)...so that the new template
800 we just created will actually be used...what a hack! */
801 if (TYPE_POINTER_TO (t
))
802 TYPE_POINTER_TO (t
) = NULL_TREE
;
811 get_object_reference (protocols
)
814 tree type_decl
= lookup_name (objc_id_id
);
817 if (type_decl
&& TREE_CODE (type_decl
) == TYPE_DECL
)
819 type
= TREE_TYPE (type_decl
);
820 if (TYPE_MAIN_VARIANT (type
) != id_type
)
821 warning ("unexpected type for `id' (%s)",
822 gen_declaration (type
, errbuf
));
826 error ("undefined type `id', please import <objc/objc.h>");
827 return error_mark_node
;
830 /* This clause creates a new pointer type that is qualified with
831 the protocol specification...this info is used later to do more
832 elaborate type checking. */
836 tree t
, m
= TYPE_MAIN_VARIANT (type
);
838 t
= copy_node (type
);
839 TYPE_BINFO (t
) = make_tree_vec (2);
841 /* Add this type to the chain of variants of TYPE. */
842 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
843 TYPE_NEXT_VARIANT (m
) = t
;
845 /* Look up protocols...and install in lang specific list */
846 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
848 /* This forces a new pointer type to be created later
849 (in build_pointer_type)...so that the new template
850 we just created will actually be used...what a hack! */
851 if (TYPE_POINTER_TO (t
))
852 TYPE_POINTER_TO (t
) = NULL_TREE
;
859 /* Check for circular dependencies in protocols. The arguments are
860 PROTO, the protocol to check, and LIST, a list of protocol it
864 check_protocol_recursively (proto
, list
)
870 for (p
= list
; p
; p
= TREE_CHAIN (p
))
872 tree pp
= TREE_VALUE (p
);
874 if (TREE_CODE (pp
) == IDENTIFIER_NODE
)
875 pp
= lookup_protocol (pp
);
878 fatal_error ("protocol `%s' has circular dependency",
879 IDENTIFIER_POINTER (PROTOCOL_NAME (pp
)));
881 check_protocol_recursively (proto
, PROTOCOL_LIST (pp
));
886 lookup_and_install_protocols (protocols
)
891 tree return_value
= protocols
;
893 for (proto
= protocols
; proto
; proto
= TREE_CHAIN (proto
))
895 tree ident
= TREE_VALUE (proto
);
896 tree p
= lookup_protocol (ident
);
900 error ("cannot find protocol declaration for `%s'",
901 IDENTIFIER_POINTER (ident
));
903 TREE_CHAIN (prev
) = TREE_CHAIN (proto
);
905 return_value
= TREE_CHAIN (proto
);
909 /* Replace identifier with actual protocol node. */
910 TREE_VALUE (proto
) = p
;
918 /* Create and push a decl for a built-in external variable or field NAME.
920 TYPE is its data type. */
923 create_builtin_decl (code
, type
, name
)
928 tree decl
= build_decl (code
, get_identifier (name
), type
);
930 if (code
== VAR_DECL
)
932 TREE_STATIC (decl
) = 1;
933 make_decl_rtl (decl
, 0);
937 DECL_ARTIFICIAL (decl
) = 1;
941 /* Find the decl for the constant string class. */
946 if (!string_class_decl
)
948 if (!constant_string_global_id
)
949 constant_string_global_id
= get_identifier (STRING_OBJECT_GLOBAL_NAME
);
950 string_class_decl
= lookup_name (constant_string_global_id
);
954 /* Purpose: "play" parser, creating/installing representations
955 of the declarations that are required by Objective-C.
959 type_spec--------->sc_spec
960 (tree_list) (tree_list)
963 identifier_node identifier_node */
966 synth_module_prologue ()
971 /* Defined in `objc.h' */
972 objc_object_id
= get_identifier (TAG_OBJECT
);
974 objc_object_reference
= xref_tag (RECORD_TYPE
, objc_object_id
);
976 id_type
= build_pointer_type (objc_object_reference
);
978 objc_id_id
= get_identifier (TYPE_ID
);
979 objc_class_id
= get_identifier (TAG_CLASS
);
981 objc_class_type
= build_pointer_type (xref_tag (RECORD_TYPE
, objc_class_id
));
982 protocol_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
983 get_identifier (PROTOCOL_OBJECT_CLASS_NAME
)));
985 /* Declare type of selector-objects that represent an operation name. */
987 /* `struct objc_selector *' */
989 = build_pointer_type (xref_tag (RECORD_TYPE
,
990 get_identifier (TAG_SELECTOR
)));
992 /* Forward declare type, or else the prototype for msgSendSuper will
995 super_p
= build_pointer_type (xref_tag (RECORD_TYPE
,
996 get_identifier (TAG_SUPER
)));
999 /* id objc_msgSend (id, SEL, ...); */
1002 = build_function_type (id_type
,
1003 tree_cons (NULL_TREE
, id_type
,
1004 tree_cons (NULL_TREE
, selector_type
,
1007 if (! flag_next_runtime
)
1009 umsg_decl
= build_decl (FUNCTION_DECL
,
1010 get_identifier (TAG_MSGSEND
), temp_type
);
1011 DECL_EXTERNAL (umsg_decl
) = 1;
1012 TREE_PUBLIC (umsg_decl
) = 1;
1013 DECL_INLINE (umsg_decl
) = 1;
1014 DECL_ARTIFICIAL (umsg_decl
) = 1;
1016 make_decl_rtl (umsg_decl
, NULL
);
1017 pushdecl (umsg_decl
);
1020 umsg_decl
= builtin_function (TAG_MSGSEND
, temp_type
, 0, NOT_BUILT_IN
,
1023 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1026 = build_function_type (id_type
,
1027 tree_cons (NULL_TREE
, super_p
,
1028 tree_cons (NULL_TREE
, selector_type
,
1031 umsg_super_decl
= builtin_function (TAG_MSGSENDSUPER
,
1032 temp_type
, 0, NOT_BUILT_IN
,
1035 /* id objc_getClass (const char *); */
1037 temp_type
= build_function_type (id_type
,
1038 tree_cons (NULL_TREE
,
1039 const_string_type_node
,
1040 tree_cons (NULL_TREE
, void_type_node
,
1044 = builtin_function (TAG_GETCLASS
, temp_type
, 0, NOT_BUILT_IN
,
1047 /* id objc_getMetaClass (const char *); */
1049 objc_get_meta_class_decl
1050 = builtin_function (TAG_GETMETACLASS
, temp_type
, 0, NOT_BUILT_IN
,
1053 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1055 if (! flag_next_runtime
)
1057 if (flag_typed_selectors
)
1059 /* Suppress outputting debug symbols, because
1060 dbxout_init hasn'r been called yet. */
1061 enum debug_info_type save_write_symbols
= write_symbols
;
1062 const struct gcc_debug_hooks
*const save_hooks
= debug_hooks
;
1063 write_symbols
= NO_DEBUG
;
1064 debug_hooks
= &do_nothing_debug_hooks
;
1066 build_selector_template ();
1067 temp_type
= build_array_type (objc_selector_template
, NULL_TREE
);
1069 write_symbols
= save_write_symbols
;
1070 debug_hooks
= save_hooks
;
1073 temp_type
= build_array_type (selector_type
, NULL_TREE
);
1075 layout_type (temp_type
);
1076 UOBJC_SELECTOR_TABLE_decl
1077 = create_builtin_decl (VAR_DECL
, temp_type
,
1078 "_OBJC_SELECTOR_TABLE");
1080 /* Avoid warning when not sending messages. */
1081 TREE_USED (UOBJC_SELECTOR_TABLE_decl
) = 1;
1084 generate_forward_declaration_to_string_table ();
1086 /* Forward declare constant_string_id and constant_string_type. */
1087 if (!constant_string_class_name
)
1088 constant_string_class_name
= default_constant_string_class_name
;
1090 constant_string_id
= get_identifier (constant_string_class_name
);
1091 constant_string_type
= xref_tag (RECORD_TYPE
, constant_string_id
);
1094 /* Predefine the following data type:
1096 struct STRING_OBJECT_CLASS_NAME
1100 unsigned int length;
1104 build_string_class_template ()
1106 tree field_decl
, field_decl_chain
;
1108 field_decl
= create_builtin_decl (FIELD_DECL
, id_type
, "isa");
1109 field_decl_chain
= field_decl
;
1111 field_decl
= create_builtin_decl (FIELD_DECL
,
1112 build_pointer_type (char_type_node
),
1114 chainon (field_decl_chain
, field_decl
);
1116 field_decl
= create_builtin_decl (FIELD_DECL
, unsigned_type_node
, "length");
1117 chainon (field_decl_chain
, field_decl
);
1119 finish_struct (constant_string_type
, field_decl_chain
, NULL_TREE
);
1122 /* Custom build_string which sets TREE_TYPE! */
1125 my_build_string (len
, str
)
1129 return fix_string_type (build_string (len
, str
));
1132 /* Given a chain of STRING_CST's, build a static instance of
1133 NXConstantString which points at the concatenation of those strings.
1134 We place the string object in the __string_objects section of the
1135 __OBJC segment. The Objective-C runtime will initialize the isa
1136 pointers of the string objects to point at the NXConstantString
1140 build_objc_string_object (strings
)
1143 tree string
, initlist
, constructor
;
1146 if (lookup_interface (constant_string_id
) == NULL_TREE
)
1148 error ("cannot find interface declaration for `%s'",
1149 IDENTIFIER_POINTER (constant_string_id
));
1150 return error_mark_node
;
1153 add_class_reference (constant_string_id
);
1155 if (TREE_CHAIN (strings
))
1157 varray_type vstrings
;
1158 VARRAY_TREE_INIT (vstrings
, 32, "strings");
1160 for (; strings
; strings
= TREE_CHAIN (strings
))
1161 VARRAY_PUSH_TREE (vstrings
, strings
);
1163 string
= combine_strings (vstrings
);
1168 string
= fix_string_type (string
);
1170 TREE_SET_CODE (string
, STRING_CST
);
1171 length
= TREE_STRING_LENGTH (string
) - 1;
1173 /* We could not properly create NXConstantString in synth_module_prologue,
1174 because that's called before debugging is initialized. Do it now. */
1175 if (TYPE_FIELDS (constant_string_type
) == NULL_TREE
)
1176 build_string_class_template ();
1178 /* & ((NXConstantString) { NULL, string, length }) */
1180 if (flag_next_runtime
)
1182 /* For the NeXT runtime, we can generate a literal reference
1183 to the string class, don't need to run a constructor. */
1184 setup_string_decl ();
1185 if (string_class_decl
== NULL_TREE
)
1187 error ("cannot find reference tag for class `%s'",
1188 IDENTIFIER_POINTER (constant_string_id
));
1189 return error_mark_node
;
1191 initlist
= build_tree_list
1193 copy_node (build_unary_op (ADDR_EXPR
, string_class_decl
, 0)));
1197 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1201 = tree_cons (NULL_TREE
, copy_node (build_unary_op (ADDR_EXPR
, string
, 1)),
1203 initlist
= tree_cons (NULL_TREE
, build_int_2 (length
, 0), initlist
);
1204 constructor
= build_constructor (constant_string_type
, nreverse (initlist
));
1206 if (!flag_next_runtime
)
1209 = objc_add_static_instance (constructor
, constant_string_type
);
1212 return (build_unary_op (ADDR_EXPR
, constructor
, 1));
1215 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1218 objc_add_static_instance (constructor
, class_decl
)
1219 tree constructor
, class_decl
;
1221 static int num_static_inst
;
1225 /* Find the list of static instances for the CLASS_DECL. Create one if
1227 for (chain
= &objc_static_instances
;
1228 *chain
&& TREE_VALUE (*chain
) != class_decl
;
1229 chain
= &TREE_CHAIN (*chain
));
1232 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
1233 add_objc_string (TYPE_NAME (class_decl
), class_names
);
1236 sprintf (buf
, "_OBJC_INSTANCE_%d", num_static_inst
++);
1237 decl
= build_decl (VAR_DECL
, get_identifier (buf
), class_decl
);
1238 DECL_COMMON (decl
) = 1;
1239 TREE_STATIC (decl
) = 1;
1240 DECL_ARTIFICIAL (decl
) = 1;
1241 DECL_INITIAL (decl
) = constructor
;
1243 /* We may be writing something else just now.
1244 Postpone till end of input. */
1245 DECL_DEFER_OUTPUT (decl
) = 1;
1246 pushdecl_top_level (decl
);
1247 rest_of_decl_compilation (decl
, 0, 1, 0);
1249 /* Add the DECL to the head of this CLASS' list. */
1250 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
1255 /* Build a static constant CONSTRUCTOR
1256 with type TYPE and elements ELTS. */
1259 build_constructor (type
, elts
)
1262 tree constructor
, f
, e
;
1264 /* ??? Most of the places that we build constructors, we don't fill in
1265 the type of integers properly. Convert them all en masse. */
1266 if (TREE_CODE (type
) == ARRAY_TYPE
)
1268 f
= TREE_TYPE (type
);
1269 if (TREE_CODE (f
) == POINTER_TYPE
|| TREE_CODE (f
) == INTEGER_TYPE
)
1270 for (e
= elts
; e
; e
= TREE_CHAIN (e
))
1271 TREE_VALUE (e
) = convert (f
, TREE_VALUE (e
));
1275 f
= TYPE_FIELDS (type
);
1276 for (e
= elts
; e
; e
= TREE_CHAIN (e
), f
= TREE_CHAIN (f
))
1277 if (TREE_CODE (TREE_TYPE (f
)) == POINTER_TYPE
1278 || TREE_CODE (TREE_TYPE (f
)) == INTEGER_TYPE
)
1279 TREE_VALUE (e
) = convert (TREE_TYPE (f
), TREE_VALUE (e
));
1282 constructor
= build (CONSTRUCTOR
, type
, NULL_TREE
, elts
);
1283 TREE_CONSTANT (constructor
) = 1;
1284 TREE_STATIC (constructor
) = 1;
1285 TREE_READONLY (constructor
) = 1;
1290 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1292 /* Predefine the following data type:
1300 void *defs[cls_def_cnt + cat_def_cnt];
1304 build_objc_symtab_template ()
1306 tree field_decl
, field_decl_chain
, index
;
1308 objc_symtab_template
1309 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SYMTAB
));
1311 /* long sel_ref_cnt; */
1313 field_decl
= create_builtin_decl (FIELD_DECL
,
1314 long_integer_type_node
,
1316 field_decl_chain
= field_decl
;
1320 field_decl
= create_builtin_decl (FIELD_DECL
,
1321 build_pointer_type (selector_type
),
1323 chainon (field_decl_chain
, field_decl
);
1325 /* short cls_def_cnt; */
1327 field_decl
= create_builtin_decl (FIELD_DECL
,
1328 short_integer_type_node
,
1330 chainon (field_decl_chain
, field_decl
);
1332 /* short cat_def_cnt; */
1334 field_decl
= create_builtin_decl (FIELD_DECL
,
1335 short_integer_type_node
,
1337 chainon (field_decl_chain
, field_decl
);
1339 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1341 if (!flag_next_runtime
)
1342 index
= build_index_type (build_int_2 (imp_count
+ cat_count
, 0));
1344 index
= build_index_type (build_int_2 (imp_count
+ cat_count
- 1,
1345 imp_count
== 0 && cat_count
== 0
1347 field_decl
= create_builtin_decl (FIELD_DECL
,
1348 build_array_type (ptr_type_node
, index
),
1350 chainon (field_decl_chain
, field_decl
);
1352 finish_struct (objc_symtab_template
, field_decl_chain
, NULL_TREE
);
1355 /* Create the initial value for the `defs' field of _objc_symtab.
1356 This is a CONSTRUCTOR. */
1359 init_def_list (type
)
1362 tree expr
, initlist
= NULL_TREE
;
1363 struct imp_entry
*impent
;
1366 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1368 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
1370 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1371 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1376 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1378 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1380 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1381 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1385 if (!flag_next_runtime
)
1387 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1390 if (static_instances_decl
)
1391 expr
= build_unary_op (ADDR_EXPR
, static_instances_decl
, 0);
1393 expr
= build_int_2 (0, 0);
1395 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1398 return build_constructor (type
, nreverse (initlist
));
1401 /* Construct the initial value for all of _objc_symtab. */
1404 init_objc_symtab (type
)
1409 /* sel_ref_cnt = { ..., 5, ... } */
1411 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1413 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1415 if (flag_next_runtime
|| ! sel_ref_chain
)
1416 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1418 initlist
= tree_cons (NULL_TREE
,
1419 build_unary_op (ADDR_EXPR
,
1420 UOBJC_SELECTOR_TABLE_decl
, 1),
1423 /* cls_def_cnt = { ..., 5, ... } */
1425 initlist
= tree_cons (NULL_TREE
, build_int_2 (imp_count
, 0), initlist
);
1427 /* cat_def_cnt = { ..., 5, ... } */
1429 initlist
= tree_cons (NULL_TREE
, build_int_2 (cat_count
, 0), initlist
);
1431 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1433 if (imp_count
|| cat_count
|| static_instances_decl
)
1436 tree field
= TYPE_FIELDS (type
);
1437 field
= TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field
))));
1439 initlist
= tree_cons (NULL_TREE
, init_def_list (TREE_TYPE (field
)),
1443 return build_constructor (type
, nreverse (initlist
));
1446 /* Push forward-declarations of all the categories so that
1447 init_def_list can use them in a CONSTRUCTOR. */
1450 forward_declare_categories ()
1452 struct imp_entry
*impent
;
1453 tree sav
= objc_implementation_context
;
1455 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1457 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1459 /* Set an invisible arg to synth_id_with_class_suffix. */
1460 objc_implementation_context
= impent
->imp_context
;
1462 = create_builtin_decl (VAR_DECL
, objc_category_template
,
1463 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", objc_implementation_context
)));
1466 objc_implementation_context
= sav
;
1469 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1470 and initialized appropriately. */
1473 generate_objc_symtab_decl ()
1477 if (!objc_category_template
)
1478 build_category_template ();
1480 /* forward declare categories */
1482 forward_declare_categories ();
1484 if (!objc_symtab_template
)
1485 build_objc_symtab_template ();
1487 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
1489 UOBJC_SYMBOLS_decl
= start_decl (get_identifier ("_OBJC_SYMBOLS"),
1490 tree_cons (NULL_TREE
,
1491 objc_symtab_template
, sc_spec
),
1495 TREE_USED (UOBJC_SYMBOLS_decl
) = 1;
1496 DECL_IGNORED_P (UOBJC_SYMBOLS_decl
) = 1;
1497 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl
) = 1;
1498 finish_decl (UOBJC_SYMBOLS_decl
,
1499 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)),
1504 init_module_descriptor (type
)
1507 tree initlist
, expr
;
1509 /* version = { 1, ... } */
1511 expr
= build_int_2 (OBJC_VERSION
, 0);
1512 initlist
= build_tree_list (NULL_TREE
, expr
);
1514 /* size = { ..., sizeof (struct objc_module), ... } */
1516 expr
= size_in_bytes (objc_module_template
);
1517 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1519 /* name = { ..., "foo.m", ... } */
1521 expr
= add_objc_string (get_identifier (input_filename
), class_names
);
1522 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1524 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1526 if (UOBJC_SYMBOLS_decl
)
1527 expr
= build_unary_op (ADDR_EXPR
, UOBJC_SYMBOLS_decl
, 0);
1529 expr
= build_int_2 (0, 0);
1530 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1532 return build_constructor (type
, nreverse (initlist
));
1535 /* Write out the data structures to describe Objective C classes defined.
1536 If appropriate, compile and output a setup function to initialize them.
1537 Return a symbol_ref to the function to call to initialize the Objective C
1538 data structures for this file (and perhaps for other files also).
1540 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1543 build_module_descriptor ()
1545 tree decl_specs
, field_decl
, field_decl_chain
;
1547 objc_module_template
1548 = start_struct (RECORD_TYPE
, get_identifier (UTAG_MODULE
));
1552 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1553 field_decl
= get_identifier ("version");
1555 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1556 field_decl_chain
= field_decl
;
1560 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1561 field_decl
= get_identifier ("size");
1563 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1564 chainon (field_decl_chain
, field_decl
);
1568 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
1569 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
1571 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1572 chainon (field_decl_chain
, field_decl
);
1574 /* struct objc_symtab *symtab; */
1576 decl_specs
= get_identifier (UTAG_SYMTAB
);
1577 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
1578 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("symtab"));
1580 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1581 chainon (field_decl_chain
, field_decl
);
1583 finish_struct (objc_module_template
, field_decl_chain
, NULL_TREE
);
1585 /* Create an instance of "objc_module". */
1587 decl_specs
= tree_cons (NULL_TREE
, objc_module_template
,
1588 build_tree_list (NULL_TREE
,
1589 ridpointers
[(int) RID_STATIC
]));
1591 UOBJC_MODULES_decl
= start_decl (get_identifier ("_OBJC_MODULES"),
1592 decl_specs
, 1, NULL_TREE
);
1594 DECL_ARTIFICIAL (UOBJC_MODULES_decl
) = 1;
1595 DECL_IGNORED_P (UOBJC_MODULES_decl
) = 1;
1596 DECL_CONTEXT (UOBJC_MODULES_decl
) = NULL_TREE
;
1598 finish_decl (UOBJC_MODULES_decl
,
1599 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl
)),
1602 /* Mark the decl to avoid "defined but not used" warning. */
1603 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl
) = 1;
1605 /* Generate a constructor call for the module descriptor.
1606 This code was generated by reading the grammar rules
1607 of c-parse.in; Therefore, it may not be the most efficient
1608 way of generating the requisite code. */
1610 if (flag_next_runtime
)
1614 tree parms
, execclass_decl
, decelerator
, void_list_node_1
;
1615 tree init_function_name
, init_function_decl
;
1617 /* Declare void __objc_execClass (void *); */
1619 void_list_node_1
= build_tree_list (NULL_TREE
, void_type_node
);
1620 execclass_decl
= build_decl (FUNCTION_DECL
,
1621 get_identifier (TAG_EXECCLASS
),
1622 build_function_type (void_type_node
,
1623 tree_cons (NULL_TREE
, ptr_type_node
,
1624 void_list_node_1
)));
1625 DECL_EXTERNAL (execclass_decl
) = 1;
1626 DECL_ARTIFICIAL (execclass_decl
) = 1;
1627 TREE_PUBLIC (execclass_decl
) = 1;
1628 pushdecl (execclass_decl
);
1629 rest_of_decl_compilation (execclass_decl
, 0, 0, 0);
1630 assemble_external (execclass_decl
);
1632 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1634 init_function_name
= get_file_function_name ('I');
1635 start_function (void_list_node_1
,
1636 build_nt (CALL_EXPR
, init_function_name
,
1637 tree_cons (NULL_TREE
, NULL_TREE
,
1641 store_parm_decls ();
1643 init_function_decl
= current_function_decl
;
1644 TREE_PUBLIC (init_function_decl
) = ! targetm
.have_ctors_dtors
;
1645 TREE_USED (init_function_decl
) = 1;
1646 /* Don't let this one be deferred. */
1647 DECL_INLINE (init_function_decl
) = 0;
1648 DECL_UNINLINABLE (init_function_decl
) = 1;
1649 current_function_cannot_inline
1650 = "static constructors and destructors cannot be inlined";
1653 = build_tree_list (NULL_TREE
,
1654 build_unary_op (ADDR_EXPR
, UOBJC_MODULES_decl
, 0));
1655 decelerator
= build_function_call (execclass_decl
, parms
);
1657 c_expand_expr_stmt (decelerator
);
1659 finish_function (0, 0);
1661 return XEXP (DECL_RTL (init_function_decl
), 0);
1665 /* extern const char _OBJC_STRINGS[]; */
1668 generate_forward_declaration_to_string_table ()
1670 tree sc_spec
, decl_specs
, expr_decl
;
1672 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_EXTERN
], NULL_TREE
);
1673 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1676 = build_nt (ARRAY_REF
, get_identifier ("_OBJC_STRINGS"), NULL_TREE
);
1678 UOBJC_STRINGS_decl
= define_decl (expr_decl
, decl_specs
);
1681 /* Return the DECL of the string IDENT in the SECTION. */
1684 get_objc_string_decl (ident
, section
)
1686 enum string_section section
;
1690 if (section
== class_names
)
1691 chain
= class_names_chain
;
1692 else if (section
== meth_var_names
)
1693 chain
= meth_var_names_chain
;
1694 else if (section
== meth_var_types
)
1695 chain
= meth_var_types_chain
;
1699 for (; chain
!= 0; chain
= TREE_VALUE (chain
))
1700 if (TREE_VALUE (chain
) == ident
)
1701 return (TREE_PURPOSE (chain
));
1707 /* Output references to all statically allocated objects. Return the DECL
1708 for the array built. */
1711 generate_static_references ()
1713 tree decls
= NULL_TREE
, ident
, decl_spec
, expr_decl
, expr
= NULL_TREE
;
1714 tree class_name
, class, decl
, initlist
;
1715 tree cl_chain
, in_chain
, type
;
1716 int num_inst
, num_class
;
1719 if (flag_next_runtime
)
1722 for (cl_chain
= objc_static_instances
, num_class
= 0;
1723 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
1725 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
1726 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
1728 sprintf (buf
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
1729 ident
= get_identifier (buf
);
1731 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1732 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1733 build_tree_list (NULL_TREE
,
1734 ridpointers
[(int) RID_STATIC
]));
1735 decl
= start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
);
1736 DECL_CONTEXT (decl
) = 0;
1737 DECL_ARTIFICIAL (decl
) = 1;
1739 /* Output {class_name, ...}. */
1740 class = TREE_VALUE (cl_chain
);
1741 class_name
= get_objc_string_decl (TYPE_NAME (class), class_names
);
1742 initlist
= build_tree_list (NULL_TREE
,
1743 build_unary_op (ADDR_EXPR
, class_name
, 1));
1745 /* Output {..., instance, ...}. */
1746 for (in_chain
= TREE_PURPOSE (cl_chain
);
1747 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
1749 expr
= build_unary_op (ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
1750 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1753 /* Output {..., NULL}. */
1754 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1756 expr
= build_constructor (TREE_TYPE (decl
), nreverse (initlist
));
1757 finish_decl (decl
, expr
, NULL_TREE
);
1758 TREE_USED (decl
) = 1;
1760 type
= build_array_type (build_pointer_type (void_type_node
), 0);
1761 decl
= build_decl (VAR_DECL
, ident
, type
);
1762 TREE_USED (decl
) = 1;
1763 TREE_STATIC (decl
) = 1;
1765 = tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, decl
, 1), decls
);
1768 decls
= tree_cons (NULL_TREE
, build_int_2 (0, 0), decls
);
1769 ident
= get_identifier ("_OBJC_STATIC_INSTANCES");
1770 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1771 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1772 build_tree_list (NULL_TREE
,
1773 ridpointers
[(int) RID_STATIC
]));
1774 static_instances_decl
1775 = start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
);
1776 TREE_USED (static_instances_decl
) = 1;
1777 DECL_CONTEXT (static_instances_decl
) = 0;
1778 DECL_ARTIFICIAL (static_instances_decl
) = 1;
1779 expr
= build_constructor (TREE_TYPE (static_instances_decl
),
1781 finish_decl (static_instances_decl
, expr
, NULL_TREE
);
1784 /* Output all strings. */
1789 tree sc_spec
, decl_specs
, expr_decl
;
1790 tree chain
, string_expr
;
1793 for (chain
= class_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1795 string
= TREE_VALUE (chain
);
1796 decl
= TREE_PURPOSE (chain
);
1798 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1799 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1800 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1801 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1802 DECL_CONTEXT (decl
) = NULL_TREE
;
1803 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1804 IDENTIFIER_POINTER (string
));
1805 finish_decl (decl
, string_expr
, NULL_TREE
);
1808 for (chain
= meth_var_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1810 string
= TREE_VALUE (chain
);
1811 decl
= TREE_PURPOSE (chain
);
1813 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1814 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1815 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1816 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1817 DECL_CONTEXT (decl
) = NULL_TREE
;
1818 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1819 IDENTIFIER_POINTER (string
));
1820 finish_decl (decl
, string_expr
, NULL_TREE
);
1823 for (chain
= meth_var_types_chain
; chain
; chain
= TREE_CHAIN (chain
))
1825 string
= TREE_VALUE (chain
);
1826 decl
= TREE_PURPOSE (chain
);
1828 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1829 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1830 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1831 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1832 DECL_CONTEXT (decl
) = NULL_TREE
;
1833 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1834 IDENTIFIER_POINTER (string
));
1835 finish_decl (decl
, string_expr
, NULL_TREE
);
1840 build_selector_reference_decl ()
1846 sprintf (buf
, "_OBJC_SELECTOR_REFERENCES_%d", idx
++);
1848 ident
= get_identifier (buf
);
1850 decl
= build_decl (VAR_DECL
, ident
, selector_type
);
1851 DECL_EXTERNAL (decl
) = 1;
1852 TREE_PUBLIC (decl
) = 1;
1853 TREE_USED (decl
) = 1;
1854 TREE_READONLY (decl
) = 1;
1855 DECL_ARTIFICIAL (decl
) = 1;
1856 DECL_CONTEXT (decl
) = 0;
1858 make_decl_rtl (decl
, 0);
1859 pushdecl_top_level (decl
);
1864 /* Just a handy wrapper for add_objc_string. */
1867 build_selector (ident
)
1870 tree expr
= add_objc_string (ident
, meth_var_names
);
1871 if (flag_typed_selectors
)
1874 return build_c_cast (selector_type
, expr
); /* cast! */
1878 build_selector_translation_table ()
1880 tree sc_spec
, decl_specs
;
1881 tree chain
, initlist
= NULL_TREE
;
1883 tree decl
= NULL_TREE
, var_decl
, name
;
1885 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
1889 if (warn_selector
&& objc_implementation_context
)
1893 for (method_chain
= meth_var_names_chain
;
1895 method_chain
= TREE_CHAIN (method_chain
))
1897 if (TREE_VALUE (method_chain
) == TREE_VALUE (chain
))
1905 /* Adjust line number for warning message. */
1906 int save_lineno
= lineno
;
1907 if (flag_next_runtime
&& TREE_PURPOSE (chain
))
1908 lineno
= DECL_SOURCE_LINE (TREE_PURPOSE (chain
));
1909 warning ("creating selector for non existant method %s",
1910 IDENTIFIER_POINTER (TREE_VALUE (chain
)));
1911 lineno
= save_lineno
;
1915 expr
= build_selector (TREE_VALUE (chain
));
1917 if (flag_next_runtime
)
1919 name
= DECL_NAME (TREE_PURPOSE (chain
));
1921 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
1923 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
1924 decl_specs
= tree_cons (NULL_TREE
, selector_type
, sc_spec
);
1928 /* The `decl' that is returned from start_decl is the one that we
1929 forward declared in `build_selector_reference' */
1930 decl
= start_decl (var_decl
, decl_specs
, 1, NULL_TREE
);
1933 /* add one for the '\0' character */
1934 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (chain
)) + 1;
1936 if (flag_next_runtime
)
1937 finish_decl (decl
, expr
, NULL_TREE
);
1940 if (flag_typed_selectors
)
1942 tree eltlist
= NULL_TREE
;
1943 tree encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
1944 eltlist
= tree_cons (NULL_TREE
, expr
, NULL_TREE
);
1945 eltlist
= tree_cons (NULL_TREE
, encoding
, eltlist
);
1946 expr
= build_constructor (objc_selector_template
,
1947 nreverse (eltlist
));
1949 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1954 if (! flag_next_runtime
)
1956 /* Cause the variable and its initial value to be actually output. */
1957 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl
) = 0;
1958 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl
) = 1;
1959 /* NULL terminate the list and fix the decl for output. */
1960 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1961 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl
) = objc_ellipsis_node
;
1962 initlist
= build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
1963 nreverse (initlist
));
1964 finish_decl (UOBJC_SELECTOR_TABLE_decl
, initlist
, NULL_TREE
);
1965 current_function_decl
= NULL_TREE
;
1970 get_proto_encoding (proto
)
1978 if (! METHOD_ENCODING (proto
))
1980 tmp_decl
= build_tmp_function_decl ();
1981 hack_method_prototype (proto
, tmp_decl
);
1982 encoding
= encode_method_prototype (proto
, tmp_decl
);
1983 METHOD_ENCODING (proto
) = encoding
;
1986 encoding
= METHOD_ENCODING (proto
);
1988 return add_objc_string (encoding
, meth_var_types
);
1991 return build_int_2 (0, 0);
1994 /* sel_ref_chain is a list whose "value" fields will be instances of
1995 identifier_node that represent the selector. */
1998 build_typed_selector_reference (ident
, proto
)
2001 tree
*chain
= &sel_ref_chain
;
2007 if (TREE_PURPOSE (*chain
) == ident
&& TREE_VALUE (*chain
) == proto
)
2008 goto return_at_index
;
2011 chain
= &TREE_CHAIN (*chain
);
2014 *chain
= tree_cons (proto
, ident
, NULL_TREE
);
2017 expr
= build_unary_op (ADDR_EXPR
,
2018 build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2019 build_int_2 (index
, 0)),
2021 return build_c_cast (selector_type
, expr
);
2025 build_selector_reference (ident
)
2028 tree
*chain
= &sel_ref_chain
;
2034 if (TREE_VALUE (*chain
) == ident
)
2035 return (flag_next_runtime
2036 ? TREE_PURPOSE (*chain
)
2037 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2038 build_int_2 (index
, 0)));
2041 chain
= &TREE_CHAIN (*chain
);
2044 expr
= build_selector_reference_decl ();
2046 *chain
= tree_cons (expr
, ident
, NULL_TREE
);
2048 return (flag_next_runtime
2050 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2051 build_int_2 (index
, 0)));
2055 build_class_reference_decl ()
2061 sprintf (buf
, "_OBJC_CLASS_REFERENCES_%d", idx
++);
2063 ident
= get_identifier (buf
);
2065 decl
= build_decl (VAR_DECL
, ident
, objc_class_type
);
2066 DECL_EXTERNAL (decl
) = 1;
2067 TREE_PUBLIC (decl
) = 1;
2068 TREE_USED (decl
) = 1;
2069 TREE_READONLY (decl
) = 1;
2070 DECL_CONTEXT (decl
) = 0;
2071 DECL_ARTIFICIAL (decl
) = 1;
2073 make_decl_rtl (decl
, 0);
2074 pushdecl_top_level (decl
);
2079 /* Create a class reference, but don't create a variable to reference
2083 add_class_reference (ident
)
2088 if ((chain
= cls_ref_chain
))
2093 if (ident
== TREE_VALUE (chain
))
2097 chain
= TREE_CHAIN (chain
);
2101 /* Append to the end of the list */
2102 TREE_CHAIN (tail
) = tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2105 cls_ref_chain
= tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2108 /* Get a class reference, creating it if necessary. Also create the
2109 reference variable. */
2112 get_class_reference (ident
)
2115 if (flag_next_runtime
)
2120 for (chain
= &cls_ref_chain
; *chain
; chain
= &TREE_CHAIN (*chain
))
2121 if (TREE_VALUE (*chain
) == ident
)
2123 if (! TREE_PURPOSE (*chain
))
2124 TREE_PURPOSE (*chain
) = build_class_reference_decl ();
2126 return TREE_PURPOSE (*chain
);
2129 decl
= build_class_reference_decl ();
2130 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2137 add_class_reference (ident
);
2139 params
= build_tree_list (NULL_TREE
,
2140 my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
2141 IDENTIFIER_POINTER (ident
)));
2143 assemble_external (objc_get_class_decl
);
2144 return build_function_call (objc_get_class_decl
, params
);
2148 /* For each string section we have a chain which maps identifier nodes
2149 to decls for the strings. */
2152 add_objc_string (ident
, section
)
2154 enum string_section section
;
2158 if (section
== class_names
)
2159 chain
= &class_names_chain
;
2160 else if (section
== meth_var_names
)
2161 chain
= &meth_var_names_chain
;
2162 else if (section
== meth_var_types
)
2163 chain
= &meth_var_types_chain
;
2169 if (TREE_VALUE (*chain
) == ident
)
2170 return build_unary_op (ADDR_EXPR
, TREE_PURPOSE (*chain
), 1);
2172 chain
= &TREE_CHAIN (*chain
);
2175 decl
= build_objc_string_decl (section
);
2177 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2179 return build_unary_op (ADDR_EXPR
, decl
, 1);
2183 build_objc_string_decl (section
)
2184 enum string_section section
;
2188 static int class_names_idx
= 0;
2189 static int meth_var_names_idx
= 0;
2190 static int meth_var_types_idx
= 0;
2192 if (section
== class_names
)
2193 sprintf (buf
, "_OBJC_CLASS_NAME_%d", class_names_idx
++);
2194 else if (section
== meth_var_names
)
2195 sprintf (buf
, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx
++);
2196 else if (section
== meth_var_types
)
2197 sprintf (buf
, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx
++);
2199 ident
= get_identifier (buf
);
2201 decl
= build_decl (VAR_DECL
, ident
, build_array_type (char_type_node
, 0));
2202 DECL_EXTERNAL (decl
) = 1;
2203 TREE_PUBLIC (decl
) = 1;
2204 TREE_USED (decl
) = 1;
2205 TREE_READONLY (decl
) = 1;
2206 TREE_CONSTANT (decl
) = 1;
2207 DECL_CONTEXT (decl
) = 0;
2208 DECL_ARTIFICIAL (decl
) = 1;
2210 make_decl_rtl (decl
, 0);
2211 pushdecl_top_level (decl
);
2218 objc_declare_alias (alias_ident
, class_ident
)
2222 if (is_class_name (class_ident
) != class_ident
)
2223 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident
));
2224 else if (is_class_name (alias_ident
))
2225 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident
));
2227 alias_chain
= tree_cons (class_ident
, alias_ident
, alias_chain
);
2231 objc_declare_class (ident_list
)
2236 for (list
= ident_list
; list
; list
= TREE_CHAIN (list
))
2238 tree ident
= TREE_VALUE (list
);
2241 if ((decl
= lookup_name (ident
)))
2243 error ("`%s' redeclared as different kind of symbol",
2244 IDENTIFIER_POINTER (ident
));
2245 error_with_decl (decl
, "previous declaration of `%s'");
2248 if (! is_class_name (ident
))
2250 tree record
= xref_tag (RECORD_TYPE
, ident
);
2251 TREE_STATIC_TEMPLATE (record
) = 1;
2252 class_chain
= tree_cons (NULL_TREE
, ident
, class_chain
);
2258 is_class_name (ident
)
2263 if (lookup_interface (ident
))
2266 for (chain
= class_chain
; chain
; chain
= TREE_CHAIN (chain
))
2268 if (ident
== TREE_VALUE (chain
))
2272 for (chain
= alias_chain
; chain
; chain
= TREE_CHAIN (chain
))
2274 if (ident
== TREE_VALUE (chain
))
2275 return TREE_PURPOSE (chain
);
2282 lookup_interface (ident
)
2287 for (chain
= interface_chain
; chain
; chain
= TREE_CHAIN (chain
))
2289 if (ident
== CLASS_NAME (chain
))
2296 objc_copy_list (list
, head
)
2300 tree newlist
= NULL_TREE
, tail
= NULL_TREE
;
2304 tail
= copy_node (list
);
2306 /* The following statement fixes a bug when inheriting instance
2307 variables that are declared to be bitfields. finish_struct
2308 expects to find the width of the bitfield in DECL_INITIAL. */
2309 if (DECL_BIT_FIELD (tail
) && DECL_INITIAL (tail
) == 0)
2310 DECL_INITIAL (tail
) = DECL_SIZE (tail
);
2312 newlist
= chainon (newlist
, tail
);
2313 list
= TREE_CHAIN (list
);
2320 /* Used by: build_private_template, get_class_ivars, and
2321 continue_class. COPY is 1 when called from @defs. In this case
2322 copy all fields. Otherwise don't copy leaf ivars since we rely on
2323 them being side-effected exactly once by finish_struct. */
2326 build_ivar_chain (interface
, copy
)
2330 tree my_name
, super_name
, ivar_chain
;
2332 my_name
= CLASS_NAME (interface
);
2333 super_name
= CLASS_SUPER_NAME (interface
);
2335 /* Possibly copy leaf ivars. */
2337 objc_copy_list (CLASS_IVARS (interface
), &ivar_chain
);
2339 ivar_chain
= CLASS_IVARS (interface
);
2344 tree super_interface
= lookup_interface (super_name
);
2346 if (!super_interface
)
2348 /* fatal did not work with 2 args...should fix */
2349 error ("cannot find interface declaration for `%s', superclass of `%s'",
2350 IDENTIFIER_POINTER (super_name
),
2351 IDENTIFIER_POINTER (my_name
));
2352 exit (FATAL_EXIT_CODE
);
2355 if (super_interface
== interface
)
2356 fatal_error ("circular inheritance in interface declaration for `%s'",
2357 IDENTIFIER_POINTER (super_name
));
2359 interface
= super_interface
;
2360 my_name
= CLASS_NAME (interface
);
2361 super_name
= CLASS_SUPER_NAME (interface
);
2363 op1
= CLASS_IVARS (interface
);
2366 tree head
, tail
= objc_copy_list (op1
, &head
);
2368 /* Prepend super class ivars...make a copy of the list, we
2369 do not want to alter the original. */
2370 TREE_CHAIN (tail
) = ivar_chain
;
2377 /* struct <classname> {
2378 struct objc_class *isa;
2383 build_private_template (class)
2388 if (CLASS_STATIC_TEMPLATE (class))
2390 uprivate_record
= CLASS_STATIC_TEMPLATE (class);
2391 ivar_context
= TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2395 uprivate_record
= start_struct (RECORD_TYPE
, CLASS_NAME (class));
2397 ivar_context
= build_ivar_chain (class, 0);
2399 finish_struct (uprivate_record
, ivar_context
, NULL_TREE
);
2401 CLASS_STATIC_TEMPLATE (class) = uprivate_record
;
2403 /* mark this record as class template - for class type checking */
2404 TREE_STATIC_TEMPLATE (uprivate_record
) = 1;
2408 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
2410 build1 (INDIRECT_REF
, NULL_TREE
,
2413 return ivar_context
;
2416 /* Begin code generation for protocols... */
2418 /* struct objc_protocol {
2419 char *protocol_name;
2420 struct objc_protocol **protocol_list;
2421 struct objc_method_desc *instance_methods;
2422 struct objc_method_desc *class_methods;
2426 build_protocol_template ()
2428 tree decl_specs
, field_decl
, field_decl_chain
;
2431 template = start_struct (RECORD_TYPE
, get_identifier (UTAG_PROTOCOL
));
2433 /* struct objc_class *isa; */
2435 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2436 get_identifier (UTAG_CLASS
)));
2437 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
2439 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2440 field_decl_chain
= field_decl
;
2442 /* char *protocol_name; */
2444 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
2446 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_name"));
2448 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2449 chainon (field_decl_chain
, field_decl
);
2451 /* struct objc_protocol **protocol_list; */
2453 decl_specs
= build_tree_list (NULL_TREE
, template);
2455 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
2456 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
2458 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2459 chainon (field_decl_chain
, field_decl
);
2461 /* struct objc_method_list *instance_methods; */
2464 = build_tree_list (NULL_TREE
,
2465 xref_tag (RECORD_TYPE
,
2466 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2468 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
2470 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2471 chainon (field_decl_chain
, field_decl
);
2473 /* struct objc_method_list *class_methods; */
2476 = build_tree_list (NULL_TREE
,
2477 xref_tag (RECORD_TYPE
,
2478 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2480 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
2482 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2483 chainon (field_decl_chain
, field_decl
);
2485 return finish_struct (template, field_decl_chain
, NULL_TREE
);
2489 build_descriptor_table_initializer (type
, entries
)
2493 tree initlist
= NULL_TREE
;
2497 tree eltlist
= NULL_TREE
;
2500 = tree_cons (NULL_TREE
,
2501 build_selector (METHOD_SEL_NAME (entries
)), NULL_TREE
);
2503 = tree_cons (NULL_TREE
,
2504 add_objc_string (METHOD_ENCODING (entries
),
2509 = tree_cons (NULL_TREE
,
2510 build_constructor (type
, nreverse (eltlist
)), initlist
);
2512 entries
= TREE_CHAIN (entries
);
2516 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
2519 /* struct objc_method_prototype_list {
2521 struct objc_method_prototype {
2528 build_method_prototype_list_template (list_type
, size
)
2532 tree objc_ivar_list_record
;
2533 tree decl_specs
, field_decl
, field_decl_chain
;
2535 /* Generate an unnamed struct definition. */
2537 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
2539 /* int method_count; */
2541 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
2542 field_decl
= get_identifier ("method_count");
2545 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2546 field_decl_chain
= field_decl
;
2548 /* struct objc_method method_list[]; */
2550 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
2551 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
2552 build_int_2 (size
, 0));
2555 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2556 chainon (field_decl_chain
, field_decl
);
2558 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
2560 return objc_ivar_list_record
;
2564 build_method_prototype_template ()
2567 tree decl_specs
, field_decl
, field_decl_chain
;
2570 = start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD_PROTOTYPE
));
2572 /* struct objc_selector *_cmd; */
2573 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
2574 get_identifier (TAG_SELECTOR
)), NULL_TREE
);
2575 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
2578 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2579 field_decl_chain
= field_decl
;
2581 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
2583 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_types"));
2585 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2586 chainon (field_decl_chain
, field_decl
);
2588 finish_struct (proto_record
, field_decl_chain
, NULL_TREE
);
2590 return proto_record
;
2593 /* True if last call to forwarding_offset yielded a register offset. */
2594 static int offset_is_register
;
2597 forwarding_offset (parm
)
2600 int offset_in_bytes
;
2602 if (GET_CODE (DECL_INCOMING_RTL (parm
)) == MEM
)
2604 rtx addr
= XEXP (DECL_INCOMING_RTL (parm
), 0);
2606 /* ??? Here we assume that the parm address is indexed
2607 off the frame pointer or arg pointer.
2608 If that is not true, we produce meaningless results,
2609 but do not crash. */
2610 if (GET_CODE (addr
) == PLUS
2611 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
2612 offset_in_bytes
= INTVAL (XEXP (addr
, 1));
2614 offset_in_bytes
= 0;
2616 offset_in_bytes
+= OBJC_FORWARDING_STACK_OFFSET
;
2617 offset_is_register
= 0;
2619 else if (GET_CODE (DECL_INCOMING_RTL (parm
)) == REG
)
2621 int regno
= REGNO (DECL_INCOMING_RTL (parm
));
2622 offset_in_bytes
= apply_args_register_offset (regno
);
2623 offset_is_register
= 1;
2628 /* This is the case where the parm is passed as an int or double
2629 and it is converted to a char, short or float and stored back
2630 in the parmlist. In this case, describe the parm
2631 with the variable's declared type, and adjust the address
2632 if the least significant bytes (which we are using) are not
2634 if (BYTES_BIG_ENDIAN
&& TREE_TYPE (parm
) != DECL_ARG_TYPE (parm
))
2635 offset_in_bytes
+= (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm
)))
2636 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm
))));
2638 return offset_in_bytes
;
2642 encode_method_prototype (method_decl
, func_decl
)
2649 HOST_WIDE_INT max_parm_end
= 0;
2653 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2654 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl
)));
2657 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
2658 obstack_object_size (&util_obstack
),
2659 OBJC_ENCODE_INLINE_DEFS
);
2662 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
2663 parms
= TREE_CHAIN (parms
))
2665 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
2666 + int_size_in_bytes (TREE_TYPE (parms
)));
2668 if (!offset_is_register
&& max_parm_end
< parm_end
)
2669 max_parm_end
= parm_end
;
2672 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
2674 sprintf (buf
, "%d", stack_size
);
2675 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2677 user_args
= METHOD_SEL_ARGS (method_decl
);
2679 /* Argument types. */
2680 for (parms
= DECL_ARGUMENTS (func_decl
), i
= 0; parms
;
2681 parms
= TREE_CHAIN (parms
), i
++)
2683 /* Process argument qualifiers for user supplied arguments. */
2686 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args
)));
2687 user_args
= TREE_CHAIN (user_args
);
2691 encode_type (TREE_TYPE (parms
),
2692 obstack_object_size (&util_obstack
),
2693 OBJC_ENCODE_INLINE_DEFS
);
2695 /* Compute offset. */
2696 sprintf (buf
, "%d", forwarding_offset (parms
));
2698 /* Indicate register. */
2699 if (offset_is_register
)
2700 obstack_1grow (&util_obstack
, '+');
2702 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2705 obstack_1grow (&util_obstack
, '\0');
2706 result
= get_identifier (obstack_finish (&util_obstack
));
2707 obstack_free (&util_obstack
, util_firstobj
);
2712 generate_descriptor_table (type
, name
, size
, list
, proto
)
2719 tree sc_spec
, decl_specs
, decl
, initlist
;
2721 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2722 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
2724 decl
= start_decl (synth_id_with_class_suffix (name
, proto
),
2725 decl_specs
, 1, NULL_TREE
);
2726 DECL_CONTEXT (decl
) = NULL_TREE
;
2728 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
2729 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
2731 finish_decl (decl
, build_constructor (type
, nreverse (initlist
)),
2738 generate_method_descriptors (protocol
)
2741 tree initlist
, chain
, method_list_template
;
2742 tree cast
, variable_length_type
;
2745 if (!objc_method_prototype_template
)
2746 objc_method_prototype_template
= build_method_prototype_template ();
2748 cast
= build_tree_list (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2749 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
))),
2751 variable_length_type
= groktypename (cast
);
2753 chain
= PROTOCOL_CLS_METHODS (protocol
);
2756 size
= list_length (chain
);
2758 method_list_template
2759 = build_method_prototype_list_template (objc_method_prototype_template
,
2763 = build_descriptor_table_initializer (objc_method_prototype_template
,
2766 UOBJC_CLASS_METHODS_decl
2767 = generate_descriptor_table (method_list_template
,
2768 "_OBJC_PROTOCOL_CLASS_METHODS",
2769 size
, initlist
, protocol
);
2770 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
2773 UOBJC_CLASS_METHODS_decl
= 0;
2775 chain
= PROTOCOL_NST_METHODS (protocol
);
2778 size
= list_length (chain
);
2780 method_list_template
2781 = build_method_prototype_list_template (objc_method_prototype_template
,
2784 = build_descriptor_table_initializer (objc_method_prototype_template
,
2787 UOBJC_INSTANCE_METHODS_decl
2788 = generate_descriptor_table (method_list_template
,
2789 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2790 size
, initlist
, protocol
);
2791 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
2794 UOBJC_INSTANCE_METHODS_decl
= 0;
2797 /* Generate a temporary FUNCTION_DECL node to be used in
2798 hack_method_prototype below. */
2801 build_tmp_function_decl ()
2803 tree decl_specs
, expr_decl
, parms
;
2807 /* struct objc_object *objc_xxx (id, SEL, ...); */
2809 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
2810 push_parm_decl (build_tree_list
2811 (build_tree_list (decl_specs
,
2812 build1 (INDIRECT_REF
, NULL_TREE
,
2816 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2817 get_identifier (TAG_SELECTOR
)));
2818 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
);
2820 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, expr_decl
),
2822 parms
= get_parm_info (0);
2825 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
2826 sprintf (buffer
, "__objc_tmp_%x", xxx
++);
2827 expr_decl
= build_nt (CALL_EXPR
, get_identifier (buffer
), parms
, NULL_TREE
);
2828 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
2830 return define_decl (expr_decl
, decl_specs
);
2833 /* Generate the prototypes for protocol methods. This is used to
2834 generate method encodings for these.
2836 NST_METHODS is the method to generate a _DECL node for TMP_DECL is
2837 a decl node to be used. This is also where the return value is
2841 hack_method_prototype (nst_methods
, tmp_decl
)
2848 /* Hack to avoid problem with static typing of self arg. */
2849 TREE_SET_CODE (nst_methods
, CLASS_METHOD_DECL
);
2850 start_method_def (nst_methods
);
2851 TREE_SET_CODE (nst_methods
, INSTANCE_METHOD_DECL
);
2853 if (METHOD_ADD_ARGS (nst_methods
) == objc_ellipsis_node
)
2854 parms
= get_parm_info (0); /* we have a `, ...' */
2856 parms
= get_parm_info (1); /* place a `void_at_end' */
2858 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2860 /* Usually called from store_parm_decls -> init_function_start. */
2862 DECL_ARGUMENTS (tmp_decl
) = TREE_PURPOSE (parms
);
2864 if (current_function_decl
)
2866 current_function_decl
= tmp_decl
;
2869 /* Code taken from start_function. */
2870 tree restype
= TREE_TYPE (TREE_TYPE (tmp_decl
));
2871 /* Promote the value to int before returning it. */
2872 if (TREE_CODE (restype
) == INTEGER_TYPE
2873 && TYPE_PRECISION (restype
) < TYPE_PRECISION (integer_type_node
))
2874 restype
= integer_type_node
;
2875 DECL_RESULT (tmp_decl
) = build_decl (RESULT_DECL
, 0, restype
);
2878 for (parm
= DECL_ARGUMENTS (tmp_decl
); parm
; parm
= TREE_CHAIN (parm
))
2879 DECL_CONTEXT (parm
) = tmp_decl
;
2881 init_function_start (tmp_decl
, "objc-act", 0);
2883 /* Typically called from expand_function_start for function definitions. */
2884 assign_parms (tmp_decl
);
2886 /* install return type */
2887 TREE_TYPE (TREE_TYPE (tmp_decl
)) = groktypename (TREE_TYPE (nst_methods
));
2889 current_function_decl
= NULL
;
2893 generate_protocol_references (plist
)
2898 /* Forward declare protocols referenced. */
2899 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
2901 tree proto
= TREE_VALUE (lproto
);
2903 if (TREE_CODE (proto
) == PROTOCOL_INTERFACE_TYPE
2904 && PROTOCOL_NAME (proto
))
2906 if (! PROTOCOL_FORWARD_DECL (proto
))
2907 build_protocol_reference (proto
);
2909 if (PROTOCOL_LIST (proto
))
2910 generate_protocol_references (PROTOCOL_LIST (proto
));
2916 generate_protocols ()
2918 tree p
, tmp_decl
, encoding
;
2919 tree sc_spec
, decl_specs
, decl
;
2920 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
2923 tmp_decl
= build_tmp_function_decl ();
2925 if (! objc_protocol_template
)
2926 objc_protocol_template
= build_protocol_template ();
2928 /* If a protocol was directly referenced, pull in indirect references. */
2929 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
2930 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
2931 generate_protocol_references (PROTOCOL_LIST (p
));
2933 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
2935 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
2936 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
2938 /* If protocol wasn't referenced, don't generate any code. */
2939 if (! PROTOCOL_FORWARD_DECL (p
))
2942 /* Make sure we link in the Protocol class. */
2943 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
2947 if (! METHOD_ENCODING (nst_methods
))
2949 hack_method_prototype (nst_methods
, tmp_decl
);
2950 encoding
= encode_method_prototype (nst_methods
, tmp_decl
);
2951 METHOD_ENCODING (nst_methods
) = encoding
;
2953 nst_methods
= TREE_CHAIN (nst_methods
);
2958 if (! METHOD_ENCODING (cls_methods
))
2960 hack_method_prototype (cls_methods
, tmp_decl
);
2961 encoding
= encode_method_prototype (cls_methods
, tmp_decl
);
2962 METHOD_ENCODING (cls_methods
) = encoding
;
2965 cls_methods
= TREE_CHAIN (cls_methods
);
2967 generate_method_descriptors (p
);
2969 if (PROTOCOL_LIST (p
))
2970 refs_decl
= generate_protocol_list (p
);
2974 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
2976 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
],
2978 decl_specs
= tree_cons (NULL_TREE
, objc_protocol_template
, sc_spec
);
2980 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
),
2981 decl_specs
, 1, NULL_TREE
);
2983 DECL_CONTEXT (decl
) = NULL_TREE
;
2985 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
2991 (build_tree_list (build_tree_list (NULL_TREE
,
2992 objc_protocol_template
),
2993 build1 (INDIRECT_REF
, NULL_TREE
,
2994 build1 (INDIRECT_REF
, NULL_TREE
,
2997 refs_expr
= build_unary_op (ADDR_EXPR
, refs_decl
, 0);
2998 TREE_TYPE (refs_expr
) = cast_type2
;
3001 refs_expr
= build_int_2 (0, 0);
3003 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3004 by generate_method_descriptors, which is called above. */
3005 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
3006 protocol_name_expr
, refs_expr
,
3007 UOBJC_INSTANCE_METHODS_decl
,
3008 UOBJC_CLASS_METHODS_decl
);
3009 finish_decl (decl
, initlist
, NULL_TREE
);
3011 /* Mark the decl as used to avoid "defined but not used" warning. */
3012 TREE_USED (decl
) = 1;
3017 build_protocol_initializer (type
, protocol_name
, protocol_list
,
3018 instance_methods
, class_methods
)
3022 tree instance_methods
;
3025 tree initlist
= NULL_TREE
, expr
;
3028 cast_type
= groktypename
3030 (build_tree_list (NULL_TREE
,
3031 xref_tag (RECORD_TYPE
,
3032 get_identifier (UTAG_CLASS
))),
3033 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
3035 /* Filling the "isa" in with one allows the runtime system to
3036 detect that the version change...should remove before final release. */
3038 expr
= build_int_2 (PROTOCOL_VERSION
, 0);
3039 TREE_TYPE (expr
) = cast_type
;
3040 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3041 initlist
= tree_cons (NULL_TREE
, protocol_name
, initlist
);
3042 initlist
= tree_cons (NULL_TREE
, protocol_list
, initlist
);
3044 if (!instance_methods
)
3045 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3048 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
3049 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3053 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3056 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
3057 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3060 return build_constructor (type
, nreverse (initlist
));
3063 /* struct objc_category {
3064 char *category_name;
3066 struct objc_method_list *instance_methods;
3067 struct objc_method_list *class_methods;
3068 struct objc_protocol_list *protocols;
3072 build_category_template ()
3074 tree decl_specs
, field_decl
, field_decl_chain
;
3076 objc_category_template
= start_struct (RECORD_TYPE
,
3077 get_identifier (UTAG_CATEGORY
));
3078 /* char *category_name; */
3080 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3082 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("category_name"));
3084 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3085 field_decl_chain
= field_decl
;
3087 /* char *class_name; */
3089 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3090 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_name"));
3092 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3093 chainon (field_decl_chain
, field_decl
);
3095 /* struct objc_method_list *instance_methods; */
3097 decl_specs
= build_tree_list (NULL_TREE
,
3098 xref_tag (RECORD_TYPE
,
3099 get_identifier (UTAG_METHOD_LIST
)));
3101 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
3103 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3104 chainon (field_decl_chain
, field_decl
);
3106 /* struct objc_method_list *class_methods; */
3108 decl_specs
= build_tree_list (NULL_TREE
,
3109 xref_tag (RECORD_TYPE
,
3110 get_identifier (UTAG_METHOD_LIST
)));
3112 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
3114 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3115 chainon (field_decl_chain
, field_decl
);
3117 /* struct objc_protocol **protocol_list; */
3119 decl_specs
= build_tree_list (NULL_TREE
,
3120 xref_tag (RECORD_TYPE
,
3121 get_identifier (UTAG_PROTOCOL
)));
3123 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3124 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3126 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3127 chainon (field_decl_chain
, field_decl
);
3129 finish_struct (objc_category_template
, field_decl_chain
, NULL_TREE
);
3132 /* struct objc_selector {
3138 build_selector_template ()
3141 tree decl_specs
, field_decl
, field_decl_chain
;
3143 objc_selector_template
3144 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SELECTOR
));
3148 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3149 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3151 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3152 field_decl_chain
= field_decl
;
3154 /* char *sel_type; */
3156 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3157 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_type"));
3159 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3160 chainon (field_decl_chain
, field_decl
);
3162 finish_struct (objc_selector_template
, field_decl_chain
, NULL_TREE
);
3165 /* struct objc_class {
3166 struct objc_class *isa;
3167 struct objc_class *super_class;
3172 struct objc_ivar_list *ivars;
3173 struct objc_method_list *methods;
3174 if (flag_next_runtime)
3175 struct objc_cache *cache;
3177 struct sarray *dtable;
3178 struct objc_class *subclass_list;
3179 struct objc_class *sibling_class;
3181 struct objc_protocol_list *protocols;
3182 void *gc_object_type;
3186 build_class_template ()
3188 tree decl_specs
, field_decl
, field_decl_chain
;
3191 = start_struct (RECORD_TYPE
, get_identifier (UTAG_CLASS
));
3193 /* struct objc_class *isa; */
3195 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3196 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
3198 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3199 field_decl_chain
= field_decl
;
3201 /* struct objc_class *super_class; */
3203 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3205 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("super_class"));
3207 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3208 chainon (field_decl_chain
, field_decl
);
3212 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3213 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
3215 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3216 chainon (field_decl_chain
, field_decl
);
3220 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3221 field_decl
= get_identifier ("version");
3223 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3224 chainon (field_decl_chain
, field_decl
);
3228 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3229 field_decl
= get_identifier ("info");
3231 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3232 chainon (field_decl_chain
, field_decl
);
3234 /* long instance_size; */
3236 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3237 field_decl
= get_identifier ("instance_size");
3239 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3240 chainon (field_decl_chain
, field_decl
);
3242 /* struct objc_ivar_list *ivars; */
3244 decl_specs
= build_tree_list (NULL_TREE
,
3245 xref_tag (RECORD_TYPE
,
3246 get_identifier (UTAG_IVAR_LIST
)));
3247 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivars"));
3249 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3250 chainon (field_decl_chain
, field_decl
);
3252 /* struct objc_method_list *methods; */
3254 decl_specs
= build_tree_list (NULL_TREE
,
3255 xref_tag (RECORD_TYPE
,
3256 get_identifier (UTAG_METHOD_LIST
)));
3257 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("methods"));
3259 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3260 chainon (field_decl_chain
, field_decl
);
3262 if (flag_next_runtime
)
3264 /* struct objc_cache *cache; */
3266 decl_specs
= build_tree_list (NULL_TREE
,
3267 xref_tag (RECORD_TYPE
,
3268 get_identifier ("objc_cache")));
3269 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("cache"));
3270 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3271 decl_specs
, NULL_TREE
);
3272 chainon (field_decl_chain
, field_decl
);
3276 /* struct sarray *dtable; */
3278 decl_specs
= build_tree_list (NULL_TREE
,
3279 xref_tag (RECORD_TYPE
,
3280 get_identifier ("sarray")));
3281 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("dtable"));
3282 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3283 decl_specs
, NULL_TREE
);
3284 chainon (field_decl_chain
, field_decl
);
3286 /* struct objc_class *subclass_list; */
3288 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3290 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("subclass_list"));
3291 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3292 decl_specs
, NULL_TREE
);
3293 chainon (field_decl_chain
, field_decl
);
3295 /* struct objc_class *sibling_class; */
3297 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3299 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sibling_class"));
3300 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3301 decl_specs
, NULL_TREE
);
3302 chainon (field_decl_chain
, field_decl
);
3305 /* struct objc_protocol **protocol_list; */
3307 decl_specs
= build_tree_list (NULL_TREE
,
3308 xref_tag (RECORD_TYPE
,
3309 get_identifier (UTAG_PROTOCOL
)));
3311 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3313 = build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3314 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3315 decl_specs
, NULL_TREE
);
3316 chainon (field_decl_chain
, field_decl
);
3320 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3321 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3323 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3324 chainon (field_decl_chain
, field_decl
);
3326 /* void *gc_object_type; */
3328 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3329 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("gc_object_type"));
3331 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3332 chainon (field_decl_chain
, field_decl
);
3334 finish_struct (objc_class_template
, field_decl_chain
, NULL_TREE
);
3337 /* Generate appropriate forward declarations for an implementation. */
3340 synth_forward_declarations ()
3342 tree sc_spec
, decl_specs
, an_id
;
3344 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3346 an_id
= synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context
);
3348 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
3349 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
3350 UOBJC_CLASS_decl
= define_decl (an_id
, decl_specs
);
3351 TREE_USED (UOBJC_CLASS_decl
) = 1;
3352 DECL_ARTIFICIAL (UOBJC_CLASS_decl
) = 1;
3354 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3356 an_id
= synth_id_with_class_suffix ("_OBJC_METACLASS",
3357 objc_implementation_context
);
3359 UOBJC_METACLASS_decl
= define_decl (an_id
, decl_specs
);
3360 TREE_USED (UOBJC_METACLASS_decl
) = 1;
3361 DECL_ARTIFICIAL(UOBJC_METACLASS_decl
) = 1;
3363 /* Pre-build the following entities - for speed/convenience. */
3365 an_id
= get_identifier ("super_class");
3366 ucls_super_ref
= build_component_ref (UOBJC_CLASS_decl
, an_id
);
3367 uucls_super_ref
= build_component_ref (UOBJC_METACLASS_decl
, an_id
);
3371 error_with_ivar (message
, decl
, rawdecl
)
3372 const char *message
;
3376 diagnostic_count_diagnostic (global_dc
, DK_ERROR
);
3378 diagnostic_report_current_function (global_dc
);
3380 error_with_file_and_line (DECL_SOURCE_FILE (decl
),
3381 DECL_SOURCE_LINE (decl
),
3383 message
, gen_declaration (rawdecl
, errbuf
));
3388 check_ivars (inter
, imp
)
3392 tree intdecls
= CLASS_IVARS (inter
);
3393 tree impdecls
= CLASS_IVARS (imp
);
3394 tree rawintdecls
= CLASS_RAW_IVARS (inter
);
3395 tree rawimpdecls
= CLASS_RAW_IVARS (imp
);
3401 if (intdecls
== 0 && impdecls
== 0)
3403 if (intdecls
== 0 || impdecls
== 0)
3405 error ("inconsistent instance variable specification");
3409 t1
= TREE_TYPE (intdecls
); t2
= TREE_TYPE (impdecls
);
3411 if (!comptypes (t1
, t2
))
3413 if (DECL_NAME (intdecls
) == DECL_NAME (impdecls
))
3415 error_with_ivar ("conflicting instance variable type",
3416 impdecls
, rawimpdecls
);
3417 error_with_ivar ("previous declaration of",
3418 intdecls
, rawintdecls
);
3420 else /* both the type and the name don't match */
3422 error ("inconsistent instance variable specification");
3427 else if (DECL_NAME (intdecls
) != DECL_NAME (impdecls
))
3429 error_with_ivar ("conflicting instance variable name",
3430 impdecls
, rawimpdecls
);
3431 error_with_ivar ("previous declaration of",
3432 intdecls
, rawintdecls
);
3435 intdecls
= TREE_CHAIN (intdecls
);
3436 impdecls
= TREE_CHAIN (impdecls
);
3437 rawintdecls
= TREE_CHAIN (rawintdecls
);
3438 rawimpdecls
= TREE_CHAIN (rawimpdecls
);
3442 /* Set super_type to the data type node for struct objc_super *,
3443 first defining struct objc_super itself.
3444 This needs to be done just once per compilation. */
3447 build_super_template ()
3449 tree record
, decl_specs
, field_decl
, field_decl_chain
;
3451 record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_SUPER
));
3453 /* struct objc_object *self; */
3455 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3456 field_decl
= get_identifier ("self");
3457 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3458 field_decl
= grokfield (input_filename
, lineno
,
3459 field_decl
, decl_specs
, NULL_TREE
);
3460 field_decl_chain
= field_decl
;
3462 /* struct objc_class *class; */
3464 decl_specs
= get_identifier (UTAG_CLASS
);
3465 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
3466 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class"));
3468 field_decl
= grokfield (input_filename
, lineno
,
3469 field_decl
, decl_specs
, NULL_TREE
);
3470 chainon (field_decl_chain
, field_decl
);
3472 finish_struct (record
, field_decl_chain
, NULL_TREE
);
3474 /* `struct objc_super *' */
3475 super_type
= groktypename (build_tree_list (build_tree_list (NULL_TREE
,
3477 build1 (INDIRECT_REF
,
3478 NULL_TREE
, NULL_TREE
)));
3482 /* struct objc_ivar {
3489 build_ivar_template ()
3491 tree objc_ivar_id
, objc_ivar_record
;
3492 tree decl_specs
, field_decl
, field_decl_chain
;
3494 objc_ivar_id
= get_identifier (UTAG_IVAR
);
3495 objc_ivar_record
= start_struct (RECORD_TYPE
, objc_ivar_id
);
3497 /* char *ivar_name; */
3499 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3500 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_name"));
3502 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3503 decl_specs
, NULL_TREE
);
3504 field_decl_chain
= field_decl
;
3506 /* char *ivar_type; */
3508 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3509 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_type"));
3511 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3512 decl_specs
, NULL_TREE
);
3513 chainon (field_decl_chain
, field_decl
);
3515 /* int ivar_offset; */
3517 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3518 field_decl
= get_identifier ("ivar_offset");
3520 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3521 decl_specs
, NULL_TREE
);
3522 chainon (field_decl_chain
, field_decl
);
3524 finish_struct (objc_ivar_record
, field_decl_chain
, NULL_TREE
);
3526 return objc_ivar_record
;
3531 struct objc_ivar ivar_list[ivar_count];
3535 build_ivar_list_template (list_type
, size
)
3539 tree objc_ivar_list_record
;
3540 tree decl_specs
, field_decl
, field_decl_chain
;
3542 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3544 /* int ivar_count; */
3546 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3547 field_decl
= get_identifier ("ivar_count");
3549 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3550 decl_specs
, NULL_TREE
);
3551 field_decl_chain
= field_decl
;
3553 /* struct objc_ivar ivar_list[]; */
3555 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3556 field_decl
= build_nt (ARRAY_REF
, get_identifier ("ivar_list"),
3557 build_int_2 (size
, 0));
3559 field_decl
= grokfield (input_filename
, lineno
,
3560 field_decl
, decl_specs
, NULL_TREE
);
3561 chainon (field_decl_chain
, field_decl
);
3563 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3565 return objc_ivar_list_record
;
3571 struct objc_method method_list[method_count];
3575 build_method_list_template (list_type
, size
)
3579 tree objc_ivar_list_record
;
3580 tree decl_specs
, field_decl
, field_decl_chain
;
3582 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3584 /* int method_next; */
3589 xref_tag (RECORD_TYPE
,
3590 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
3592 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_next"));
3593 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3594 decl_specs
, NULL_TREE
);
3595 field_decl_chain
= field_decl
;
3597 /* int method_count; */
3599 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3600 field_decl
= get_identifier ("method_count");
3602 field_decl
= grokfield (input_filename
, lineno
,
3603 field_decl
, decl_specs
, NULL_TREE
);
3604 chainon (field_decl_chain
, field_decl
);
3606 /* struct objc_method method_list[]; */
3608 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3609 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
3610 build_int_2 (size
, 0));
3612 field_decl
= grokfield (input_filename
, lineno
,
3613 field_decl
, decl_specs
, NULL_TREE
);
3614 chainon (field_decl_chain
, field_decl
);
3616 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3618 return objc_ivar_list_record
;
3622 build_ivar_list_initializer (type
, field_decl
)
3626 tree initlist
= NULL_TREE
;
3630 tree ivar
= NULL_TREE
;
3633 if (DECL_NAME (field_decl
))
3634 ivar
= tree_cons (NULL_TREE
,
3635 add_objc_string (DECL_NAME (field_decl
),
3639 /* Unnamed bit-field ivar (yuck). */
3640 ivar
= tree_cons (NULL_TREE
, build_int_2 (0, 0), ivar
);
3643 encode_field_decl (field_decl
,
3644 obstack_object_size (&util_obstack
),
3645 OBJC_ENCODE_DONT_INLINE_DEFS
);
3647 /* Null terminate string. */
3648 obstack_1grow (&util_obstack
, 0);
3652 add_objc_string (get_identifier (obstack_finish (&util_obstack
)),
3655 obstack_free (&util_obstack
, util_firstobj
);
3658 ivar
= tree_cons (NULL_TREE
, byte_position (field_decl
), ivar
);
3659 initlist
= tree_cons (NULL_TREE
,
3660 build_constructor (type
, nreverse (ivar
)),
3663 field_decl
= TREE_CHAIN (field_decl
);
3667 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3671 generate_ivars_list (type
, name
, size
, list
)
3677 tree sc_spec
, decl_specs
, decl
, initlist
;
3679 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3680 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
3682 decl
= start_decl (synth_id_with_class_suffix (name
, objc_implementation_context
),
3683 decl_specs
, 1, NULL_TREE
);
3685 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
3686 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3689 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3696 generate_ivar_lists ()
3698 tree initlist
, ivar_list_template
, chain
;
3699 tree cast
, variable_length_type
;
3702 generating_instance_variables
= 1;
3704 if (!objc_ivar_template
)
3705 objc_ivar_template
= build_ivar_template ();
3709 (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3710 get_identifier (UTAG_IVAR_LIST
))),
3712 variable_length_type
= groktypename (cast
);
3714 /* Only generate class variables for the root of the inheritance
3715 hierarchy since these will be the same for every class. */
3717 if (CLASS_SUPER_NAME (implementation_template
) == NULL_TREE
3718 && (chain
= TYPE_FIELDS (objc_class_template
)))
3720 size
= list_length (chain
);
3722 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3723 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3725 UOBJC_CLASS_VARIABLES_decl
3726 = generate_ivars_list (ivar_list_template
, "_OBJC_CLASS_VARIABLES",
3728 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl
) = variable_length_type
;
3731 UOBJC_CLASS_VARIABLES_decl
= 0;
3733 chain
= CLASS_IVARS (implementation_template
);
3736 size
= list_length (chain
);
3737 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3738 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3740 UOBJC_INSTANCE_VARIABLES_decl
3741 = generate_ivars_list (ivar_list_template
, "_OBJC_INSTANCE_VARIABLES",
3743 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl
) = variable_length_type
;
3746 UOBJC_INSTANCE_VARIABLES_decl
= 0;
3748 generating_instance_variables
= 0;
3752 build_dispatch_table_initializer (type
, entries
)
3756 tree initlist
= NULL_TREE
;
3760 tree elemlist
= NULL_TREE
;
3762 elemlist
= tree_cons (NULL_TREE
,
3763 build_selector (METHOD_SEL_NAME (entries
)),
3766 /* Generate the method encoding if we don't have one already. */
3767 if (! METHOD_ENCODING (entries
))
3768 METHOD_ENCODING (entries
) =
3769 encode_method_def (METHOD_DEFINITION (entries
));
3771 elemlist
= tree_cons (NULL_TREE
,
3772 add_objc_string (METHOD_ENCODING (entries
),
3776 elemlist
= tree_cons (NULL_TREE
,
3777 build_unary_op (ADDR_EXPR
,
3778 METHOD_DEFINITION (entries
), 1),
3781 initlist
= tree_cons (NULL_TREE
,
3782 build_constructor (type
, nreverse (elemlist
)),
3785 entries
= TREE_CHAIN (entries
);
3789 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3792 /* To accomplish method prototyping without generating all kinds of
3793 inane warnings, the definition of the dispatch table entries were
3796 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3798 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3801 build_method_template ()
3804 tree decl_specs
, field_decl
, field_decl_chain
;
3806 _SLT_record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD
));
3808 /* struct objc_selector *_cmd; */
3809 decl_specs
= tree_cons (NULL_TREE
,
3810 xref_tag (RECORD_TYPE
,
3811 get_identifier (TAG_SELECTOR
)),
3813 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
3815 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3816 decl_specs
, NULL_TREE
);
3817 field_decl_chain
= field_decl
;
3819 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
3820 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
,
3821 get_identifier ("method_types"));
3822 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3823 decl_specs
, NULL_TREE
);
3824 chainon (field_decl_chain
, field_decl
);
3828 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_VOID
], NULL_TREE
);
3829 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_imp"));
3830 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3831 decl_specs
, NULL_TREE
);
3832 chainon (field_decl_chain
, field_decl
);
3834 finish_struct (_SLT_record
, field_decl_chain
, NULL_TREE
);
3841 generate_dispatch_table (type
, name
, size
, list
)
3847 tree sc_spec
, decl_specs
, decl
, initlist
;
3849 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3850 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
3852 decl
= start_decl (synth_id_with_class_suffix (name
, objc_implementation_context
),
3853 decl_specs
, 1, NULL_TREE
);
3855 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
3856 initlist
= tree_cons (NULL_TREE
, build_int_2 (size
, 0), initlist
);
3857 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3860 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3867 generate_dispatch_tables ()
3869 tree initlist
, chain
, method_list_template
;
3870 tree cast
, variable_length_type
;
3873 if (!objc_method_template
)
3874 objc_method_template
= build_method_template ();
3878 (build_tree_list (NULL_TREE
,
3879 xref_tag (RECORD_TYPE
,
3880 get_identifier (UTAG_METHOD_LIST
))),
3883 variable_length_type
= groktypename (cast
);
3885 chain
= CLASS_CLS_METHODS (objc_implementation_context
);
3888 size
= list_length (chain
);
3890 method_list_template
3891 = build_method_list_template (objc_method_template
, size
);
3893 = build_dispatch_table_initializer (objc_method_template
, chain
);
3895 UOBJC_CLASS_METHODS_decl
3896 = generate_dispatch_table (method_list_template
,
3897 ((TREE_CODE (objc_implementation_context
)
3898 == CLASS_IMPLEMENTATION_TYPE
)
3899 ? "_OBJC_CLASS_METHODS"
3900 : "_OBJC_CATEGORY_CLASS_METHODS"),
3902 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
3905 UOBJC_CLASS_METHODS_decl
= 0;
3907 chain
= CLASS_NST_METHODS (objc_implementation_context
);
3910 size
= list_length (chain
);
3912 method_list_template
3913 = build_method_list_template (objc_method_template
, size
);
3915 = build_dispatch_table_initializer (objc_method_template
, chain
);
3917 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
3918 UOBJC_INSTANCE_METHODS_decl
3919 = generate_dispatch_table (method_list_template
,
3920 "_OBJC_INSTANCE_METHODS",
3923 /* We have a category. */
3924 UOBJC_INSTANCE_METHODS_decl
3925 = generate_dispatch_table (method_list_template
,
3926 "_OBJC_CATEGORY_INSTANCE_METHODS",
3928 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
3931 UOBJC_INSTANCE_METHODS_decl
= 0;
3935 generate_protocol_list (i_or_p
)
3938 tree initlist
, decl_specs
, sc_spec
;
3939 tree refs_decl
, expr_decl
, lproto
, e
, plist
;
3943 if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
3944 || TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
3945 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
3946 else if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
3947 plist
= PROTOCOL_LIST (i_or_p
);
3951 cast_type
= groktypename
3953 (build_tree_list (NULL_TREE
,
3954 xref_tag (RECORD_TYPE
,
3955 get_identifier (UTAG_PROTOCOL
))),
3956 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
3959 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
3960 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
3961 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
3964 /* Build initializer. */
3965 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), NULL_TREE
);
3967 e
= build_int_2 (size
, 0);
3968 TREE_TYPE (e
) = cast_type
;
3969 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
3971 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
3973 tree pval
= TREE_VALUE (lproto
);
3975 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
3976 && PROTOCOL_FORWARD_DECL (pval
))
3978 e
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (pval
), 0);
3979 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
3983 /* static struct objc_protocol *refs[n]; */
3985 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3986 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
3987 get_identifier (UTAG_PROTOCOL
)),
3990 if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
3991 expr_decl
= build_nt (ARRAY_REF
,
3992 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
3994 build_int_2 (size
+ 2, 0));
3995 else if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
)
3996 expr_decl
= build_nt (ARRAY_REF
,
3997 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
3999 build_int_2 (size
+ 2, 0));
4000 else if (TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4002 = build_nt (ARRAY_REF
,
4003 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4005 build_int_2 (size
+ 2, 0));
4009 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
4011 refs_decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
4012 DECL_CONTEXT (refs_decl
) = NULL_TREE
;
4014 finish_decl (refs_decl
, build_constructor (TREE_TYPE (refs_decl
),
4015 nreverse (initlist
)),
4022 build_category_initializer (type
, cat_name
, class_name
,
4023 instance_methods
, class_methods
, protocol_list
)
4027 tree instance_methods
;
4031 tree initlist
= NULL_TREE
, expr
;
4033 initlist
= tree_cons (NULL_TREE
, cat_name
, initlist
);
4034 initlist
= tree_cons (NULL_TREE
, class_name
, initlist
);
4036 if (!instance_methods
)
4037 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4040 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
4041 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4044 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4047 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
4048 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4051 /* protocol_list = */
4053 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4056 tree cast_type2
= groktypename
4058 (build_tree_list (NULL_TREE
,
4059 xref_tag (RECORD_TYPE
,
4060 get_identifier (UTAG_PROTOCOL
))),
4061 build1 (INDIRECT_REF
, NULL_TREE
,
4062 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4064 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4065 TREE_TYPE (expr
) = cast_type2
;
4066 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4069 return build_constructor (type
, nreverse (initlist
));
4072 /* struct objc_class {
4073 struct objc_class *isa;
4074 struct objc_class *super_class;
4079 struct objc_ivar_list *ivars;
4080 struct objc_method_list *methods;
4081 if (flag_next_runtime)
4082 struct objc_cache *cache;
4084 struct sarray *dtable;
4085 struct objc_class *subclass_list;
4086 struct objc_class *sibling_class;
4088 struct objc_protocol_list *protocols;
4089 void *gc_object_type;
4093 build_shared_structure_initializer (type
, isa
, super
, name
, size
, status
,
4094 dispatch_table
, ivar_list
, protocol_list
)
4101 tree dispatch_table
;
4105 tree initlist
= NULL_TREE
, expr
;
4108 initlist
= tree_cons (NULL_TREE
, isa
, initlist
);
4111 initlist
= tree_cons (NULL_TREE
, super
, initlist
);
4114 initlist
= tree_cons (NULL_TREE
, default_conversion (name
), initlist
);
4117 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4120 initlist
= tree_cons (NULL_TREE
, build_int_2 (status
, 0), initlist
);
4122 /* instance_size = */
4123 initlist
= tree_cons (NULL_TREE
, size
, initlist
);
4125 /* objc_ivar_list = */
4127 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4130 expr
= build_unary_op (ADDR_EXPR
, ivar_list
, 0);
4131 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4134 /* objc_method_list = */
4135 if (!dispatch_table
)
4136 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4139 expr
= build_unary_op (ADDR_EXPR
, dispatch_table
, 0);
4140 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4143 if (flag_next_runtime
)
4144 /* method_cache = */
4145 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4149 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4151 /* subclass_list = */
4152 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4154 /* sibling_class = */
4155 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4158 /* protocol_list = */
4159 if (! protocol_list
)
4160 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4166 (build_tree_list (NULL_TREE
,
4167 xref_tag (RECORD_TYPE
,
4168 get_identifier (UTAG_PROTOCOL
))),
4169 build1 (INDIRECT_REF
, NULL_TREE
,
4170 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4172 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4173 TREE_TYPE (expr
) = cast_type2
;
4174 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4177 /* gc_object_type = NULL */
4178 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4180 return build_constructor (type
, nreverse (initlist
));
4183 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4186 generate_category (cat
)
4189 tree sc_spec
, decl_specs
, decl
;
4190 tree initlist
, cat_name_expr
, class_name_expr
;
4191 tree protocol_decl
, category
;
4193 add_class_reference (CLASS_NAME (cat
));
4194 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
4196 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
4198 category
= CLASS_CATEGORY_LIST (implementation_template
);
4200 /* find the category interface from the class it is associated with */
4203 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
4205 category
= CLASS_CATEGORY_LIST (category
);
4208 if (category
&& CLASS_PROTOCOL_LIST (category
))
4210 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
4211 protocol_decl
= generate_protocol_list (category
);
4216 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4217 decl_specs
= tree_cons (NULL_TREE
, objc_category_template
, sc_spec
);
4219 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4220 objc_implementation_context
),
4221 decl_specs
, 1, NULL_TREE
);
4223 initlist
= build_category_initializer (TREE_TYPE (decl
),
4224 cat_name_expr
, class_name_expr
,
4225 UOBJC_INSTANCE_METHODS_decl
,
4226 UOBJC_CLASS_METHODS_decl
,
4229 TREE_USED (decl
) = 1;
4230 finish_decl (decl
, initlist
, NULL_TREE
);
4233 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4234 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4237 generate_shared_structures ()
4239 tree sc_spec
, decl_specs
, decl
;
4240 tree name_expr
, super_expr
, root_expr
;
4241 tree my_root_id
= NULL_TREE
, my_super_id
= NULL_TREE
;
4242 tree cast_type
, initlist
, protocol_decl
;
4244 my_super_id
= CLASS_SUPER_NAME (implementation_template
);
4247 add_class_reference (my_super_id
);
4249 /* Compute "my_root_id" - this is required for code generation.
4250 the "isa" for all meta class structures points to the root of
4251 the inheritance hierarchy (e.g. "__Object")... */
4252 my_root_id
= my_super_id
;
4255 tree my_root_int
= lookup_interface (my_root_id
);
4257 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
4258 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
4265 /* No super class. */
4266 my_root_id
= CLASS_NAME (implementation_template
);
4269 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
4270 objc_class_template
),
4271 build1 (INDIRECT_REF
,
4272 NULL_TREE
, NULL_TREE
)));
4274 name_expr
= add_objc_string (CLASS_NAME (implementation_template
),
4277 /* Install class `isa' and `super' pointers at runtime. */
4280 super_expr
= add_objc_string (my_super_id
, class_names
);
4281 super_expr
= build_c_cast (cast_type
, super_expr
); /* cast! */
4284 super_expr
= build_int_2 (0, 0);
4286 root_expr
= add_objc_string (my_root_id
, class_names
);
4287 root_expr
= build_c_cast (cast_type
, root_expr
); /* cast! */
4289 if (CLASS_PROTOCOL_LIST (implementation_template
))
4291 generate_protocol_references
4292 (CLASS_PROTOCOL_LIST (implementation_template
));
4293 protocol_decl
= generate_protocol_list (implementation_template
);
4298 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4300 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
4301 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
4303 decl
= start_decl (DECL_NAME (UOBJC_METACLASS_decl
), decl_specs
, 1,
4307 = build_shared_structure_initializer
4309 root_expr
, super_expr
, name_expr
,
4310 convert (integer_type_node
, TYPE_SIZE_UNIT (objc_class_template
)),
4312 UOBJC_CLASS_METHODS_decl
,
4313 UOBJC_CLASS_VARIABLES_decl
,
4316 finish_decl (decl
, initlist
, NULL_TREE
);
4318 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4320 decl
= start_decl (DECL_NAME (UOBJC_CLASS_decl
), decl_specs
, 1,
4324 = build_shared_structure_initializer
4326 build_unary_op (ADDR_EXPR
, UOBJC_METACLASS_decl
, 0),
4327 super_expr
, name_expr
,
4328 convert (integer_type_node
,
4329 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4330 (implementation_template
))),
4332 UOBJC_INSTANCE_METHODS_decl
,
4333 UOBJC_INSTANCE_VARIABLES_decl
,
4336 finish_decl (decl
, initlist
, NULL_TREE
);
4340 synth_id_with_class_suffix (preamble
, ctxt
)
4341 const char *preamble
;
4345 if (TREE_CODE (ctxt
) == CLASS_IMPLEMENTATION_TYPE
4346 || TREE_CODE (ctxt
) == CLASS_INTERFACE_TYPE
)
4348 const char *const class_name
4349 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
4350 string
= (char *) alloca (strlen (preamble
) + strlen (class_name
) + 3);
4351 sprintf (string
, "%s_%s", preamble
,
4352 IDENTIFIER_POINTER (CLASS_NAME (ctxt
)));
4354 else if (TREE_CODE (ctxt
) == CATEGORY_IMPLEMENTATION_TYPE
4355 || TREE_CODE (ctxt
) == CATEGORY_INTERFACE_TYPE
)
4357 /* We have a category. */
4358 const char *const class_name
4359 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
4360 const char *const class_super_name
4361 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
));
4362 string
= (char *) alloca (strlen (preamble
)
4363 + strlen (class_name
)
4364 + strlen (class_super_name
)
4366 sprintf (string
, "%s_%s_%s", preamble
, class_name
, class_super_name
);
4368 else if (TREE_CODE (ctxt
) == PROTOCOL_INTERFACE_TYPE
)
4370 const char *protocol_name
= IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt
));
4372 = (char *) alloca (strlen (preamble
) + strlen (protocol_name
) + 3);
4373 sprintf (string
, "%s_%s", preamble
, protocol_name
);
4378 return get_identifier (string
);
4382 is_objc_type_qualifier (node
)
4385 return (TREE_CODE (node
) == IDENTIFIER_NODE
4386 && (node
== ridpointers
[(int) RID_CONST
]
4387 || node
== ridpointers
[(int) RID_VOLATILE
]
4388 || node
== ridpointers
[(int) RID_IN
]
4389 || node
== ridpointers
[(int) RID_OUT
]
4390 || node
== ridpointers
[(int) RID_INOUT
]
4391 || node
== ridpointers
[(int) RID_BYCOPY
]
4392 || node
== ridpointers
[(int) RID_BYREF
]
4393 || node
== ridpointers
[(int) RID_ONEWAY
]));
4396 /* If type is empty or only type qualifiers are present, add default
4397 type of id (otherwise grokdeclarator will default to int). */
4400 adjust_type_for_id_default (type
)
4403 tree declspecs
, chain
;
4406 return build_tree_list (build_tree_list (NULL_TREE
, objc_object_reference
),
4407 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4409 declspecs
= TREE_PURPOSE (type
);
4411 /* Determine if a typespec is present. */
4412 for (chain
= declspecs
;
4414 chain
= TREE_CHAIN (chain
))
4416 if (TYPED_OBJECT (TREE_VALUE (chain
))
4417 && !(TREE_VALUE (type
)
4418 && TREE_CODE (TREE_VALUE (type
)) == INDIRECT_REF
))
4419 error ("can not use an object as parameter to a method\n");
4420 if (!is_objc_type_qualifier (TREE_VALUE (chain
)))
4424 return build_tree_list (tree_cons (NULL_TREE
, objc_object_reference
,
4426 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4431 selector ':' '(' typename ')' identifier
4434 Transform an Objective-C keyword argument into
4435 the C equivalent parameter declarator.
4437 In: key_name, an "identifier_node" (optional).
4438 arg_type, a "tree_list" (optional).
4439 arg_name, an "identifier_node".
4441 Note: It would be really nice to strongly type the preceding
4442 arguments in the function prototype; however, then I
4443 could not use the "accessor" macros defined in "tree.h".
4445 Out: an instance of "keyword_decl". */
4448 build_keyword_decl (key_name
, arg_type
, arg_name
)
4455 /* If no type is specified, default to "id". */
4456 arg_type
= adjust_type_for_id_default (arg_type
);
4458 keyword_decl
= make_node (KEYWORD_DECL
);
4460 TREE_TYPE (keyword_decl
) = arg_type
;
4461 KEYWORD_ARG_NAME (keyword_decl
) = arg_name
;
4462 KEYWORD_KEY_NAME (keyword_decl
) = key_name
;
4464 return keyword_decl
;
4467 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4470 build_keyword_selector (selector
)
4474 tree key_chain
, key_name
;
4477 /* Scan the selector to see how much space we'll need. */
4478 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4480 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4481 key_name
= KEYWORD_KEY_NAME (key_chain
);
4482 else if (TREE_CODE (selector
) == TREE_LIST
)
4483 key_name
= TREE_PURPOSE (key_chain
);
4488 len
+= IDENTIFIER_LENGTH (key_name
) + 1;
4490 /* Just a ':' arg. */
4494 buf
= (char *) alloca (len
+ 1);
4495 /* Start the buffer out as an empty string. */
4498 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4500 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4501 key_name
= KEYWORD_KEY_NAME (key_chain
);
4502 else if (TREE_CODE (selector
) == TREE_LIST
)
4503 key_name
= TREE_PURPOSE (key_chain
);
4508 strcat (buf
, IDENTIFIER_POINTER (key_name
));
4512 return get_identifier (buf
);
4515 /* Used for declarations and definitions. */
4518 build_method_decl (code
, ret_type
, selector
, add_args
)
4519 enum tree_code code
;
4526 /* If no type is specified, default to "id". */
4527 ret_type
= adjust_type_for_id_default (ret_type
);
4529 method_decl
= make_node (code
);
4530 TREE_TYPE (method_decl
) = ret_type
;
4532 /* If we have a keyword selector, create an identifier_node that
4533 represents the full selector name (`:' included)... */
4534 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4536 METHOD_SEL_NAME (method_decl
) = build_keyword_selector (selector
);
4537 METHOD_SEL_ARGS (method_decl
) = selector
;
4538 METHOD_ADD_ARGS (method_decl
) = add_args
;
4542 METHOD_SEL_NAME (method_decl
) = selector
;
4543 METHOD_SEL_ARGS (method_decl
) = NULL_TREE
;
4544 METHOD_ADD_ARGS (method_decl
) = NULL_TREE
;
4550 #define METHOD_DEF 0
4551 #define METHOD_REF 1
4553 /* Used by `build_objc_method_call' and `comp_method_types'. Return
4554 an argument list for method METH. CONTEXT is either METHOD_DEF or
4555 METHOD_REF, saying whether we are trying to define a method or call
4556 one. SUPERFLAG says this is for a send to super; this makes a
4557 difference for the NeXT calling sequence in which the lookup and
4558 the method call are done together. */
4561 get_arg_type_list (meth
, context
, superflag
)
4568 /* Receiver type. */
4569 if (flag_next_runtime
&& superflag
)
4570 arglist
= build_tree_list (NULL_TREE
, super_type
);
4571 else if (context
== METHOD_DEF
)
4572 arglist
= build_tree_list (NULL_TREE
, TREE_TYPE (self_decl
));
4574 arglist
= build_tree_list (NULL_TREE
, id_type
);
4576 /* Selector type - will eventually change to `int'. */
4577 chainon (arglist
, build_tree_list (NULL_TREE
, selector_type
));
4579 /* Build a list of argument types. */
4580 for (akey
= METHOD_SEL_ARGS (meth
); akey
; akey
= TREE_CHAIN (akey
))
4582 tree arg_decl
= groktypename_in_parm_context (TREE_TYPE (akey
));
4583 chainon (arglist
, build_tree_list (NULL_TREE
, TREE_TYPE (arg_decl
)));
4586 if (METHOD_ADD_ARGS (meth
) == objc_ellipsis_node
)
4587 /* We have a `, ...' immediately following the selector,
4588 finalize the arglist...simulate get_parm_info (0). */
4590 else if (METHOD_ADD_ARGS (meth
))
4592 /* we have a variable length selector */
4593 tree add_arg_list
= TREE_CHAIN (METHOD_ADD_ARGS (meth
));
4594 chainon (arglist
, add_arg_list
);
4597 /* finalize the arglist...simulate get_parm_info (1) */
4598 chainon (arglist
, build_tree_list (NULL_TREE
, void_type_node
));
4604 check_duplicates (hsh
)
4607 tree meth
= NULL_TREE
;
4615 /* We have two methods with the same name and different types. */
4617 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
) ? '-' : '+';
4619 warning ("multiple declarations for method `%s'",
4620 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
4622 warn_with_method ("using", type
, meth
);
4623 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
4624 warn_with_method ("also found", type
, loop
->value
);
4630 /* If RECEIVER is a class reference, return the identifier node for
4631 the referenced class. RECEIVER is created by get_class_reference,
4632 so we check the exact form created depending on which runtimes are
4636 receiver_is_class_object (receiver
)
4639 tree chain
, exp
, arg
;
4641 /* The receiver is 'self' in the context of a class method. */
4642 if (objc_method_context
4643 && receiver
== self_decl
4644 && TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
4646 return CLASS_NAME (objc_implementation_context
);
4649 if (flag_next_runtime
)
4651 /* The receiver is a variable created by
4652 build_class_reference_decl. */
4653 if (TREE_CODE (receiver
) == VAR_DECL
4654 && TREE_TYPE (receiver
) == objc_class_type
)
4655 /* Look up the identifier. */
4656 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
4657 if (TREE_PURPOSE (chain
) == receiver
)
4658 return TREE_VALUE (chain
);
4662 /* The receiver is a function call that returns an id. Check if
4663 it is a call to objc_getClass, if so, pick up the class name. */
4664 if (TREE_CODE (receiver
) == CALL_EXPR
4665 && (exp
= TREE_OPERAND (receiver
, 0))
4666 && TREE_CODE (exp
) == ADDR_EXPR
4667 && (exp
= TREE_OPERAND (exp
, 0))
4668 && TREE_CODE (exp
) == FUNCTION_DECL
4669 && exp
== objc_get_class_decl
4670 /* We have a call to objc_getClass! */
4671 && (arg
= TREE_OPERAND (receiver
, 1))
4672 && TREE_CODE (arg
) == TREE_LIST
4673 && (arg
= TREE_VALUE (arg
)))
4676 if (TREE_CODE (arg
) == ADDR_EXPR
4677 && (arg
= TREE_OPERAND (arg
, 0))
4678 && TREE_CODE (arg
) == STRING_CST
)
4679 /* Finally, we have the class name. */
4680 return get_identifier (TREE_STRING_POINTER (arg
));
4686 /* If we are currently building a message expr, this holds
4687 the identifier of the selector of the message. This is
4688 used when printing warnings about argument mismatches. */
4690 static tree building_objc_message_expr
= 0;
4693 maybe_building_objc_message_expr ()
4695 return building_objc_message_expr
;
4698 /* Construct an expression for sending a message.
4699 MESS has the object to send to in TREE_PURPOSE
4700 and the argument list (including selector) in TREE_VALUE.
4702 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4703 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4706 build_message_expr (mess
)
4709 tree receiver
= TREE_PURPOSE (mess
);
4711 tree args
= TREE_VALUE (mess
);
4712 tree method_params
= NULL_TREE
;
4714 if (TREE_CODE (receiver
) == ERROR_MARK
)
4715 return error_mark_node
;
4717 /* Obtain the full selector name. */
4718 if (TREE_CODE (args
) == IDENTIFIER_NODE
)
4719 /* A unary selector. */
4721 else if (TREE_CODE (args
) == TREE_LIST
)
4722 sel_name
= build_keyword_selector (args
);
4726 /* Build the parameter list to give to the method. */
4727 if (TREE_CODE (args
) == TREE_LIST
)
4729 tree chain
= args
, prev
= NULL_TREE
;
4731 /* We have a keyword selector--check for comma expressions. */
4734 tree element
= TREE_VALUE (chain
);
4736 /* We have a comma expression, must collapse... */
4737 if (TREE_CODE (element
) == TREE_LIST
)
4740 TREE_CHAIN (prev
) = element
;
4745 chain
= TREE_CHAIN (chain
);
4747 method_params
= args
;
4750 return finish_message_expr (receiver
, sel_name
, method_params
);
4753 /* The 'finish_message_expr' routine is called from within
4754 'build_message_expr' for non-template functions. In the case of
4755 C++ template functions, it is called from 'build_expr_from_tree'
4756 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
4759 finish_message_expr (receiver
, sel_name
, method_params
)
4760 tree receiver
, sel_name
, method_params
;
4762 tree method_prototype
= NULL_TREE
, class_ident
= NULL_TREE
;
4763 tree selector
, self_object
, retval
;
4764 int statically_typed
= 0, statically_allocated
= 0;
4766 /* Determine receiver type. */
4767 tree rtype
= TREE_TYPE (receiver
);
4768 int super
= IS_SUPER (rtype
);
4772 if (TREE_STATIC_TEMPLATE (rtype
))
4773 statically_allocated
= 1;
4774 else if (TREE_CODE (rtype
) == POINTER_TYPE
4775 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype
)))
4776 statically_typed
= 1;
4777 else if ((flag_next_runtime
4779 && (class_ident
= receiver_is_class_object (receiver
)))
4781 else if (! IS_ID (rtype
)
4782 /* Allow any type that matches objc_class_type. */
4783 && ! comptypes (rtype
, objc_class_type
))
4785 warning ("invalid receiver type `%s'",
4786 gen_declaration (rtype
, errbuf
));
4788 if (statically_allocated
)
4789 receiver
= build_unary_op (ADDR_EXPR
, receiver
, 0);
4791 /* Don't evaluate the receiver twice. */
4792 receiver
= save_expr (receiver
);
4793 self_object
= receiver
;
4796 /* If sending to `super', use current self as the object. */
4797 self_object
= self_decl
;
4799 /* Determine operation return type. */
4805 if (CLASS_SUPER_NAME (implementation_template
))
4808 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
4810 if (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
)
4811 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4813 method_prototype
= lookup_class_method_static (iface
, sel_name
);
4815 if (iface
&& !method_prototype
)
4816 warning ("`%s' does not respond to `%s'",
4817 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template
)),
4818 IDENTIFIER_POINTER (sel_name
));
4822 error ("no super class declared in interface for `%s'",
4823 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
4824 return error_mark_node
;
4828 else if (statically_allocated
)
4830 tree ctype
= TREE_TYPE (rtype
);
4831 tree iface
= lookup_interface (TYPE_NAME (rtype
));
4834 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4836 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
4838 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
4841 if (!method_prototype
)
4842 warning ("`%s' does not respond to `%s'",
4843 IDENTIFIER_POINTER (TYPE_NAME (rtype
)),
4844 IDENTIFIER_POINTER (sel_name
));
4846 else if (statically_typed
)
4848 tree ctype
= TREE_TYPE (rtype
);
4850 /* `self' is now statically_typed. All methods should be visible
4851 within the context of the implementation. */
4852 if (objc_implementation_context
4853 && CLASS_NAME (objc_implementation_context
) == TYPE_NAME (ctype
))
4856 = lookup_instance_method_static (implementation_template
,
4859 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
4861 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
4864 if (! method_prototype
4865 && implementation_template
!= objc_implementation_context
)
4866 /* The method is not published in the interface. Check
4869 = lookup_method (CLASS_NST_METHODS (objc_implementation_context
),
4876 if ((iface
= lookup_interface (TYPE_NAME (ctype
))))
4877 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4879 if (! method_prototype
)
4881 tree protocol_list
= TYPE_PROTOCOL_LIST (ctype
);
4884 = lookup_method_in_protocol_list (protocol_list
,
4889 if (!method_prototype
)
4890 warning ("`%s' does not respond to `%s'",
4891 IDENTIFIER_POINTER (TYPE_NAME (ctype
)),
4892 IDENTIFIER_POINTER (sel_name
));
4894 else if (class_ident
)
4896 if (objc_implementation_context
4897 && CLASS_NAME (objc_implementation_context
) == class_ident
)
4900 = lookup_class_method_static (implementation_template
, sel_name
);
4902 if (!method_prototype
4903 && implementation_template
!= objc_implementation_context
)
4904 /* The method is not published in the interface. Check
4907 = lookup_method (CLASS_CLS_METHODS (objc_implementation_context
),
4914 if ((iface
= lookup_interface (class_ident
)))
4915 method_prototype
= lookup_class_method_static (iface
, sel_name
);
4918 if (!method_prototype
)
4920 warning ("cannot find class (factory) method");
4921 warning ("return type for `%s' defaults to id",
4922 IDENTIFIER_POINTER (sel_name
));
4925 else if (IS_PROTOCOL_QUALIFIED_ID (rtype
))
4927 /* An anonymous object that has been qualified with a protocol. */
4929 tree protocol_list
= TYPE_PROTOCOL_LIST (rtype
);
4931 method_prototype
= lookup_method_in_protocol_list (protocol_list
,
4934 if (!method_prototype
)
4938 warning ("method `%s' not implemented by protocol",
4939 IDENTIFIER_POINTER (sel_name
));
4941 /* Try and find the method signature in the global pools. */
4943 if (!(hsh
= hash_lookup (nst_method_hash_list
, sel_name
)))
4944 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
4946 if (!(method_prototype
= check_duplicates (hsh
)))
4947 warning ("return type defaults to id");
4954 /* We think we have an instance...loophole: extern id Object; */
4955 hsh
= hash_lookup (nst_method_hash_list
, sel_name
);
4958 /* For various loopholes */
4959 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
4961 method_prototype
= check_duplicates (hsh
);
4962 if (!method_prototype
)
4964 warning ("cannot find method");
4965 warning ("return type for `%s' defaults to id",
4966 IDENTIFIER_POINTER (sel_name
));
4970 /* Save the selector name for printing error messages. */
4971 building_objc_message_expr
= sel_name
;
4973 /* Build the parameters list for looking up the method.
4974 These are the object itself and the selector. */
4976 if (flag_typed_selectors
)
4977 selector
= build_typed_selector_reference (sel_name
, method_prototype
);
4979 selector
= build_selector_reference (sel_name
);
4981 retval
= build_objc_method_call (super
, method_prototype
,
4982 receiver
, self_object
,
4983 selector
, method_params
);
4985 building_objc_message_expr
= 0;
4990 /* Build a tree expression to send OBJECT the operation SELECTOR,
4991 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
4992 assuming the method has prototype METHOD_PROTOTYPE.
4993 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
4994 Use METHOD_PARAMS as list of args to pass to the method.
4995 If SUPER_FLAG is nonzero, we look up the superclass's method. */
4998 build_objc_method_call (super_flag
, method_prototype
, lookup_object
, object
,
4999 selector
, method_params
)
5001 tree method_prototype
, lookup_object
, object
, selector
, method_params
;
5003 tree sender
= (super_flag
? umsg_super_decl
: umsg_decl
);
5004 tree rcv_p
= (super_flag
5005 ? build_pointer_type (xref_tag (RECORD_TYPE
,
5006 get_identifier (TAG_SUPER
)))
5009 if (flag_next_runtime
)
5011 if (! method_prototype
)
5013 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5014 tree_cons (NULL_TREE
, selector
,
5016 assemble_external (sender
);
5017 return build_function_call (sender
, method_params
);
5021 /* This is a real kludge, but it is used only for the Next.
5022 Clobber the data type of SENDER temporarily to accept
5023 all the arguments for this operation, and to return
5024 whatever this operation returns. */
5025 tree arglist
= NULL_TREE
, retval
, savarg
, savret
;
5026 tree ret_type
= groktypename (TREE_TYPE (method_prototype
));
5028 /* Save the proper contents of SENDER's data type. */
5029 savarg
= TYPE_ARG_TYPES (TREE_TYPE (sender
));
5030 savret
= TREE_TYPE (TREE_TYPE (sender
));
5032 /* Install this method's argument types. */
5033 arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5035 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = arglist
;
5037 /* Install this method's return type. */
5038 TREE_TYPE (TREE_TYPE (sender
)) = ret_type
;
5040 /* Call SENDER with all the parameters. This will do type
5041 checking using the arg types for this method. */
5042 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5043 tree_cons (NULL_TREE
, selector
,
5045 assemble_external (sender
);
5046 retval
= build_function_call (sender
, method_params
);
5048 /* Restore SENDER's return/argument types. */
5049 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = savarg
;
5050 TREE_TYPE (TREE_TYPE (sender
)) = savret
;
5056 /* This is the portable way.
5057 First call the lookup function to get a pointer to the method,
5058 then cast the pointer, then call it with the method arguments. */
5061 /* Avoid trouble since we may evaluate each of these twice. */
5062 object
= save_expr (object
);
5063 selector
= save_expr (selector
);
5065 lookup_object
= build_c_cast (rcv_p
, lookup_object
);
5067 assemble_external (sender
);
5069 = build_function_call (sender
,
5070 tree_cons (NULL_TREE
, lookup_object
,
5071 tree_cons (NULL_TREE
, selector
,
5074 /* If we have a method prototype, construct the data type this
5075 method needs, and cast what we got from SENDER into a pointer
5077 if (method_prototype
)
5079 tree arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5081 tree valtype
= groktypename (TREE_TYPE (method_prototype
));
5082 tree fake_function_type
= build_function_type (valtype
, arglist
);
5083 TREE_TYPE (method
) = build_pointer_type (fake_function_type
);
5087 = build_pointer_type (build_function_type (ptr_type_node
, NULL_TREE
));
5089 /* Pass the object to the method. */
5090 assemble_external (method
);
5091 return build_function_call (method
,
5092 tree_cons (NULL_TREE
, object
,
5093 tree_cons (NULL_TREE
, selector
,
5099 build_protocol_reference (p
)
5102 tree decl
, ident
, ptype
;
5104 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5106 ident
= synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
);
5108 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
5109 objc_protocol_template
),
5112 if (IDENTIFIER_GLOBAL_VALUE (ident
))
5113 decl
= IDENTIFIER_GLOBAL_VALUE (ident
); /* Set by pushdecl. */
5116 decl
= build_decl (VAR_DECL
, ident
, ptype
);
5117 DECL_EXTERNAL (decl
) = 1;
5118 TREE_PUBLIC (decl
) = 1;
5119 TREE_USED (decl
) = 1;
5120 DECL_ARTIFICIAL (decl
) = 1;
5122 make_decl_rtl (decl
, 0);
5123 pushdecl_top_level (decl
);
5126 PROTOCOL_FORWARD_DECL (p
) = decl
;
5130 build_protocol_expr (protoname
)
5134 tree p
= lookup_protocol (protoname
);
5138 error ("cannot find protocol declaration for `%s'",
5139 IDENTIFIER_POINTER (protoname
));
5140 return error_mark_node
;
5143 if (!PROTOCOL_FORWARD_DECL (p
))
5144 build_protocol_reference (p
);
5146 expr
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
5148 TREE_TYPE (expr
) = protocol_type
;
5154 build_selector_expr (selnamelist
)
5159 /* Obtain the full selector name. */
5160 if (TREE_CODE (selnamelist
) == IDENTIFIER_NODE
)
5161 /* A unary selector. */
5162 selname
= selnamelist
;
5163 else if (TREE_CODE (selnamelist
) == TREE_LIST
)
5164 selname
= build_keyword_selector (selnamelist
);
5168 if (flag_typed_selectors
)
5169 return build_typed_selector_reference (selname
, 0);
5171 return build_selector_reference (selname
);
5175 build_encode_expr (type
)
5181 encode_type (type
, obstack_object_size (&util_obstack
),
5182 OBJC_ENCODE_INLINE_DEFS
);
5183 obstack_1grow (&util_obstack
, 0); /* null terminate string */
5184 string
= obstack_finish (&util_obstack
);
5186 /* Synthesize a string that represents the encoded struct/union. */
5187 result
= my_build_string (strlen (string
) + 1, string
);
5188 obstack_free (&util_obstack
, util_firstobj
);
5193 build_ivar_reference (id
)
5196 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
5198 /* Historically, a class method that produced objects (factory
5199 method) would assign `self' to the instance that it
5200 allocated. This would effectively turn the class method into
5201 an instance method. Following this assignment, the instance
5202 variables could be accessed. That practice, while safe,
5203 violates the simple rule that a class method should not refer
5204 to an instance variable. It's better to catch the cases
5205 where this is done unknowingly than to support the above
5207 warning ("instance variable `%s' accessed in class method",
5208 IDENTIFIER_POINTER (id
));
5209 TREE_TYPE (self_decl
) = instance_type
; /* cast */
5212 return build_component_ref (build_indirect_ref (self_decl
, "->"), id
);
5215 /* Compute a hash value for a given method SEL_NAME. */
5218 hash_func (sel_name
)
5221 const unsigned char *s
5222 = (const unsigned char *)IDENTIFIER_POINTER (sel_name
);
5226 h
= h
* 67 + *s
++ - 113;
5233 nst_method_hash_list
= (hash
*) ggc_calloc (SIZEHASHTABLE
, sizeof (hash
));
5234 cls_method_hash_list
= (hash
*) ggc_calloc (SIZEHASHTABLE
, sizeof (hash
));
5237 /* WARNING!!!! hash_enter is called with a method, and will peek
5238 inside to find its selector! But hash_lookup is given a selector
5239 directly, and looks for the selector that's inside the found
5240 entry's key (method) for comparison. */
5243 hash_enter (hashlist
, method
)
5248 int slot
= hash_func (METHOD_SEL_NAME (method
)) % SIZEHASHTABLE
;
5250 obj
= (hash
) ggc_alloc (sizeof (struct hashed_entry
));
5252 obj
->next
= hashlist
[slot
];
5255 hashlist
[slot
] = obj
; /* append to front */
5259 hash_lookup (hashlist
, sel_name
)
5265 target
= hashlist
[hash_func (sel_name
) % SIZEHASHTABLE
];
5269 if (sel_name
== METHOD_SEL_NAME (target
->key
))
5272 target
= target
->next
;
5278 hash_add_attr (entry
, value
)
5284 obj
= (attr
) ggc_alloc (sizeof (struct hashed_attribute
));
5285 obj
->next
= entry
->list
;
5288 entry
->list
= obj
; /* append to front */
5292 lookup_method (mchain
, method
)
5298 if (TREE_CODE (method
) == IDENTIFIER_NODE
)
5301 key
= METHOD_SEL_NAME (method
);
5305 if (METHOD_SEL_NAME (mchain
) == key
)
5307 mchain
= TREE_CHAIN (mchain
);
5313 lookup_instance_method_static (interface
, ident
)
5317 tree inter
= interface
;
5318 tree chain
= CLASS_NST_METHODS (inter
);
5319 tree meth
= NULL_TREE
;
5323 if ((meth
= lookup_method (chain
, ident
)))
5326 if (CLASS_CATEGORY_LIST (inter
))
5328 tree category
= CLASS_CATEGORY_LIST (inter
);
5329 chain
= CLASS_NST_METHODS (category
);
5333 if ((meth
= lookup_method (chain
, ident
)))
5336 /* Check for instance methods in protocols in categories. */
5337 if (CLASS_PROTOCOL_LIST (category
))
5339 if ((meth
= (lookup_method_in_protocol_list
5340 (CLASS_PROTOCOL_LIST (category
), ident
, 0))))
5344 if ((category
= CLASS_CATEGORY_LIST (category
)))
5345 chain
= CLASS_NST_METHODS (category
);
5350 if (CLASS_PROTOCOL_LIST (inter
))
5352 if ((meth
= (lookup_method_in_protocol_list
5353 (CLASS_PROTOCOL_LIST (inter
), ident
, 0))))
5357 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5358 chain
= CLASS_NST_METHODS (inter
);
5366 lookup_class_method_static (interface
, ident
)
5370 tree inter
= interface
;
5371 tree chain
= CLASS_CLS_METHODS (inter
);
5372 tree meth
= NULL_TREE
;
5373 tree root_inter
= NULL_TREE
;
5377 if ((meth
= lookup_method (chain
, ident
)))
5380 if (CLASS_CATEGORY_LIST (inter
))
5382 tree category
= CLASS_CATEGORY_LIST (inter
);
5383 chain
= CLASS_CLS_METHODS (category
);
5387 if ((meth
= lookup_method (chain
, ident
)))
5390 /* Check for class methods in protocols in categories. */
5391 if (CLASS_PROTOCOL_LIST (category
))
5393 if ((meth
= (lookup_method_in_protocol_list
5394 (CLASS_PROTOCOL_LIST (category
), ident
, 1))))
5398 if ((category
= CLASS_CATEGORY_LIST (category
)))
5399 chain
= CLASS_CLS_METHODS (category
);
5404 /* Check for class methods in protocols. */
5405 if (CLASS_PROTOCOL_LIST (inter
))
5407 if ((meth
= (lookup_method_in_protocol_list
5408 (CLASS_PROTOCOL_LIST (inter
), ident
, 1))))
5413 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5414 chain
= CLASS_CLS_METHODS (inter
);
5418 /* If no class (factory) method was found, check if an _instance_
5419 method of the same name exists in the root class. This is what
5420 the Objective-C runtime will do. */
5421 return lookup_instance_method_static (root_inter
, ident
);
5425 add_class_method (class, method
)
5432 if (!(mth
= lookup_method (CLASS_CLS_METHODS (class), method
)))
5434 /* put method on list in reverse order */
5435 TREE_CHAIN (method
) = CLASS_CLS_METHODS (class);
5436 CLASS_CLS_METHODS (class) = method
;
5440 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5441 error ("duplicate definition of class method `%s'",
5442 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5445 /* Check types; if different, complain. */
5446 if (!comp_proto_with_proto (method
, mth
))
5447 error ("duplicate declaration of class method `%s'",
5448 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5452 if (!(hsh
= hash_lookup (cls_method_hash_list
, METHOD_SEL_NAME (method
))))
5454 /* Install on a global chain. */
5455 hash_enter (cls_method_hash_list
, method
);
5459 /* Check types; if different, add to a list. */
5460 if (!comp_proto_with_proto (method
, hsh
->key
))
5461 hash_add_attr (hsh
, method
);
5467 add_instance_method (class, method
)
5474 if (!(mth
= lookup_method (CLASS_NST_METHODS (class), method
)))
5476 /* Put method on list in reverse order. */
5477 TREE_CHAIN (method
) = CLASS_NST_METHODS (class);
5478 CLASS_NST_METHODS (class) = method
;
5482 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5483 error ("duplicate definition of instance method `%s'",
5484 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5487 /* Check types; if different, complain. */
5488 if (!comp_proto_with_proto (method
, mth
))
5489 error ("duplicate declaration of instance method `%s'",
5490 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5494 if (!(hsh
= hash_lookup (nst_method_hash_list
, METHOD_SEL_NAME (method
))))
5496 /* Install on a global chain. */
5497 hash_enter (nst_method_hash_list
, method
);
5501 /* Check types; if different, add to a list. */
5502 if (!comp_proto_with_proto (method
, hsh
->key
))
5503 hash_add_attr (hsh
, method
);
5512 /* Put interfaces on list in reverse order. */
5513 TREE_CHAIN (class) = interface_chain
;
5514 interface_chain
= class;
5515 return interface_chain
;
5519 add_category (class, category
)
5523 /* Put categories on list in reverse order. */
5524 tree cat
= CLASS_CATEGORY_LIST (class);
5528 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
5529 warning ("duplicate interface declaration for category `%s(%s)'",
5530 IDENTIFIER_POINTER (CLASS_NAME (class)),
5531 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category
)));
5532 cat
= CLASS_CATEGORY_LIST (cat
);
5535 CLASS_CATEGORY_LIST (category
) = CLASS_CATEGORY_LIST (class);
5536 CLASS_CATEGORY_LIST (class) = category
;
5539 /* Called after parsing each instance variable declaration. Necessary to
5540 preserve typedefs and implement public/private...
5542 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5545 add_instance_variable (class, public, declarator
, declspecs
, width
)
5552 tree field_decl
, raw_decl
;
5554 raw_decl
= build_tree_list (declspecs
, declarator
);
5556 if (CLASS_RAW_IVARS (class))
5557 chainon (CLASS_RAW_IVARS (class), raw_decl
);
5559 CLASS_RAW_IVARS (class) = raw_decl
;
5561 field_decl
= grokfield (input_filename
, lineno
,
5562 declarator
, declspecs
, width
);
5564 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5568 TREE_PUBLIC (field_decl
) = 0;
5569 TREE_PRIVATE (field_decl
) = 0;
5570 TREE_PROTECTED (field_decl
) = 1;
5574 TREE_PUBLIC (field_decl
) = 1;
5575 TREE_PRIVATE (field_decl
) = 0;
5576 TREE_PROTECTED (field_decl
) = 0;
5580 TREE_PUBLIC (field_decl
) = 0;
5581 TREE_PRIVATE (field_decl
) = 1;
5582 TREE_PROTECTED (field_decl
) = 0;
5587 if (CLASS_IVARS (class))
5588 chainon (CLASS_IVARS (class), field_decl
);
5590 CLASS_IVARS (class) = field_decl
;
5596 is_ivar (decl_chain
, ident
)
5600 for ( ; decl_chain
; decl_chain
= TREE_CHAIN (decl_chain
))
5601 if (DECL_NAME (decl_chain
) == ident
)
5606 /* True if the ivar is private and we are not in its implementation. */
5612 if (TREE_PRIVATE (decl
)
5613 && ! is_ivar (CLASS_IVARS (implementation_template
), DECL_NAME (decl
)))
5615 error ("instance variable `%s' is declared private",
5616 IDENTIFIER_POINTER (DECL_NAME (decl
)));
5623 /* We have an instance variable reference;, check to see if it is public. */
5626 is_public (expr
, identifier
)
5630 tree basetype
= TREE_TYPE (expr
);
5631 enum tree_code code
= TREE_CODE (basetype
);
5634 if (code
== RECORD_TYPE
)
5636 if (TREE_STATIC_TEMPLATE (basetype
))
5638 if (!lookup_interface (TYPE_NAME (basetype
)))
5640 error ("cannot find interface declaration for `%s'",
5641 IDENTIFIER_POINTER (TYPE_NAME (basetype
)));
5645 if ((decl
= is_ivar (TYPE_FIELDS (basetype
), identifier
)))
5647 if (TREE_PUBLIC (decl
))
5650 /* Important difference between the Stepstone translator:
5651 all instance variables should be public within the context
5652 of the implementation. */
5653 if (objc_implementation_context
5654 && (((TREE_CODE (objc_implementation_context
)
5655 == CLASS_IMPLEMENTATION_TYPE
)
5656 || (TREE_CODE (objc_implementation_context
)
5657 == CATEGORY_IMPLEMENTATION_TYPE
))
5658 && (CLASS_NAME (objc_implementation_context
)
5659 == TYPE_NAME (basetype
))))
5660 return ! is_private (decl
);
5662 error ("instance variable `%s' is declared %s",
5663 IDENTIFIER_POINTER (identifier
),
5664 TREE_PRIVATE (decl
) ? "private" : "protected");
5669 else if (objc_implementation_context
&& (basetype
== objc_object_reference
))
5671 TREE_TYPE (expr
) = uprivate_record
;
5672 warning ("static access to object of type `id'");
5679 /* Implement @defs (<classname>) within struct bodies. */
5682 get_class_ivars (interface
)
5685 /* Make sure we copy the leaf ivars in case @defs is used in a local
5686 context. Otherwise finish_struct will overwrite the layout info
5687 using temporary storage. */
5688 return build_ivar_chain (interface
, 1);
5691 /* Make sure all entries in CHAIN are also in LIST. */
5694 check_methods (chain
, list
, mtype
)
5703 if (!lookup_method (list
, chain
))
5707 if (TREE_CODE (objc_implementation_context
)
5708 == CLASS_IMPLEMENTATION_TYPE
)
5709 warning ("incomplete implementation of class `%s'",
5710 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
)));
5711 else if (TREE_CODE (objc_implementation_context
)
5712 == CATEGORY_IMPLEMENTATION_TYPE
)
5713 warning ("incomplete implementation of category `%s'",
5714 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
5718 warning ("method definition for `%c%s' not found",
5719 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
5722 chain
= TREE_CHAIN (chain
);
5728 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
5731 conforms_to_protocol (class, protocol
)
5735 if (TREE_CODE (protocol
) == PROTOCOL_INTERFACE_TYPE
)
5737 tree p
= CLASS_PROTOCOL_LIST (class);
5738 while (p
&& TREE_VALUE (p
) != protocol
)
5743 tree super
= (CLASS_SUPER_NAME (class)
5744 ? lookup_interface (CLASS_SUPER_NAME (class))
5746 int tmp
= super
? conforms_to_protocol (super
, protocol
) : 0;
5755 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5756 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5759 check_methods_accessible (chain
, context
, mtype
)
5766 tree base_context
= context
;
5770 context
= base_context
;
5774 list
= CLASS_CLS_METHODS (context
);
5776 list
= CLASS_NST_METHODS (context
);
5778 if (lookup_method (list
, chain
))
5781 else if (TREE_CODE (context
) == CLASS_IMPLEMENTATION_TYPE
5782 || TREE_CODE (context
) == CLASS_INTERFACE_TYPE
)
5783 context
= (CLASS_SUPER_NAME (context
)
5784 ? lookup_interface (CLASS_SUPER_NAME (context
))
5787 else if (TREE_CODE (context
) == CATEGORY_IMPLEMENTATION_TYPE
5788 || TREE_CODE (context
) == CATEGORY_INTERFACE_TYPE
)
5789 context
= (CLASS_NAME (context
)
5790 ? lookup_interface (CLASS_NAME (context
))
5796 if (context
== NULL_TREE
)
5800 if (TREE_CODE (objc_implementation_context
)
5801 == CLASS_IMPLEMENTATION_TYPE
)
5802 warning ("incomplete implementation of class `%s'",
5804 (CLASS_NAME (objc_implementation_context
)));
5805 else if (TREE_CODE (objc_implementation_context
)
5806 == CATEGORY_IMPLEMENTATION_TYPE
)
5807 warning ("incomplete implementation of category `%s'",
5809 (CLASS_SUPER_NAME (objc_implementation_context
)));
5812 warning ("method definition for `%c%s' not found",
5813 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
5816 chain
= TREE_CHAIN (chain
); /* next method... */
5821 /* Check whether the current interface (accessible via
5822 'objc_implementation_context') actually implements protocol P, along
5823 with any protocols that P inherits. */
5826 check_protocol (p
, type
, name
)
5831 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
5835 /* Ensure that all protocols have bodies! */
5838 f1
= check_methods (PROTOCOL_CLS_METHODS (p
),
5839 CLASS_CLS_METHODS (objc_implementation_context
),
5841 f2
= check_methods (PROTOCOL_NST_METHODS (p
),
5842 CLASS_NST_METHODS (objc_implementation_context
),
5847 f1
= check_methods_accessible (PROTOCOL_CLS_METHODS (p
),
5848 objc_implementation_context
,
5850 f2
= check_methods_accessible (PROTOCOL_NST_METHODS (p
),
5851 objc_implementation_context
,
5856 warning ("%s `%s' does not fully implement the `%s' protocol",
5857 type
, name
, IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
5860 /* Check protocols recursively. */
5861 if (PROTOCOL_LIST (p
))
5863 tree subs
= PROTOCOL_LIST (p
);
5865 lookup_interface (CLASS_SUPER_NAME (implementation_template
));
5869 tree sub
= TREE_VALUE (subs
);
5871 /* If the superclass does not conform to the protocols
5872 inherited by P, then we must! */
5873 if (!super_class
|| !conforms_to_protocol (super_class
, sub
))
5874 check_protocol (sub
, type
, name
);
5875 subs
= TREE_CHAIN (subs
);
5880 /* Check whether the current interface (accessible via
5881 'objc_implementation_context') actually implements the protocols listed
5885 check_protocols (proto_list
, type
, name
)
5890 for ( ; proto_list
; proto_list
= TREE_CHAIN (proto_list
))
5892 tree p
= TREE_VALUE (proto_list
);
5894 check_protocol (p
, type
, name
);
5898 /* Make sure that the class CLASS_NAME is defined
5899 CODE says which kind of thing CLASS_NAME ought to be.
5900 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
5901 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
5904 start_class (code
, class_name
, super_name
, protocol_list
)
5905 enum tree_code code
;
5912 if (objc_implementation_context
)
5914 warning ("`@end' missing in implementation context");
5915 finish_class (objc_implementation_context
);
5916 objc_ivar_chain
= NULL_TREE
;
5917 objc_implementation_context
= NULL_TREE
;
5920 class = make_node (code
);
5921 TYPE_BINFO (class) = make_tree_vec (5);
5923 CLASS_NAME (class) = class_name
;
5924 CLASS_SUPER_NAME (class) = super_name
;
5925 CLASS_CLS_METHODS (class) = NULL_TREE
;
5927 if (! is_class_name (class_name
) && (decl
= lookup_name (class_name
)))
5929 error ("`%s' redeclared as different kind of symbol",
5930 IDENTIFIER_POINTER (class_name
));
5931 error_with_decl (decl
, "previous declaration of `%s'");
5934 if (code
== CLASS_IMPLEMENTATION_TYPE
)
5939 for (chain
= implemented_classes
; chain
; chain
= TREE_CHAIN (chain
))
5940 if (TREE_VALUE (chain
) == class_name
)
5942 error ("reimplementation of class `%s'",
5943 IDENTIFIER_POINTER (class_name
));
5944 return error_mark_node
;
5946 implemented_classes
= tree_cons (NULL_TREE
, class_name
,
5947 implemented_classes
);
5950 /* Pre-build the following entities - for speed/convenience. */
5952 self_id
= get_identifier ("self");
5954 ucmd_id
= get_identifier ("_cmd");
5957 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
5958 if (!objc_super_template
)
5959 objc_super_template
= build_super_template ();
5961 /* Reset for multiple classes per file. */
5964 objc_implementation_context
= class;
5966 /* Lookup the interface for this implementation. */
5968 if (!(implementation_template
= lookup_interface (class_name
)))
5970 warning ("cannot find interface declaration for `%s'",
5971 IDENTIFIER_POINTER (class_name
));
5972 add_class (implementation_template
= objc_implementation_context
);
5975 /* If a super class has been specified in the implementation,
5976 insure it conforms to the one specified in the interface. */
5979 && (super_name
!= CLASS_SUPER_NAME (implementation_template
)))
5981 tree previous_name
= CLASS_SUPER_NAME (implementation_template
);
5982 const char *const name
=
5983 previous_name
? IDENTIFIER_POINTER (previous_name
) : "";
5984 error ("conflicting super class name `%s'",
5985 IDENTIFIER_POINTER (super_name
));
5986 error ("previous declaration of `%s'", name
);
5989 else if (! super_name
)
5991 CLASS_SUPER_NAME (objc_implementation_context
)
5992 = CLASS_SUPER_NAME (implementation_template
);
5996 else if (code
== CLASS_INTERFACE_TYPE
)
5998 if (lookup_interface (class_name
))
5999 warning ("duplicate interface declaration for class `%s'",
6000 IDENTIFIER_POINTER (class_name
));
6005 CLASS_PROTOCOL_LIST (class)
6006 = lookup_and_install_protocols (protocol_list
);
6009 else if (code
== CATEGORY_INTERFACE_TYPE
)
6011 tree class_category_is_assoc_with
;
6013 /* For a category, class_name is really the name of the class that
6014 the following set of methods will be associated with. We must
6015 find the interface so that can derive the objects template. */
6017 if (!(class_category_is_assoc_with
= lookup_interface (class_name
)))
6019 error ("cannot find interface declaration for `%s'",
6020 IDENTIFIER_POINTER (class_name
));
6021 exit (FATAL_EXIT_CODE
);
6024 add_category (class_category_is_assoc_with
, class);
6027 CLASS_PROTOCOL_LIST (class)
6028 = lookup_and_install_protocols (protocol_list
);
6031 else if (code
== CATEGORY_IMPLEMENTATION_TYPE
)
6033 /* Pre-build the following entities for speed/convenience. */
6035 self_id
= get_identifier ("self");
6037 ucmd_id
= get_identifier ("_cmd");
6040 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6041 if (!objc_super_template
)
6042 objc_super_template
= build_super_template ();
6044 /* Reset for multiple classes per file. */
6047 objc_implementation_context
= class;
6049 /* For a category, class_name is really the name of the class that
6050 the following set of methods will be associated with. We must
6051 find the interface so that can derive the objects template. */
6053 if (!(implementation_template
= lookup_interface (class_name
)))
6055 error ("cannot find interface declaration for `%s'",
6056 IDENTIFIER_POINTER (class_name
));
6057 exit (FATAL_EXIT_CODE
);
6064 continue_class (class)
6067 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6068 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6070 struct imp_entry
*imp_entry
;
6073 /* Check consistency of the instance variables. */
6075 if (CLASS_IVARS (class))
6076 check_ivars (implementation_template
, class);
6078 /* code generation */
6080 ivar_context
= build_private_template (implementation_template
);
6082 if (!objc_class_template
)
6083 build_class_template ();
6085 imp_entry
= (struct imp_entry
*) ggc_alloc (sizeof (struct imp_entry
));
6087 imp_entry
->next
= imp_list
;
6088 imp_entry
->imp_context
= class;
6089 imp_entry
->imp_template
= implementation_template
;
6091 synth_forward_declarations ();
6092 imp_entry
->class_decl
= UOBJC_CLASS_decl
;
6093 imp_entry
->meta_decl
= UOBJC_METACLASS_decl
;
6095 /* Append to front and increment count. */
6096 imp_list
= imp_entry
;
6097 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6102 return ivar_context
;
6105 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6107 tree record
= xref_tag (RECORD_TYPE
, CLASS_NAME (class));
6109 if (!TYPE_FIELDS (record
))
6111 finish_struct (record
, build_ivar_chain (class, 0), NULL_TREE
);
6112 CLASS_STATIC_TEMPLATE (class) = record
;
6114 /* Mark this record as a class template for static typing. */
6115 TREE_STATIC_TEMPLATE (record
) = 1;
6122 return error_mark_node
;
6125 /* This is called once we see the "@end" in an interface/implementation. */
6128 finish_class (class)
6131 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6133 /* All code generation is done in finish_objc. */
6135 if (implementation_template
!= objc_implementation_context
)
6137 /* Ensure that all method listed in the interface contain bodies. */
6138 check_methods (CLASS_CLS_METHODS (implementation_template
),
6139 CLASS_CLS_METHODS (objc_implementation_context
), '+');
6140 check_methods (CLASS_NST_METHODS (implementation_template
),
6141 CLASS_NST_METHODS (objc_implementation_context
), '-');
6143 if (CLASS_PROTOCOL_LIST (implementation_template
))
6144 check_protocols (CLASS_PROTOCOL_LIST (implementation_template
),
6146 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
)));
6150 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6152 tree category
= CLASS_CATEGORY_LIST (implementation_template
);
6154 /* Find the category interface from the class it is associated with. */
6157 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category
))
6159 category
= CLASS_CATEGORY_LIST (category
);
6164 /* Ensure all method listed in the interface contain bodies. */
6165 check_methods (CLASS_CLS_METHODS (category
),
6166 CLASS_CLS_METHODS (objc_implementation_context
), '+');
6167 check_methods (CLASS_NST_METHODS (category
),
6168 CLASS_NST_METHODS (objc_implementation_context
), '-');
6170 if (CLASS_PROTOCOL_LIST (category
))
6171 check_protocols (CLASS_PROTOCOL_LIST (category
),
6173 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
6177 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6180 const char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (class));
6181 char *string
= (char *) alloca (strlen (class_name
) + 3);
6183 /* extern struct objc_object *_<my_name>; */
6185 sprintf (string
, "_%s", class_name
);
6187 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
6188 decl_specs
= tree_cons (NULL_TREE
, objc_object_reference
, decl_specs
);
6189 define_decl (build1 (INDIRECT_REF
, NULL_TREE
, get_identifier (string
)),
6195 add_protocol (protocol
)
6198 /* Put protocol on list in reverse order. */
6199 TREE_CHAIN (protocol
) = protocol_chain
;
6200 protocol_chain
= protocol
;
6201 return protocol_chain
;
6205 lookup_protocol (ident
)
6210 for (chain
= protocol_chain
; chain
; chain
= TREE_CHAIN (chain
))
6211 if (ident
== PROTOCOL_NAME (chain
))
6217 /* This function forward declares the protocols named by NAMES. If
6218 they are already declared or defined, the function has no effect. */
6221 objc_declare_protocols (names
)
6226 for (list
= names
; list
; list
= TREE_CHAIN (list
))
6228 tree name
= TREE_VALUE (list
);
6230 if (lookup_protocol (name
) == NULL_TREE
)
6232 tree protocol
= make_node (PROTOCOL_INTERFACE_TYPE
);
6234 TYPE_BINFO (protocol
) = make_tree_vec (2);
6235 PROTOCOL_NAME (protocol
) = name
;
6236 PROTOCOL_LIST (protocol
) = NULL_TREE
;
6237 add_protocol (protocol
);
6238 PROTOCOL_DEFINED (protocol
) = 0;
6239 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6245 start_protocol (code
, name
, list
)
6246 enum tree_code code
;
6252 /* This is as good a place as any. Need to invoke
6253 push_tag_toplevel. */
6254 if (!objc_protocol_template
)
6255 objc_protocol_template
= build_protocol_template ();
6257 protocol
= lookup_protocol (name
);
6261 protocol
= make_node (code
);
6262 TYPE_BINFO (protocol
) = make_tree_vec (2);
6264 PROTOCOL_NAME (protocol
) = name
;
6265 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
6266 add_protocol (protocol
);
6267 PROTOCOL_DEFINED (protocol
) = 1;
6268 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6270 check_protocol_recursively (protocol
, list
);
6272 else if (! PROTOCOL_DEFINED (protocol
))
6274 PROTOCOL_DEFINED (protocol
) = 1;
6275 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
6277 check_protocol_recursively (protocol
, list
);
6281 warning ("duplicate declaration for protocol `%s'",
6282 IDENTIFIER_POINTER (name
));
6288 finish_protocol (protocol
)
6289 tree protocol ATTRIBUTE_UNUSED
;
6294 /* "Encode" a data type into a string, which grows in util_obstack.
6295 ??? What is the FORMAT? Someone please document this! */
6298 encode_type_qualifiers (declspecs
)
6303 for (spec
= declspecs
; spec
; spec
= TREE_CHAIN (spec
))
6305 if (ridpointers
[(int) RID_CONST
] == TREE_VALUE (spec
))
6306 obstack_1grow (&util_obstack
, 'r');
6307 else if (ridpointers
[(int) RID_IN
] == TREE_VALUE (spec
))
6308 obstack_1grow (&util_obstack
, 'n');
6309 else if (ridpointers
[(int) RID_INOUT
] == TREE_VALUE (spec
))
6310 obstack_1grow (&util_obstack
, 'N');
6311 else if (ridpointers
[(int) RID_OUT
] == TREE_VALUE (spec
))
6312 obstack_1grow (&util_obstack
, 'o');
6313 else if (ridpointers
[(int) RID_BYCOPY
] == TREE_VALUE (spec
))
6314 obstack_1grow (&util_obstack
, 'O');
6315 else if (ridpointers
[(int) RID_BYREF
] == TREE_VALUE (spec
))
6316 obstack_1grow (&util_obstack
, 'R');
6317 else if (ridpointers
[(int) RID_ONEWAY
] == TREE_VALUE (spec
))
6318 obstack_1grow (&util_obstack
, 'V');
6322 /* Encode a pointer type. */
6325 encode_pointer (type
, curtype
, format
)
6330 tree pointer_to
= TREE_TYPE (type
);
6332 if (TREE_CODE (pointer_to
) == RECORD_TYPE
)
6334 if (TYPE_NAME (pointer_to
)
6335 && TREE_CODE (TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
)
6337 const char *name
= IDENTIFIER_POINTER (TYPE_NAME (pointer_to
));
6339 if (strcmp (name
, TAG_OBJECT
) == 0) /* '@' */
6341 obstack_1grow (&util_obstack
, '@');
6344 else if (TREE_STATIC_TEMPLATE (pointer_to
))
6346 if (generating_instance_variables
)
6348 obstack_1grow (&util_obstack
, '@');
6349 obstack_1grow (&util_obstack
, '"');
6350 obstack_grow (&util_obstack
, name
, strlen (name
));
6351 obstack_1grow (&util_obstack
, '"');
6356 obstack_1grow (&util_obstack
, '@');
6360 else if (strcmp (name
, TAG_CLASS
) == 0) /* '#' */
6362 obstack_1grow (&util_obstack
, '#');
6365 else if (strcmp (name
, TAG_SELECTOR
) == 0) /* ':' */
6367 obstack_1grow (&util_obstack
, ':');
6372 else if (TREE_CODE (pointer_to
) == INTEGER_TYPE
6373 && TYPE_MODE (pointer_to
) == QImode
)
6375 obstack_1grow (&util_obstack
, '*');
6379 /* We have a type that does not get special treatment. */
6381 /* NeXT extension */
6382 obstack_1grow (&util_obstack
, '^');
6383 encode_type (pointer_to
, curtype
, format
);
6387 encode_array (type
, curtype
, format
)
6392 tree an_int_cst
= TYPE_SIZE (type
);
6393 tree array_of
= TREE_TYPE (type
);
6396 /* An incomplete array is treated like a pointer. */
6397 if (an_int_cst
== NULL
)
6399 encode_pointer (type
, curtype
, format
);
6403 sprintf (buffer
, "[%ld",
6404 (long) (TREE_INT_CST_LOW (an_int_cst
)
6405 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
6407 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6408 encode_type (array_of
, curtype
, format
);
6409 obstack_1grow (&util_obstack
, ']');
6414 encode_aggregate_within (type
, curtype
, format
, left
, right
)
6421 /* The RECORD_TYPE may in fact be a typedef! For purposes
6422 of encoding, we need the real underlying enchilada. */
6423 if (TYPE_MAIN_VARIANT (type
))
6424 type
= TYPE_MAIN_VARIANT (type
);
6426 if (obstack_object_size (&util_obstack
) > 0
6427 && *(obstack_next_free (&util_obstack
) - 1) == '^')
6429 tree name
= TYPE_NAME (type
);
6431 /* we have a reference; this is a NeXT extension. */
6433 if (obstack_object_size (&util_obstack
) - curtype
== 1
6434 && format
== OBJC_ENCODE_INLINE_DEFS
)
6436 /* Output format of struct for first level only. */
6437 tree fields
= TYPE_FIELDS (type
);
6439 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6441 obstack_1grow (&util_obstack
, left
);
6442 obstack_grow (&util_obstack
,
6443 IDENTIFIER_POINTER (name
),
6444 strlen (IDENTIFIER_POINTER (name
)));
6445 obstack_1grow (&util_obstack
, '=');
6449 obstack_1grow (&util_obstack
, left
);
6450 obstack_grow (&util_obstack
, "?=", 2);
6453 for ( ; fields
; fields
= TREE_CHAIN (fields
))
6454 encode_field_decl (fields
, curtype
, format
);
6456 obstack_1grow (&util_obstack
, right
);
6459 else if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6461 obstack_1grow (&util_obstack
, left
);
6462 obstack_grow (&util_obstack
,
6463 IDENTIFIER_POINTER (name
),
6464 strlen (IDENTIFIER_POINTER (name
)));
6465 obstack_1grow (&util_obstack
, right
);
6470 /* We have an untagged structure or a typedef. */
6471 obstack_1grow (&util_obstack
, left
);
6472 obstack_1grow (&util_obstack
, '?');
6473 obstack_1grow (&util_obstack
, right
);
6479 tree name
= TYPE_NAME (type
);
6480 tree fields
= TYPE_FIELDS (type
);
6482 if (format
== OBJC_ENCODE_INLINE_DEFS
6483 || generating_instance_variables
)
6485 obstack_1grow (&util_obstack
, left
);
6486 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6487 obstack_grow (&util_obstack
,
6488 IDENTIFIER_POINTER (name
),
6489 strlen (IDENTIFIER_POINTER (name
)));
6491 obstack_1grow (&util_obstack
, '?');
6493 obstack_1grow (&util_obstack
, '=');
6495 for (; fields
; fields
= TREE_CHAIN (fields
))
6497 if (generating_instance_variables
)
6499 tree fname
= DECL_NAME (fields
);
6501 obstack_1grow (&util_obstack
, '"');
6502 if (fname
&& TREE_CODE (fname
) == IDENTIFIER_NODE
)
6504 obstack_grow (&util_obstack
,
6505 IDENTIFIER_POINTER (fname
),
6506 strlen (IDENTIFIER_POINTER (fname
)));
6509 obstack_1grow (&util_obstack
, '"');
6512 encode_field_decl (fields
, curtype
, format
);
6515 obstack_1grow (&util_obstack
, right
);
6520 obstack_1grow (&util_obstack
, left
);
6521 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6522 obstack_grow (&util_obstack
,
6523 IDENTIFIER_POINTER (name
),
6524 strlen (IDENTIFIER_POINTER (name
)));
6526 /* We have an untagged structure or a typedef. */
6527 obstack_1grow (&util_obstack
, '?');
6529 obstack_1grow (&util_obstack
, right
);
6535 encode_aggregate (type
, curtype
, format
)
6540 enum tree_code code
= TREE_CODE (type
);
6546 encode_aggregate_within(type
, curtype
, format
, '{', '}');
6551 encode_aggregate_within(type
, curtype
, format
, '(', ')');
6556 obstack_1grow (&util_obstack
, 'i');
6564 /* Support bitfields. The current version of Objective-C does not support
6565 them. The string will consist of one or more "b:n"'s where n is an
6566 integer describing the width of the bitfield. Currently, classes in
6567 the kit implement a method "-(char *)describeBitfieldStruct:" that
6568 simulates this. If they do not implement this method, the archiver
6569 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6570 according to the GNU compiler. After looking at the "kit", it appears
6571 that all classes currently rely on this default behavior, rather than
6572 hand generating this string (which is tedious). */
6575 encode_bitfield (width
)
6579 sprintf (buffer
, "b%d", width
);
6580 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6583 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6586 encode_type (type
, curtype
, format
)
6591 enum tree_code code
= TREE_CODE (type
);
6593 if (code
== INTEGER_TYPE
)
6595 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6597 /* Unsigned integer types. */
6599 if (TYPE_MODE (type
) == QImode
)
6600 obstack_1grow (&util_obstack
, 'C');
6601 else if (TYPE_MODE (type
) == HImode
)
6602 obstack_1grow (&util_obstack
, 'S');
6603 else if (TYPE_MODE (type
) == SImode
)
6605 if (type
== long_unsigned_type_node
)
6606 obstack_1grow (&util_obstack
, 'L');
6608 obstack_1grow (&util_obstack
, 'I');
6610 else if (TYPE_MODE (type
) == DImode
)
6611 obstack_1grow (&util_obstack
, 'Q');
6615 /* Signed integer types. */
6617 if (TYPE_MODE (type
) == QImode
)
6618 obstack_1grow (&util_obstack
, 'c');
6619 else if (TYPE_MODE (type
) == HImode
)
6620 obstack_1grow (&util_obstack
, 's');
6621 else if (TYPE_MODE (type
) == SImode
)
6623 if (type
== long_integer_type_node
)
6624 obstack_1grow (&util_obstack
, 'l');
6626 obstack_1grow (&util_obstack
, 'i');
6629 else if (TYPE_MODE (type
) == DImode
)
6630 obstack_1grow (&util_obstack
, 'q');
6634 else if (code
== REAL_TYPE
)
6636 /* Floating point types. */
6638 if (TYPE_MODE (type
) == SFmode
)
6639 obstack_1grow (&util_obstack
, 'f');
6640 else if (TYPE_MODE (type
) == DFmode
6641 || TYPE_MODE (type
) == TFmode
)
6642 obstack_1grow (&util_obstack
, 'd');
6645 else if (code
== VOID_TYPE
)
6646 obstack_1grow (&util_obstack
, 'v');
6648 else if (code
== ARRAY_TYPE
)
6649 encode_array (type
, curtype
, format
);
6651 else if (code
== POINTER_TYPE
)
6652 encode_pointer (type
, curtype
, format
);
6654 else if (code
== RECORD_TYPE
|| code
== UNION_TYPE
|| code
== ENUMERAL_TYPE
)
6655 encode_aggregate (type
, curtype
, format
);
6657 else if (code
== FUNCTION_TYPE
) /* '?' */
6658 obstack_1grow (&util_obstack
, '?');
6662 encode_complete_bitfield (position
, type
, size
)
6667 enum tree_code code
= TREE_CODE (type
);
6669 char charType
= '?';
6671 if (code
== INTEGER_TYPE
)
6673 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6675 /* Unsigned integer types. */
6677 if (TYPE_MODE (type
) == QImode
)
6679 else if (TYPE_MODE (type
) == HImode
)
6681 else if (TYPE_MODE (type
) == SImode
)
6683 if (type
== long_unsigned_type_node
)
6688 else if (TYPE_MODE (type
) == DImode
)
6693 /* Signed integer types. */
6695 if (TYPE_MODE (type
) == QImode
)
6697 else if (TYPE_MODE (type
) == HImode
)
6699 else if (TYPE_MODE (type
) == SImode
)
6701 if (type
== long_integer_type_node
)
6707 else if (TYPE_MODE (type
) == DImode
)
6711 else if (code
== ENUMERAL_TYPE
)
6716 sprintf (buffer
, "b%d%c%d", position
, charType
, size
);
6717 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6721 encode_field_decl (field_decl
, curtype
, format
)
6728 type
= TREE_TYPE (field_decl
);
6730 /* If this field is obviously a bitfield, or is a bitfield that has been
6731 clobbered to look like a ordinary integer mode, go ahead and generate
6732 the bitfield typing information. */
6733 if (flag_next_runtime
)
6735 if (DECL_BIT_FIELD (field_decl
))
6736 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl
), 1));
6738 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6742 if (DECL_BIT_FIELD (field_decl
))
6743 encode_complete_bitfield (int_bit_position (field_decl
),
6744 DECL_BIT_FIELD_TYPE (field_decl
),
6745 tree_low_cst (DECL_SIZE (field_decl
), 1));
6747 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6752 expr_last (complex_expr
)
6758 while ((next
= TREE_OPERAND (complex_expr
, 0)))
6759 complex_expr
= next
;
6761 return complex_expr
;
6764 /* Transform a method definition into a function definition as follows:
6765 - synthesize the first two arguments, "self" and "_cmd". */
6768 start_method_def (method
)
6773 /* Required to implement _msgSuper. */
6774 objc_method_context
= method
;
6775 UOBJC_SUPER_decl
= NULL_TREE
;
6777 /* Must be called BEFORE start_function. */
6780 /* Generate prototype declarations for arguments..."new-style". */
6782 if (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
)
6783 decl_specs
= build_tree_list (NULL_TREE
, uprivate_record
);
6785 /* Really a `struct objc_class *'. However, we allow people to
6786 assign to self, which changes its type midstream. */
6787 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
6789 push_parm_decl (build_tree_list
6790 (build_tree_list (decl_specs
,
6791 build1 (INDIRECT_REF
, NULL_TREE
, self_id
)),
6794 decl_specs
= build_tree_list (NULL_TREE
,
6795 xref_tag (RECORD_TYPE
,
6796 get_identifier (TAG_SELECTOR
)));
6797 push_parm_decl (build_tree_list
6798 (build_tree_list (decl_specs
,
6799 build1 (INDIRECT_REF
, NULL_TREE
, ucmd_id
)),
6802 /* Generate argument declarations if a keyword_decl. */
6803 if (METHOD_SEL_ARGS (method
))
6805 tree arglist
= METHOD_SEL_ARGS (method
);
6808 tree arg_spec
= TREE_PURPOSE (TREE_TYPE (arglist
));
6809 tree arg_decl
= TREE_VALUE (TREE_TYPE (arglist
));
6813 tree last_expr
= expr_last (arg_decl
);
6815 /* Unite the abstract decl with its name. */
6816 TREE_OPERAND (last_expr
, 0) = KEYWORD_ARG_NAME (arglist
);
6817 push_parm_decl (build_tree_list
6818 (build_tree_list (arg_spec
, arg_decl
),
6821 /* Unhook: restore the abstract declarator. */
6822 TREE_OPERAND (last_expr
, 0) = NULL_TREE
;
6826 push_parm_decl (build_tree_list
6827 (build_tree_list (arg_spec
,
6828 KEYWORD_ARG_NAME (arglist
)),
6831 arglist
= TREE_CHAIN (arglist
);
6836 if (METHOD_ADD_ARGS (method
) != NULL_TREE
6837 && METHOD_ADD_ARGS (method
) != objc_ellipsis_node
)
6839 /* We have a variable length selector - in "prototype" format. */
6840 tree akey
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
6843 /* This must be done prior to calling pushdecl. pushdecl is
6844 going to change our chain on us. */
6845 tree nextkey
= TREE_CHAIN (akey
);
6853 warn_with_method (message
, mtype
, method
)
6854 const char *message
;
6858 if (!diagnostic_count_diagnostic (global_dc
, DK_WARNING
))
6861 diagnostic_report_current_function (global_dc
);
6863 /* Add a readable method name to the warning. */
6864 warning_with_file_and_line (DECL_SOURCE_FILE (method
),
6865 DECL_SOURCE_LINE (method
),
6868 gen_method_decl (method
, errbuf
));
6871 /* Return 1 if METHOD is consistent with PROTO. */
6874 comp_method_with_proto (method
, proto
)
6877 /* Create a function template node at most once. */
6878 if (!function1_template
)
6879 function1_template
= make_node (FUNCTION_TYPE
);
6881 /* Install argument types - normally set by build_function_type. */
6882 TYPE_ARG_TYPES (function1_template
) = get_arg_type_list (proto
, METHOD_DEF
, 0);
6884 /* install return type */
6885 TREE_TYPE (function1_template
) = groktypename (TREE_TYPE (proto
));
6887 return comptypes (TREE_TYPE (METHOD_DEFINITION (method
)), function1_template
);
6890 /* Return 1 if PROTO1 is consistent with PROTO2. */
6893 comp_proto_with_proto (proto0
, proto1
)
6894 tree proto0
, proto1
;
6896 /* Create a couple of function_template nodes at most once. */
6897 if (!function1_template
)
6898 function1_template
= make_node (FUNCTION_TYPE
);
6899 if (!function2_template
)
6900 function2_template
= make_node (FUNCTION_TYPE
);
6902 /* Install argument types; normally set by build_function_type. */
6903 TYPE_ARG_TYPES (function1_template
) = get_arg_type_list (proto0
, METHOD_REF
, 0);
6904 TYPE_ARG_TYPES (function2_template
) = get_arg_type_list (proto1
, METHOD_REF
, 0);
6906 /* Install return type. */
6907 TREE_TYPE (function1_template
) = groktypename (TREE_TYPE (proto0
));
6908 TREE_TYPE (function2_template
) = groktypename (TREE_TYPE (proto1
));
6910 return comptypes (function1_template
, function2_template
);
6913 /* - Generate an identifier for the function. the format is "_n_cls",
6914 where 1 <= n <= nMethods, and cls is the name the implementation we
6916 - Install the return type from the method declaration.
6917 - If we have a prototype, check for type consistency. */
6920 really_start_method (method
, parmlist
)
6921 tree method
, parmlist
;
6923 tree sc_spec
, ret_spec
, ret_decl
, decl_specs
;
6924 tree method_decl
, method_id
;
6925 const char *sel_name
, *class_name
, *cat_name
;
6928 /* Synth the storage class & assemble the return type. */
6929 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
6930 ret_spec
= TREE_PURPOSE (TREE_TYPE (method
));
6931 decl_specs
= chainon (sc_spec
, ret_spec
);
6933 sel_name
= IDENTIFIER_POINTER (METHOD_SEL_NAME (method
));
6934 class_name
= IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
6935 cat_name
= ((TREE_CODE (objc_implementation_context
)
6936 == CLASS_IMPLEMENTATION_TYPE
)
6938 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
6941 /* Make sure this is big enough for any plausible method label. */
6942 buf
= (char *) alloca (50 + strlen (sel_name
) + strlen (class_name
)
6943 + (cat_name
? strlen (cat_name
) : 0));
6945 OBJC_GEN_METHOD_LABEL (buf
, TREE_CODE (method
) == INSTANCE_METHOD_DECL
,
6946 class_name
, cat_name
, sel_name
, method_slot
);
6948 method_id
= get_identifier (buf
);
6950 method_decl
= build_nt (CALL_EXPR
, method_id
, parmlist
, NULL_TREE
);
6952 /* Check the declarator portion of the return type for the method. */
6953 if ((ret_decl
= TREE_VALUE (TREE_TYPE (method
))))
6955 /* Unite the complex decl (specified in the abstract decl) with the
6956 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
6957 tree save_expr
= expr_last (ret_decl
);
6959 TREE_OPERAND (save_expr
, 0) = method_decl
;
6960 method_decl
= ret_decl
;
6962 /* Fool the parser into thinking it is starting a function. */
6963 start_function (decl_specs
, method_decl
, NULL_TREE
);
6965 /* Unhook: this has the effect of restoring the abstract declarator. */
6966 TREE_OPERAND (save_expr
, 0) = NULL_TREE
;
6971 TREE_VALUE (TREE_TYPE (method
)) = method_decl
;
6973 /* Fool the parser into thinking it is starting a function. */
6974 start_function (decl_specs
, method_decl
, NULL_TREE
);
6976 /* Unhook: this has the effect of restoring the abstract declarator. */
6977 TREE_VALUE (TREE_TYPE (method
)) = NULL_TREE
;
6980 METHOD_DEFINITION (method
) = current_function_decl
;
6982 /* Check consistency...start_function, pushdecl, duplicate_decls. */
6984 if (implementation_template
!= objc_implementation_context
)
6988 if (TREE_CODE (method
) == INSTANCE_METHOD_DECL
)
6989 proto
= lookup_instance_method_static (implementation_template
,
6990 METHOD_SEL_NAME (method
));
6992 proto
= lookup_class_method_static (implementation_template
,
6993 METHOD_SEL_NAME (method
));
6995 if (proto
&& ! comp_method_with_proto (method
, proto
))
6997 char type
= (TREE_CODE (method
) == INSTANCE_METHOD_DECL
? '-' : '+');
6999 warn_with_method ("conflicting types for", type
, method
);
7000 warn_with_method ("previous declaration of", type
, proto
);
7005 /* The following routine is always called...this "architecture" is to
7006 accommodate "old-style" variable length selectors.
7008 - a:a b:b // prototype ; id c; id d; // old-style. */
7011 continue_method_def ()
7015 if (METHOD_ADD_ARGS (objc_method_context
) == objc_ellipsis_node
)
7016 /* We have a `, ...' immediately following the selector. */
7017 parmlist
= get_parm_info (0);
7019 parmlist
= get_parm_info (1); /* place a `void_at_end' */
7021 /* Set self_decl from the first argument...this global is used by
7022 build_ivar_reference calling build_indirect_ref. */
7023 self_decl
= TREE_PURPOSE (parmlist
);
7026 really_start_method (objc_method_context
, parmlist
);
7027 store_parm_decls ();
7030 /* Called by the parser, from the `pushlevel' production. */
7035 if (!UOBJC_SUPER_decl
)
7037 UOBJC_SUPER_decl
= start_decl (get_identifier (UTAG_SUPER
),
7038 build_tree_list (NULL_TREE
,
7039 objc_super_template
),
7042 finish_decl (UOBJC_SUPER_decl
, NULL_TREE
, NULL_TREE
);
7044 /* This prevents `unused variable' warnings when compiling with -Wall. */
7045 TREE_USED (UOBJC_SUPER_decl
) = 1;
7046 DECL_ARTIFICIAL (UOBJC_SUPER_decl
) = 1;
7050 /* _n_Method (id self, SEL sel, ...)
7052 struct objc_super _S;
7053 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7057 get_super_receiver ()
7059 if (objc_method_context
)
7061 tree super_expr
, super_expr_list
;
7063 /* Set receiver to self. */
7064 super_expr
= build_component_ref (UOBJC_SUPER_decl
, self_id
);
7065 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, self_decl
);
7066 super_expr_list
= build_tree_list (NULL_TREE
, super_expr
);
7068 /* Set class to begin searching. */
7069 super_expr
= build_component_ref (UOBJC_SUPER_decl
,
7070 get_identifier ("class"));
7072 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
7074 /* [_cls, __cls]Super are "pre-built" in
7075 synth_forward_declarations. */
7077 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
,
7078 ((TREE_CODE (objc_method_context
)
7079 == INSTANCE_METHOD_DECL
)
7081 : uucls_super_ref
));
7085 /* We have a category. */
7087 tree super_name
= CLASS_SUPER_NAME (implementation_template
);
7090 /* Barf if super used in a category of Object. */
7093 error ("no super class declared in interface for `%s'",
7094 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
7095 return error_mark_node
;
7098 if (flag_next_runtime
)
7100 super_class
= get_class_reference (super_name
);
7101 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
7103 = build_component_ref (build_indirect_ref (super_class
, "->"),
7104 get_identifier ("isa"));
7108 add_class_reference (super_name
);
7109 super_class
= (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
7110 ? objc_get_class_decl
: objc_get_meta_class_decl
);
7111 assemble_external (super_class
);
7113 = build_function_call
7117 my_build_string (IDENTIFIER_LENGTH (super_name
) + 1,
7118 IDENTIFIER_POINTER (super_name
))));
7121 TREE_TYPE (super_class
) = TREE_TYPE (ucls_super_ref
);
7122 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, super_class
);
7125 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7127 super_expr
= build_unary_op (ADDR_EXPR
, UOBJC_SUPER_decl
, 0);
7128 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7130 return build_compound_expr (super_expr_list
);
7134 error ("[super ...] must appear in a method context");
7135 return error_mark_node
;
7140 encode_method_def (func_decl
)
7145 HOST_WIDE_INT max_parm_end
= 0;
7150 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
7151 obstack_object_size (&util_obstack
),
7152 OBJC_ENCODE_INLINE_DEFS
);
7155 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7156 parms
= TREE_CHAIN (parms
))
7158 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
7159 + int_size_in_bytes (TREE_TYPE (parms
)));
7161 if (! offset_is_register
&& parm_end
> max_parm_end
)
7162 max_parm_end
= parm_end
;
7165 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
7167 sprintf (buffer
, "%d", stack_size
);
7168 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7170 /* Argument types. */
7171 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7172 parms
= TREE_CHAIN (parms
))
7175 encode_type (TREE_TYPE (parms
),
7176 obstack_object_size (&util_obstack
),
7177 OBJC_ENCODE_INLINE_DEFS
);
7179 /* Compute offset. */
7180 sprintf (buffer
, "%d", forwarding_offset (parms
));
7182 /* Indicate register. */
7183 if (offset_is_register
)
7184 obstack_1grow (&util_obstack
, '+');
7186 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7189 /* Null terminate string. */
7190 obstack_1grow (&util_obstack
, 0);
7191 result
= get_identifier (obstack_finish (&util_obstack
));
7192 obstack_free (&util_obstack
, util_firstobj
);
7197 objc_expand_function_end ()
7199 METHOD_ENCODING (objc_method_context
) = encode_method_def (current_function_decl
);
7203 finish_method_def ()
7205 lang_expand_function_end
= objc_expand_function_end
;
7206 finish_function (0, 1);
7207 lang_expand_function_end
= NULL
;
7209 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7210 since the optimizer may find "may be used before set" errors. */
7211 objc_method_context
= NULL_TREE
;
7216 lang_report_error_function (decl
)
7219 if (objc_method_context
)
7221 fprintf (stderr
, "In method `%s'\n",
7222 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context
)));
7232 is_complex_decl (type
)
7235 return (TREE_CODE (type
) == ARRAY_TYPE
7236 || TREE_CODE (type
) == FUNCTION_TYPE
7237 || (TREE_CODE (type
) == POINTER_TYPE
&& ! IS_ID (type
)));
7241 /* Code to convert a decl node into text for a declaration in C. */
7243 static char tmpbuf
[256];
7246 adorn_decl (decl
, str
)
7250 enum tree_code code
= TREE_CODE (decl
);
7252 if (code
== ARRAY_REF
)
7254 tree an_int_cst
= TREE_OPERAND (decl
, 1);
7256 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_CST
)
7257 sprintf (str
+ strlen (str
), "[%ld]",
7258 (long) TREE_INT_CST_LOW (an_int_cst
));
7263 else if (code
== ARRAY_TYPE
)
7265 tree an_int_cst
= TYPE_SIZE (decl
);
7266 tree array_of
= TREE_TYPE (decl
);
7268 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_TYPE
)
7269 sprintf (str
+ strlen (str
), "[%ld]",
7270 (long) (TREE_INT_CST_LOW (an_int_cst
)
7271 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
7276 else if (code
== CALL_EXPR
)
7278 tree chain
= TREE_PURPOSE (TREE_OPERAND (decl
, 1));
7283 gen_declaration_1 (chain
, str
);
7284 chain
= TREE_CHAIN (chain
);
7291 else if (code
== FUNCTION_TYPE
)
7293 tree chain
= TYPE_ARG_TYPES (decl
);
7296 while (chain
&& TREE_VALUE (chain
) != void_type_node
)
7298 gen_declaration_1 (TREE_VALUE (chain
), str
);
7299 chain
= TREE_CHAIN (chain
);
7300 if (chain
&& TREE_VALUE (chain
) != void_type_node
)
7306 else if (code
== INDIRECT_REF
)
7308 strcpy (tmpbuf
, "*");
7309 if (TREE_TYPE (decl
) && TREE_CODE (TREE_TYPE (decl
)) == TREE_LIST
)
7313 for (chain
= nreverse (copy_list (TREE_TYPE (decl
)));
7315 chain
= TREE_CHAIN (chain
))
7317 if (TREE_CODE (TREE_VALUE (chain
)) == IDENTIFIER_NODE
)
7319 strcat (tmpbuf
, " ");
7320 strcat (tmpbuf
, IDENTIFIER_POINTER (TREE_VALUE (chain
)));
7324 strcat (tmpbuf
, " ");
7326 strcat (tmpbuf
, str
);
7327 strcpy (str
, tmpbuf
);
7330 else if (code
== POINTER_TYPE
)
7332 strcpy (tmpbuf
, "*");
7333 if (TREE_READONLY (decl
) || TYPE_VOLATILE (decl
))
7335 if (TREE_READONLY (decl
))
7336 strcat (tmpbuf
, " const");
7337 if (TYPE_VOLATILE (decl
))
7338 strcat (tmpbuf
, " volatile");
7340 strcat (tmpbuf
, " ");
7342 strcat (tmpbuf
, str
);
7343 strcpy (str
, tmpbuf
);
7348 gen_declarator (decl
, buf
, name
)
7355 enum tree_code code
= TREE_CODE (decl
);
7365 op
= TREE_OPERAND (decl
, 0);
7367 /* We have a pointer to a function or array...(*)(), (*)[] */
7368 if ((code
== ARRAY_REF
|| code
== CALL_EXPR
)
7369 && op
&& TREE_CODE (op
) == INDIRECT_REF
)
7372 str
= gen_declarator (op
, buf
, name
);
7376 strcpy (tmpbuf
, "(");
7377 strcat (tmpbuf
, str
);
7378 strcat (tmpbuf
, ")");
7379 strcpy (str
, tmpbuf
);
7382 adorn_decl (decl
, str
);
7391 /* This clause is done iteratively rather than recursively. */
7394 op
= (is_complex_decl (TREE_TYPE (decl
))
7395 ? TREE_TYPE (decl
) : NULL_TREE
);
7397 adorn_decl (decl
, str
);
7399 /* We have a pointer to a function or array...(*)(), (*)[] */
7400 if (code
== POINTER_TYPE
7401 && op
&& (TREE_CODE (op
) == FUNCTION_TYPE
7402 || TREE_CODE (op
) == ARRAY_TYPE
))
7404 strcpy (tmpbuf
, "(");
7405 strcat (tmpbuf
, str
);
7406 strcat (tmpbuf
, ")");
7407 strcpy (str
, tmpbuf
);
7410 decl
= (is_complex_decl (TREE_TYPE (decl
))
7411 ? TREE_TYPE (decl
) : NULL_TREE
);
7414 while (decl
&& (code
= TREE_CODE (decl
)))
7419 case IDENTIFIER_NODE
:
7420 /* Will only happen if we are processing a "raw" expr-decl. */
7421 strcpy (buf
, IDENTIFIER_POINTER (decl
));
7432 /* We have an abstract declarator or a _DECL node. */
7440 gen_declspecs (declspecs
, buf
, raw
)
7449 for (chain
= nreverse (copy_list (declspecs
));
7450 chain
; chain
= TREE_CHAIN (chain
))
7452 tree aspec
= TREE_VALUE (chain
);
7454 if (TREE_CODE (aspec
) == IDENTIFIER_NODE
)
7455 strcat (buf
, IDENTIFIER_POINTER (aspec
));
7456 else if (TREE_CODE (aspec
) == RECORD_TYPE
)
7458 if (TYPE_NAME (aspec
))
7460 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7462 if (! TREE_STATIC_TEMPLATE (aspec
))
7463 strcat (buf
, "struct ");
7464 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7469 tree chain
= protocol_list
;
7476 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7477 chain
= TREE_CHAIN (chain
);
7486 strcat (buf
, "untagged struct");
7489 else if (TREE_CODE (aspec
) == UNION_TYPE
)
7491 if (TYPE_NAME (aspec
))
7493 if (! TREE_STATIC_TEMPLATE (aspec
))
7494 strcat (buf
, "union ");
7495 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7498 strcat (buf
, "untagged union");
7501 else if (TREE_CODE (aspec
) == ENUMERAL_TYPE
)
7503 if (TYPE_NAME (aspec
))
7505 if (! TREE_STATIC_TEMPLATE (aspec
))
7506 strcat (buf
, "enum ");
7507 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7510 strcat (buf
, "untagged enum");
7513 else if (TREE_CODE (aspec
) == TYPE_DECL
&& DECL_NAME (aspec
))
7514 strcat (buf
, IDENTIFIER_POINTER (DECL_NAME (aspec
)));
7516 else if (IS_ID (aspec
))
7518 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7523 tree chain
= protocol_list
;
7530 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7531 chain
= TREE_CHAIN (chain
);
7538 if (TREE_CHAIN (chain
))
7544 /* Type qualifiers. */
7545 if (TREE_READONLY (declspecs
))
7546 strcat (buf
, "const ");
7547 if (TYPE_VOLATILE (declspecs
))
7548 strcat (buf
, "volatile ");
7550 switch (TREE_CODE (declspecs
))
7552 /* Type specifiers. */
7555 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7557 /* Signed integer types. */
7559 if (declspecs
== short_integer_type_node
)
7560 strcat (buf
, "short int ");
7561 else if (declspecs
== integer_type_node
)
7562 strcat (buf
, "int ");
7563 else if (declspecs
== long_integer_type_node
)
7564 strcat (buf
, "long int ");
7565 else if (declspecs
== long_long_integer_type_node
)
7566 strcat (buf
, "long long int ");
7567 else if (declspecs
== signed_char_type_node
7568 || declspecs
== char_type_node
)
7569 strcat (buf
, "char ");
7571 /* Unsigned integer types. */
7573 else if (declspecs
== short_unsigned_type_node
)
7574 strcat (buf
, "unsigned short ");
7575 else if (declspecs
== unsigned_type_node
)
7576 strcat (buf
, "unsigned int ");
7577 else if (declspecs
== long_unsigned_type_node
)
7578 strcat (buf
, "unsigned long ");
7579 else if (declspecs
== long_long_unsigned_type_node
)
7580 strcat (buf
, "unsigned long long ");
7581 else if (declspecs
== unsigned_char_type_node
)
7582 strcat (buf
, "unsigned char ");
7586 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7588 if (declspecs
== float_type_node
)
7589 strcat (buf
, "float ");
7590 else if (declspecs
== double_type_node
)
7591 strcat (buf
, "double ");
7592 else if (declspecs
== long_double_type_node
)
7593 strcat (buf
, "long double ");
7597 if (TYPE_NAME (declspecs
)
7598 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7600 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7602 if (! TREE_STATIC_TEMPLATE (declspecs
))
7603 strcat (buf
, "struct ");
7604 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7608 tree chain
= protocol_list
;
7615 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7616 chain
= TREE_CHAIN (chain
);
7625 strcat (buf
, "untagged struct");
7631 if (TYPE_NAME (declspecs
)
7632 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7634 strcat (buf
, "union ");
7635 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7640 strcat (buf
, "untagged union ");
7644 if (TYPE_NAME (declspecs
)
7645 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7647 strcat (buf
, "enum ");
7648 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7653 strcat (buf
, "untagged enum ");
7657 strcat (buf
, "void ");
7662 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7667 tree chain
= protocol_list
;
7674 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7675 chain
= TREE_CHAIN (chain
);
7691 /* Given a tree node, produce a printable description of it in the given
7692 buffer, overwriting the buffer. */
7695 gen_declaration (atype_or_adecl
, buf
)
7696 tree atype_or_adecl
;
7700 gen_declaration_1 (atype_or_adecl
, buf
);
7704 /* Given a tree node, append a printable description to the end of the
7708 gen_declaration_1 (atype_or_adecl
, buf
)
7709 tree atype_or_adecl
;
7714 if (TREE_CODE (atype_or_adecl
) == TREE_LIST
)
7716 tree declspecs
; /* "identifier_node", "record_type" */
7717 tree declarator
; /* "array_ref", "indirect_ref", "call_expr"... */
7719 /* We have a "raw", abstract declarator (typename). */
7720 declarator
= TREE_VALUE (atype_or_adecl
);
7721 declspecs
= TREE_PURPOSE (atype_or_adecl
);
7723 gen_declspecs (declspecs
, buf
, 1);
7727 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7734 tree declspecs
; /* "integer_type", "real_type", "record_type"... */
7735 tree declarator
; /* "array_type", "function_type", "pointer_type". */
7737 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7738 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7739 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7740 atype
= TREE_TYPE (atype_or_adecl
);
7742 /* Assume we have a *_type node. */
7743 atype
= atype_or_adecl
;
7745 if (is_complex_decl (atype
))
7749 /* Get the declaration specifier; it is at the end of the list. */
7750 declarator
= chain
= atype
;
7752 chain
= TREE_TYPE (chain
); /* not TREE_CHAIN (chain); */
7753 while (is_complex_decl (chain
));
7760 declarator
= NULL_TREE
;
7763 gen_declspecs (declspecs
, buf
, 0);
7765 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7766 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7767 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7769 const char *const decl_name
=
7770 (DECL_NAME (atype_or_adecl
)
7771 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl
)) : "");
7776 strcat (buf
, gen_declarator (declarator
, declbuf
, decl_name
));
7779 else if (decl_name
[0])
7782 strcat (buf
, decl_name
);
7785 else if (declarator
)
7788 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7793 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7795 /* Given a method tree, put a printable description into the given
7796 buffer (overwriting) and return a pointer to the buffer. */
7799 gen_method_decl (method
, buf
)
7806 if (RAW_TYPESPEC (method
) != objc_object_reference
)
7809 gen_declaration_1 (TREE_TYPE (method
), buf
);
7813 chain
= METHOD_SEL_ARGS (method
);
7816 /* We have a chain of keyword_decls. */
7819 if (KEYWORD_KEY_NAME (chain
))
7820 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain
)));
7823 if (RAW_TYPESPEC (chain
) != objc_object_reference
)
7826 gen_declaration_1 (TREE_TYPE (chain
), buf
);
7830 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain
)));
7831 if ((chain
= TREE_CHAIN (chain
)))
7836 if (METHOD_ADD_ARGS (method
) == objc_ellipsis_node
)
7837 strcat (buf
, ", ...");
7838 else if (METHOD_ADD_ARGS (method
))
7840 /* We have a tree list node as generate by get_parm_info. */
7841 chain
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
7843 /* Know we have a chain of parm_decls. */
7847 gen_declaration_1 (chain
, buf
);
7848 chain
= TREE_CHAIN (chain
);
7854 /* We have a unary selector. */
7855 strcat (buf
, IDENTIFIER_POINTER (METHOD_SEL_NAME (method
)));
7863 dump_interface (fp
, chain
)
7867 char *buf
= (char *) xmalloc (256);
7868 const char *my_name
= IDENTIFIER_POINTER (CLASS_NAME (chain
));
7869 tree ivar_decls
= CLASS_RAW_IVARS (chain
);
7870 tree nst_methods
= CLASS_NST_METHODS (chain
);
7871 tree cls_methods
= CLASS_CLS_METHODS (chain
);
7873 fprintf (fp
, "\n@interface %s", my_name
);
7875 if (CLASS_SUPER_NAME (chain
))
7877 const char *super_name
= IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain
));
7878 fprintf (fp
, " : %s\n", super_name
);
7885 fprintf (fp
, "{\n");
7888 fprintf (fp
, "\t%s;\n", gen_declaration (ivar_decls
, buf
));
7889 ivar_decls
= TREE_CHAIN (ivar_decls
);
7892 fprintf (fp
, "}\n");
7897 fprintf (fp
, "- %s;\n", gen_method_decl (nst_methods
, buf
));
7898 nst_methods
= TREE_CHAIN (nst_methods
);
7903 fprintf (fp
, "+ %s;\n", gen_method_decl (cls_methods
, buf
));
7904 cls_methods
= TREE_CHAIN (cls_methods
);
7906 fprintf (fp
, "\n@end");
7909 /* Demangle function for Objective-C */
7911 objc_demangle (mangled
)
7912 const char *mangled
;
7914 char *demangled
, *cp
;
7916 if (mangled
[0] == '_' &&
7917 (mangled
[1] == 'i' || mangled
[1] == 'c') &&
7920 cp
= demangled
= xmalloc(strlen(mangled
) + 2);
7921 if (mangled
[1] == 'i')
7922 *cp
++ = '-'; /* for instance method */
7924 *cp
++ = '+'; /* for class method */
7925 *cp
++ = '['; /* opening left brace */
7926 strcpy(cp
, mangled
+3); /* tack on the rest of the mangled name */
7927 while (*cp
&& *cp
== '_')
7928 cp
++; /* skip any initial underbars in class name */
7929 cp
= strchr(cp
, '_'); /* find first non-initial underbar */
7932 free(demangled
); /* not mangled name */
7935 if (cp
[1] == '_') /* easy case: no category name */
7937 *cp
++ = ' '; /* replace two '_' with one ' ' */
7938 strcpy(cp
, mangled
+ (cp
- demangled
) + 2);
7942 *cp
++ = '('; /* less easy case: category name */
7943 cp
= strchr(cp
, '_');
7946 free(demangled
); /* not mangled name */
7950 *cp
++ = ' '; /* overwriting 1st char of method name... */
7951 strcpy(cp
, mangled
+ (cp
- demangled
)); /* get it back */
7953 while (*cp
&& *cp
== '_')
7954 cp
++; /* skip any initial underbars in method name */
7957 *cp
= ':'; /* replace remaining '_' with ':' */
7958 *cp
++ = ']'; /* closing right brace */
7959 *cp
++ = 0; /* string terminator */
7963 return mangled
; /* not an objc mangled name */
7967 objc_printable_name (decl
, kind
)
7969 int kind ATTRIBUTE_UNUSED
;
7971 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl
)));
7977 gcc_obstack_init (&util_obstack
);
7978 util_firstobj
= (char *) obstack_finish (&util_obstack
);
7980 errbuf
= (char *) xmalloc (BUFSIZE
);
7982 synth_module_prologue ();
7988 struct imp_entry
*impent
;
7990 /* The internally generated initializers appear to have missing braces.
7991 Don't warn about this. */
7992 int save_warn_missing_braces
= warn_missing_braces
;
7993 warn_missing_braces
= 0;
7995 /* A missing @end may not be detected by the parser. */
7996 if (objc_implementation_context
)
7998 warning ("`@end' missing in implementation context");
7999 finish_class (objc_implementation_context
);
8000 objc_ivar_chain
= NULL_TREE
;
8001 objc_implementation_context
= NULL_TREE
;
8004 generate_forward_declaration_to_string_table ();
8006 #ifdef OBJC_PROLOGUE
8010 /* Process the static instances here because initialization of objc_symtab
8012 if (objc_static_instances
)
8013 generate_static_references ();
8015 if (imp_list
|| class_names_chain
8016 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8017 generate_objc_symtab_decl ();
8019 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8021 objc_implementation_context
= impent
->imp_context
;
8022 implementation_template
= impent
->imp_template
;
8024 UOBJC_CLASS_decl
= impent
->class_decl
;
8025 UOBJC_METACLASS_decl
= impent
->meta_decl
;
8027 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
8029 /* all of the following reference the string pool... */
8030 generate_ivar_lists ();
8031 generate_dispatch_tables ();
8032 generate_shared_structures ();
8036 generate_dispatch_tables ();
8037 generate_category (objc_implementation_context
);
8041 /* If we are using an array of selectors, we must always
8042 finish up the array decl even if no selectors were used. */
8043 if (! flag_next_runtime
|| sel_ref_chain
)
8044 build_selector_translation_table ();
8047 generate_protocols ();
8049 if (objc_implementation_context
|| class_names_chain
|| objc_static_instances
8050 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8052 /* Arrange for ObjC data structures to be initialized at run time. */
8053 rtx init_sym
= build_module_descriptor ();
8054 if (init_sym
&& targetm
.have_ctors_dtors
)
8055 (* targetm
.asm_out
.constructor
) (init_sym
, DEFAULT_INIT_PRIORITY
);
8058 /* Dump the class references. This forces the appropriate classes
8059 to be linked into the executable image, preserving unix archive
8060 semantics. This can be removed when we move to a more dynamically
8061 linked environment. */
8063 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
8065 handle_class_ref (chain
);
8066 if (TREE_PURPOSE (chain
))
8067 generate_classref_translation_entry (chain
);
8070 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8071 handle_impent (impent
);
8073 /* Dump the string table last. */
8075 generate_strings ();
8077 if (flag_gen_declaration
)
8079 add_class (objc_implementation_context
);
8080 dump_interface (gen_declaration_file
, objc_implementation_context
);
8088 /* Run through the selector hash tables and print a warning for any
8089 selector which has multiple methods. */
8091 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8092 for (hsh
= cls_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8095 tree meth
= hsh
->key
;
8096 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8100 warning ("potential selector conflict for method `%s'",
8101 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8102 warn_with_method ("found", type
, meth
);
8103 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8104 warn_with_method ("found", type
, loop
->value
);
8107 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8108 for (hsh
= nst_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8111 tree meth
= hsh
->key
;
8112 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8116 warning ("potential selector conflict for method `%s'",
8117 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8118 warn_with_method ("found", type
, meth
);
8119 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8120 warn_with_method ("found", type
, loop
->value
);
8124 warn_missing_braces
= save_warn_missing_braces
;
8127 /* Subroutines of finish_objc. */
8130 generate_classref_translation_entry (chain
)
8133 tree expr
, name
, decl_specs
, decl
, sc_spec
;
8136 type
= TREE_TYPE (TREE_PURPOSE (chain
));
8138 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
8139 expr
= build_c_cast (type
, expr
); /* cast! */
8141 name
= DECL_NAME (TREE_PURPOSE (chain
));
8143 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
8145 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8146 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
8148 /* The decl that is returned from start_decl is the one that we
8149 forward declared in build_class_reference. */
8150 decl
= start_decl (name
, decl_specs
, 1, NULL_TREE
);
8151 DECL_CONTEXT (decl
) = NULL_TREE
;
8152 finish_decl (decl
, expr
, NULL_TREE
);
8157 handle_class_ref (chain
)
8160 const char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
8161 char *string
= (char *) alloca (strlen (name
) + 30);
8165 sprintf (string
, "%sobjc_class_name_%s",
8166 (flag_next_runtime
? "." : "__"), name
);
8168 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8169 if (flag_next_runtime
)
8171 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file
, string
);
8176 /* Make a decl for this name, so we can use its address in a tree. */
8177 decl
= build_decl (VAR_DECL
, get_identifier (string
), char_type_node
);
8178 DECL_EXTERNAL (decl
) = 1;
8179 TREE_PUBLIC (decl
) = 1;
8182 rest_of_decl_compilation (decl
, 0, 0, 0);
8184 /* Make a decl for the address. */
8185 sprintf (string
, "%sobjc_class_ref_%s",
8186 (flag_next_runtime
? "." : "__"), name
);
8187 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
8188 decl
= build_decl (VAR_DECL
, get_identifier (string
), string_type_node
);
8189 DECL_INITIAL (decl
) = exp
;
8190 TREE_STATIC (decl
) = 1;
8191 TREE_USED (decl
) = 1;
8194 rest_of_decl_compilation (decl
, 0, 0, 0);
8198 handle_impent (impent
)
8199 struct imp_entry
*impent
;
8203 objc_implementation_context
= impent
->imp_context
;
8204 implementation_template
= impent
->imp_template
;
8206 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
8208 const char *const class_name
=
8209 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8211 string
= (char *) alloca (strlen (class_name
) + 30);
8213 sprintf (string
, "%sobjc_class_name_%s",
8214 (flag_next_runtime
? "." : "__"), class_name
);
8216 else if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
8218 const char *const class_name
=
8219 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8220 const char *const class_super_name
=
8221 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
8223 string
= (char *) alloca (strlen (class_name
)
8224 + strlen (class_super_name
) + 30);
8226 /* Do the same for categories. Even though no references to
8227 these symbols are generated automatically by the compiler, it
8228 gives you a handle to pull them into an archive by hand. */
8229 sprintf (string
, "*%sobjc_category_name_%s_%s",
8230 (flag_next_runtime
? "." : "__"), class_name
, class_super_name
);
8235 #ifdef ASM_DECLARE_CLASS_REFERENCE
8236 if (flag_next_runtime
)
8238 ASM_DECLARE_CLASS_REFERENCE (asm_out_file
, string
);
8246 init
= build_int_2 (0, 0);
8247 TREE_TYPE (init
) = c_common_type_for_size (BITS_PER_WORD
, 1);
8248 decl
= build_decl (VAR_DECL
, get_identifier (string
), TREE_TYPE (init
));
8249 TREE_PUBLIC (decl
) = 1;
8250 TREE_READONLY (decl
) = 1;
8251 TREE_USED (decl
) = 1;
8252 TREE_CONSTANT (decl
) = 1;
8253 DECL_CONTEXT (decl
) = 0;
8254 DECL_ARTIFICIAL (decl
) = 1;
8255 DECL_INITIAL (decl
) = init
;
8256 assemble_variable (decl
, 1, 0, 0);
8260 /* Look up ID as an instance variable. */
8262 lookup_objc_ivar (id
)
8267 if (objc_method_context
&& !strcmp (IDENTIFIER_POINTER (id
), "super"))
8268 /* We have a message to super. */
8269 return get_super_receiver ();
8270 else if (objc_method_context
&& (decl
= is_ivar (objc_ivar_chain
, id
)))
8272 if (is_private (decl
))
8273 return error_mark_node
;
8275 return build_ivar_reference (id
);
8281 #include "gtype-objc.h"