1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001
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':
63 /* This is the default way of generating a method name. */
64 /* I am not sure it is really correct.
65 Perhaps there's a danger that it will make name conflicts
66 if method names contain underscores. -- rms. */
67 #ifndef OBJC_GEN_METHOD_LABEL
68 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
71 sprintf ((BUF), "_%s_%s_%s_%s", \
72 ((IS_INST) ? "i" : "c"), \
74 ((CAT_NAME)? (CAT_NAME) : ""), \
76 for (temp = (BUF); *temp; temp++) \
77 if (*temp == ':') *temp = '_'; \
81 /* These need specifying. */
82 #ifndef OBJC_FORWARDING_STACK_OFFSET
83 #define OBJC_FORWARDING_STACK_OFFSET 0
86 #ifndef OBJC_FORWARDING_MIN_OFFSET
87 #define OBJC_FORWARDING_MIN_OFFSET 0
90 /* Define the special tree codes that we use. */
92 /* Table indexed by tree code giving a string containing a character
93 classifying the tree code. */
95 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
97 static const char objc_tree_code_type
[] = {
99 #include "objc-tree.def"
103 /* Table indexed by tree code giving number of expression
104 operands beyond the fixed part of the node structure.
105 Not used for types or decls. */
107 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
109 static const int objc_tree_code_length
[] = {
111 #include "objc-tree.def"
115 /* Names of tree components.
116 Used for printing out the tree and error messages. */
117 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
119 static const char * const objc_tree_code_name
[] = {
121 #include "objc-tree.def"
125 /* Set up for use of obstacks. */
129 #define obstack_chunk_alloc xmalloc
130 #define obstack_chunk_free free
132 /* This obstack is used to accumulate the encoding of a data type. */
133 static struct obstack util_obstack
;
134 /* This points to the beginning of obstack contents,
135 so we can free the whole contents. */
138 /* for encode_method_def */
141 /* The version identifies which language generation and runtime
142 the module (file) was compiled for, and is recorded in the
143 module descriptor. */
145 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
146 #define PROTOCOL_VERSION 2
148 /* (Decide if these can ever be validly changed.) */
149 #define OBJC_ENCODE_INLINE_DEFS 0
150 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
152 /*** Private Interface (procedures) ***/
154 /* Used by compile_file. */
156 static void init_objc
PARAMS ((void));
157 static void finish_objc
PARAMS ((void));
159 /* Code generation. */
161 static void synth_module_prologue
PARAMS ((void));
162 static tree build_constructor
PARAMS ((tree
, tree
));
163 static rtx build_module_descriptor
PARAMS ((void));
164 static tree init_module_descriptor
PARAMS ((tree
));
165 static tree build_objc_method_call
PARAMS ((int, tree
, tree
,
167 static void generate_strings
PARAMS ((void));
168 static tree get_proto_encoding
PARAMS ((tree
));
169 static void build_selector_translation_table
PARAMS ((void));
170 static tree build_ivar_chain
PARAMS ((tree
, int));
172 static tree objc_add_static_instance
PARAMS ((tree
, tree
));
174 static tree build_ivar_template
PARAMS ((void));
175 static tree build_method_template
PARAMS ((void));
176 static tree build_private_template
PARAMS ((tree
));
177 static void build_class_template
PARAMS ((void));
178 static void build_selector_template
PARAMS ((void));
179 static void build_category_template
PARAMS ((void));
180 static tree build_super_template
PARAMS ((void));
181 static tree build_category_initializer
PARAMS ((tree
, tree
, tree
,
183 static tree build_protocol_initializer
PARAMS ((tree
, tree
, tree
,
186 static void synth_forward_declarations
PARAMS ((void));
187 static void generate_ivar_lists
PARAMS ((void));
188 static void generate_dispatch_tables
PARAMS ((void));
189 static void generate_shared_structures
PARAMS ((void));
190 static tree generate_protocol_list
PARAMS ((tree
));
191 static void generate_forward_declaration_to_string_table
PARAMS ((void));
192 static void build_protocol_reference
PARAMS ((tree
));
194 static tree build_keyword_selector
PARAMS ((tree
));
195 static tree synth_id_with_class_suffix
PARAMS ((const char *, tree
));
197 static void generate_static_references
PARAMS ((void));
198 static int check_methods_accessible
PARAMS ((tree
, tree
,
200 static void encode_aggregate_within
PARAMS ((tree
, int, int,
202 static const char *objc_demangle
PARAMS ((const char *));
203 static const char *objc_printable_name
PARAMS ((tree
, int));
204 static void objc_expand_function_end
PARAMS ((void));
206 /* Hash tables to manage the global pool of method prototypes. */
208 hash
*nst_method_hash_list
= 0;
209 hash
*cls_method_hash_list
= 0;
211 static size_t hash_func
PARAMS ((tree
));
212 static void hash_init
PARAMS ((void));
213 static void hash_enter
PARAMS ((hash
*, tree
));
214 static hash hash_lookup
PARAMS ((hash
*, tree
));
215 static void hash_add_attr
PARAMS ((hash
, tree
));
216 static tree lookup_method
PARAMS ((tree
, tree
));
217 static tree lookup_instance_method_static
PARAMS ((tree
, tree
));
218 static tree lookup_class_method_static
PARAMS ((tree
, tree
));
219 static tree add_class
PARAMS ((tree
));
220 static void add_category
PARAMS ((tree
, tree
));
224 class_names
, /* class, category, protocol, module names */
225 meth_var_names
, /* method and variable names */
226 meth_var_types
/* method and variable type descriptors */
229 static tree add_objc_string
PARAMS ((tree
,
230 enum string_section
));
231 static tree get_objc_string_decl
PARAMS ((tree
,
232 enum string_section
));
233 static tree build_objc_string_decl
PARAMS ((enum string_section
));
234 static tree build_selector_reference_decl
PARAMS ((void));
236 /* Protocol additions. */
238 static tree add_protocol
PARAMS ((tree
));
239 static tree lookup_protocol
PARAMS ((tree
));
240 static void check_protocol_recursively
PARAMS ((tree
, tree
));
241 static tree lookup_and_install_protocols
PARAMS ((tree
));
245 static void encode_type_qualifiers
PARAMS ((tree
));
246 static void encode_pointer
PARAMS ((tree
, int, int));
247 static void encode_array
PARAMS ((tree
, int, int));
248 static void encode_aggregate
PARAMS ((tree
, int, int));
249 static void encode_bitfield
PARAMS ((int));
250 static void encode_type
PARAMS ((tree
, int, int));
251 static void encode_field_decl
PARAMS ((tree
, int, int));
253 static void really_start_method
PARAMS ((tree
, tree
));
254 static int comp_method_with_proto
PARAMS ((tree
, tree
));
255 static int comp_proto_with_proto
PARAMS ((tree
, tree
));
256 static tree get_arg_type_list
PARAMS ((tree
, int, int));
257 static tree expr_last
PARAMS ((tree
));
259 /* Utilities for debugging and error diagnostics. */
261 static void warn_with_method
PARAMS ((const char *, int, tree
));
262 static void error_with_ivar
PARAMS ((const char *, tree
, tree
));
263 static char *gen_method_decl
PARAMS ((tree
, char *));
264 static char *gen_declaration
PARAMS ((tree
, char *));
265 static void gen_declaration_1
PARAMS ((tree
, char *));
266 static char *gen_declarator
PARAMS ((tree
, char *,
268 static int is_complex_decl
PARAMS ((tree
));
269 static void adorn_decl
PARAMS ((tree
, char *));
270 static void dump_interface
PARAMS ((FILE *, tree
));
272 /* Everything else. */
274 static void add_objc_tree_codes
PARAMS ((void));
275 static tree define_decl
PARAMS ((tree
, tree
));
276 static tree lookup_method_in_protocol_list
PARAMS ((tree
, tree
, int));
277 static tree lookup_protocol_in_reflist
PARAMS ((tree
, tree
));
278 static tree create_builtin_decl
PARAMS ((enum tree_code
,
279 tree
, const char *));
280 static void setup_string_decl
PARAMS ((void));
281 static tree my_build_string
PARAMS ((int, const char *));
282 static void build_objc_symtab_template
PARAMS ((void));
283 static tree init_def_list
PARAMS ((tree
));
284 static tree init_objc_symtab
PARAMS ((tree
));
285 static void forward_declare_categories
PARAMS ((void));
286 static void generate_objc_symtab_decl
PARAMS ((void));
287 static tree build_selector
PARAMS ((tree
));
288 static tree build_typed_selector_reference
PARAMS ((tree
, tree
));
289 static tree build_selector_reference
PARAMS ((tree
));
290 static tree build_class_reference_decl
PARAMS ((void));
291 static void add_class_reference
PARAMS ((tree
));
292 static tree objc_copy_list
PARAMS ((tree
, tree
*));
293 static tree build_protocol_template
PARAMS ((void));
294 static tree build_descriptor_table_initializer
PARAMS ((tree
, tree
));
295 static tree build_method_prototype_list_template
PARAMS ((tree
, int));
296 static tree build_method_prototype_template
PARAMS ((void));
297 static int forwarding_offset
PARAMS ((tree
));
298 static tree encode_method_prototype
PARAMS ((tree
, tree
));
299 static tree generate_descriptor_table
PARAMS ((tree
, const char *,
301 static void generate_method_descriptors
PARAMS ((tree
));
302 static tree build_tmp_function_decl
PARAMS ((void));
303 static void hack_method_prototype
PARAMS ((tree
, tree
));
304 static void generate_protocol_references
PARAMS ((tree
));
305 static void generate_protocols
PARAMS ((void));
306 static void check_ivars
PARAMS ((tree
, tree
));
307 static tree build_ivar_list_template
PARAMS ((tree
, int));
308 static tree build_method_list_template
PARAMS ((tree
, int));
309 static tree build_ivar_list_initializer
PARAMS ((tree
, tree
));
310 static tree generate_ivars_list
PARAMS ((tree
, const char *,
312 static tree build_dispatch_table_initializer
PARAMS ((tree
, tree
));
313 static tree generate_dispatch_table
PARAMS ((tree
, const char *,
315 static tree build_shared_structure_initializer
PARAMS ((tree
, tree
, tree
, tree
,
316 tree
, int, tree
, tree
,
318 static void generate_category
PARAMS ((tree
));
319 static int is_objc_type_qualifier
PARAMS ((tree
));
320 static tree adjust_type_for_id_default
PARAMS ((tree
));
321 static tree check_duplicates
PARAMS ((hash
));
322 static tree receiver_is_class_object
PARAMS ((tree
));
323 static int check_methods
PARAMS ((tree
, tree
, int));
324 static int conforms_to_protocol
PARAMS ((tree
, tree
));
325 static void check_protocol
PARAMS ((tree
, const char *,
327 static void check_protocols
PARAMS ((tree
, const char *,
329 static tree encode_method_def
PARAMS ((tree
));
330 static void gen_declspecs
PARAMS ((tree
, char *, int));
331 static void generate_classref_translation_entry
PARAMS ((tree
));
332 static void handle_class_ref
PARAMS ((tree
));
333 static void generate_struct_by_value_array
PARAMS ((void))
335 static void objc_act_parse_init
PARAMS ((void));
336 static void ggc_mark_imp_list
PARAMS ((void *));
337 static void ggc_mark_hash_table
PARAMS ((void *));
339 /*** Private Interface (data) ***/
341 /* Reserved tag definitions. */
344 #define TAG_OBJECT "objc_object"
345 #define TAG_CLASS "objc_class"
346 #define TAG_SUPER "objc_super"
347 #define TAG_SELECTOR "objc_selector"
349 #define UTAG_CLASS "_objc_class"
350 #define UTAG_IVAR "_objc_ivar"
351 #define UTAG_IVAR_LIST "_objc_ivar_list"
352 #define UTAG_METHOD "_objc_method"
353 #define UTAG_METHOD_LIST "_objc_method_list"
354 #define UTAG_CATEGORY "_objc_category"
355 #define UTAG_MODULE "_objc_module"
356 #define UTAG_STATICS "_objc_statics"
357 #define UTAG_SYMTAB "_objc_symtab"
358 #define UTAG_SUPER "_objc_super"
359 #define UTAG_SELECTOR "_objc_selector"
361 #define UTAG_PROTOCOL "_objc_protocol"
362 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
363 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
364 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
366 #ifdef NEXT_OBJC_RUNTIME
367 #define STRING_OBJECT_CLASS_NAME "NSConstantString"
369 #define STRING_OBJECT_CLASS_NAME "NXConstantString"
371 /* Note that the string object global name is only needed for the
373 #define STRING_OBJECT_GLOBAL_NAME "_NSConstantStringClassReference"
375 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
377 static const char *constant_string_class_name
= NULL
;
379 static const char *TAG_GETCLASS
;
380 static const char *TAG_GETMETACLASS
;
381 static const char *TAG_MSGSEND
;
382 static const char *TAG_MSGSENDSUPER
;
383 static const char *TAG_EXECCLASS
;
385 /* The OCTI_... enumeration itself in in objc/objc-act.h. */
386 tree objc_global_trees
[OCTI_MAX
];
388 int objc_receiver_context
;
390 static void handle_impent
PARAMS ((struct imp_entry
*));
392 struct imp_entry
*imp_list
= 0;
393 int imp_count
= 0; /* `@implementation' */
394 int cat_count
= 0; /* `@category' */
396 static int method_slot
= 0; /* Used by start_method_def, */
400 static char *errbuf
; /* Buffer for error diagnostics */
402 /* Data imported from tree.c. */
404 extern enum debug_info_type write_symbols
;
406 /* Data imported from toplev.c. */
408 extern const char *dump_base_name
;
410 /* Generate code for GNU or NeXT runtime environment. */
412 #ifdef NEXT_OBJC_RUNTIME
413 int flag_next_runtime
= 1;
415 int flag_next_runtime
= 0;
418 int flag_typed_selectors
;
420 /* Open and close the file for outputting class declarations, if requested. */
422 int flag_gen_declaration
= 0;
424 FILE *gen_declaration_file
;
426 /* Warn if multiple methods are seen for the same selector, but with
427 different argument types. */
429 int warn_selector
= 0;
431 /* Warn if methods required by a protocol are not implemented in the
432 class adopting it. When turned off, methods inherited to that
433 class are also considered implemented */
435 int flag_warn_protocol
= 1;
437 /* Tells "encode_pointer/encode_aggregate" whether we are generating
438 type descriptors for instance variables (as opposed to methods).
439 Type descriptors for instance variables contain more information
440 than methods (for static typing and embedded structures). This
441 was added to support features being planned for dbkit2. */
443 static int generating_instance_variables
= 0;
445 /* Tells the compiler that this is a special run. Do not perform
446 any compiling, instead we are to test some platform dependent
447 features and output a C header file with appropriate definitions. */
449 static int print_struct_values
= 0;
451 static varray_type deferred_fns
;
453 /* Some platforms pass small structures through registers versus through
454 an invisible pointer. Determine at what size structure is the
455 transition point between the two possibilities. */
458 generate_struct_by_value_array ()
461 tree field_decl
, field_decl_chain
;
463 int aggregate_in_mem
[32];
466 /* Presumably no platform passes 32 byte structures in a register. */
467 for (i
= 1; i
< 32; i
++)
471 /* Create an unnamed struct that has `i' character components */
472 type
= start_struct (RECORD_TYPE
, NULL_TREE
);
474 strcpy (buffer
, "c1");
475 field_decl
= create_builtin_decl (FIELD_DECL
,
478 field_decl_chain
= field_decl
;
480 for (j
= 1; j
< i
; j
++)
482 sprintf (buffer
, "c%d", j
+ 1);
483 field_decl
= create_builtin_decl (FIELD_DECL
,
486 chainon (field_decl_chain
, field_decl
);
488 finish_struct (type
, field_decl_chain
, NULL_TREE
);
490 aggregate_in_mem
[i
] = aggregate_value_p (type
);
491 if (!aggregate_in_mem
[i
])
495 /* We found some structures that are returned in registers instead of memory
496 so output the necessary data. */
499 for (i
= 31; i
>= 0; i
--)
500 if (!aggregate_in_mem
[i
])
502 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i
);
504 /* The first member of the structure is always 0 because we don't handle
505 structures with 0 members */
506 printf ("static int struct_forward_array[] = {\n 0");
508 for (j
= 1; j
<= i
; j
++)
509 printf (", %d", aggregate_in_mem
[j
]);
518 const char *filename
;
520 filename
= c_objc_common_init (filename
);
521 add_objc_tree_codes ();
523 decl_printable_name
= objc_printable_name
;
525 /* Force the line number back to 0; check_newline will have
526 raised it to 1, which will make the builtin functions appear
527 not to be built in. */
530 /* If gen_declaration desired, open the output file. */
531 if (flag_gen_declaration
)
533 register char * const dumpname
= concat (dump_base_name
, ".decl", NULL
);
534 gen_declaration_file
= fopen (dumpname
, "w");
535 if (gen_declaration_file
== 0)
536 fatal_io_error ("can't open %s", dumpname
);
540 if (flag_next_runtime
)
542 TAG_GETCLASS
= "objc_getClass";
543 TAG_GETMETACLASS
= "objc_getMetaClass";
544 TAG_MSGSEND
= "objc_msgSend";
545 TAG_MSGSENDSUPER
= "objc_msgSendSuper";
546 TAG_EXECCLASS
= "__objc_execClass";
550 TAG_GETCLASS
= "objc_get_class";
551 TAG_GETMETACLASS
= "objc_get_meta_class";
552 TAG_MSGSEND
= "objc_msg_lookup";
553 TAG_MSGSENDSUPER
= "objc_msg_lookup_super";
554 TAG_EXECCLASS
= "__objc_exec_class";
555 flag_typed_selectors
= 1;
558 objc_ellipsis_node
= make_node (ERROR_MARK
);
562 if (print_struct_values
)
563 generate_struct_by_value_array ();
565 objc_act_parse_init ();
567 VARRAY_TREE_INIT (deferred_fns
, 32, "deferred_fns");
568 ggc_add_tree_varray_root (&deferred_fns
, 1);
573 /* Register a function tree, so that its optimization and conversion
574 to RTL is only done at the end of the compilation. */
580 VARRAY_PUSH_TREE (deferred_fns
, fn
);
590 for (i
= 0; i
< VARRAY_ACTIVE_SIZE (deferred_fns
); i
++)
591 /* Don't output the same function twice. We may run into such
592 situations when an extern inline function is later given a
593 non-extern-inline definition. */
594 if (! TREE_ASM_WRITTEN (VARRAY_TREE (deferred_fns
, i
)))
595 c_expand_deferred_function (VARRAY_TREE (deferred_fns
, i
));
596 VARRAY_FREE (deferred_fns
);
598 finish_objc (); /* Objective-C finalization */
600 if (gen_declaration_file
)
601 fclose (gen_declaration_file
);
605 objc_decode_option (argc
, argv
)
609 const char *p
= argv
[0];
611 if (!strcmp (p
, "-gen-decls"))
612 flag_gen_declaration
= 1;
613 else if (!strcmp (p
, "-Wselector"))
615 else if (!strcmp (p
, "-Wno-selector"))
617 else if (!strcmp (p
, "-Wprotocol"))
618 flag_warn_protocol
= 1;
619 else if (!strcmp (p
, "-Wno-protocol"))
620 flag_warn_protocol
= 0;
621 else if (!strcmp (p
, "-fgnu-runtime"))
622 flag_next_runtime
= 0;
623 else if (!strcmp (p
, "-fno-next-runtime"))
624 flag_next_runtime
= 0;
625 else if (!strcmp (p
, "-fno-gnu-runtime"))
626 flag_next_runtime
= 1;
627 else if (!strcmp (p
, "-fnext-runtime"))
628 flag_next_runtime
= 1;
629 else if (!strcmp (p
, "-print-objc-runtime-info"))
630 print_struct_values
= 1;
631 #define CSTSTRCLASS "-fconstant-string-class="
632 else if (!strncmp (p
, CSTSTRCLASS
, sizeof(CSTSTRCLASS
) - 2)) {
633 if (strlen (argv
[0]) <= strlen (CSTSTRCLASS
))
634 error ("no class name specified as argument to -fconstant-string-class");
635 constant_string_class_name
= xstrdup(argv
[0] + sizeof(CSTSTRCLASS
) - 1);
639 return c_decode_option (argc
, argv
);
646 define_decl (declarator
, declspecs
)
650 tree decl
= start_decl (declarator
, declspecs
, 0, NULL_TREE
);
651 finish_decl (decl
, NULL_TREE
, NULL_TREE
);
655 /* Return 1 if LHS and RHS are compatible types for assignment or
656 various other operations. Return 0 if they are incompatible, and
657 return -1 if we choose to not decide. When the operation is
658 REFLEXIVE, check for compatibility in either direction.
660 For statically typed objects, an assignment of the form `a' = `b'
664 `a' and `b' are the same class type, or
665 `a' and `b' are of class types A and B such that B is a descendant of A. */
668 maybe_objc_comptypes (lhs
, rhs
, reflexive
)
672 return objc_comptypes (lhs
, rhs
, reflexive
);
676 lookup_method_in_protocol_list (rproto_list
, sel_name
, class_meth
)
684 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
686 p
= TREE_VALUE (rproto
);
688 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
690 if ((fnd
= lookup_method (class_meth
691 ? PROTOCOL_CLS_METHODS (p
)
692 : PROTOCOL_NST_METHODS (p
), sel_name
)))
694 else if (PROTOCOL_LIST (p
))
695 fnd
= lookup_method_in_protocol_list (PROTOCOL_LIST (p
),
696 sel_name
, class_meth
);
700 ; /* An identifier...if we could not find a protocol. */
711 lookup_protocol_in_reflist (rproto_list
, lproto
)
717 /* Make sure the protocol is supported by the object on the rhs. */
718 if (TREE_CODE (lproto
) == PROTOCOL_INTERFACE_TYPE
)
721 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
723 p
= TREE_VALUE (rproto
);
725 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
730 else if (PROTOCOL_LIST (p
))
731 fnd
= lookup_protocol_in_reflist (PROTOCOL_LIST (p
), lproto
);
740 ; /* An identifier...if we could not find a protocol. */
746 /* Return 1 if LHS and RHS are compatible types for assignment
747 or various other operations. Return 0 if they are incompatible,
748 and return -1 if we choose to not decide. When the operation
749 is REFLEXIVE, check for compatibility in either direction. */
752 objc_comptypes (lhs
, rhs
, reflexive
)
757 /* New clause for protocols. */
759 if (TREE_CODE (lhs
) == POINTER_TYPE
760 && TREE_CODE (TREE_TYPE (lhs
)) == RECORD_TYPE
761 && TREE_CODE (rhs
) == POINTER_TYPE
762 && TREE_CODE (TREE_TYPE (rhs
)) == RECORD_TYPE
)
764 int lhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (lhs
);
765 int rhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (rhs
);
769 tree lproto
, lproto_list
= TYPE_PROTOCOL_LIST (lhs
);
770 tree rproto
, rproto_list
;
775 rproto_list
= TYPE_PROTOCOL_LIST (rhs
);
777 /* Make sure the protocol is supported by the object
779 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
781 p
= TREE_VALUE (lproto
);
782 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
785 warning ("object does not conform to the `%s' protocol",
786 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
789 else if (TYPED_OBJECT (TREE_TYPE (rhs
)))
791 tree rname
= TYPE_NAME (TREE_TYPE (rhs
));
794 /* Make sure the protocol is supported by the object
796 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
798 p
= TREE_VALUE (lproto
);
800 rinter
= lookup_interface (rname
);
802 while (rinter
&& !rproto
)
806 rproto_list
= CLASS_PROTOCOL_LIST (rinter
);
807 /* If the underlying ObjC class does not have
808 protocols attached to it, perhaps there are
809 "one-off" protocols attached to the rhs?
810 E.g., 'id<MyProt> foo;'. */
812 rproto_list
= TYPE_PROTOCOL_LIST (TREE_TYPE (rhs
));
813 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
815 /* Check for protocols adopted by categories. */
816 cat
= CLASS_CATEGORY_LIST (rinter
);
817 while (cat
&& !rproto
)
819 rproto_list
= CLASS_PROTOCOL_LIST (cat
);
820 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
822 cat
= CLASS_CATEGORY_LIST (cat
);
825 rinter
= lookup_interface (CLASS_SUPER_NAME (rinter
));
829 warning ("class `%s' does not implement the `%s' protocol",
830 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs
))),
831 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
835 /* May change...based on whether there was any mismatch */
838 else if (rhs_is_proto
)
839 /* Lhs is not a protocol...warn if it is statically typed */
840 return (TYPED_OBJECT (TREE_TYPE (lhs
)) != 0);
843 /* Defer to comptypes. */
847 else if (TREE_CODE (lhs
) == RECORD_TYPE
&& TREE_CODE (rhs
) == RECORD_TYPE
)
848 ; /* Fall thru. This is the case we have been handling all along */
850 /* Defer to comptypes. */
853 /* `id' = `<class> *', `<class> *' = `id' */
855 if ((TYPE_NAME (lhs
) == objc_object_id
&& TYPED_OBJECT (rhs
))
856 || (TYPE_NAME (rhs
) == objc_object_id
&& TYPED_OBJECT (lhs
)))
859 /* `id' = `Class', `Class' = `id' */
861 else if ((TYPE_NAME (lhs
) == objc_object_id
862 && TYPE_NAME (rhs
) == objc_class_id
)
863 || (TYPE_NAME (lhs
) == objc_class_id
864 && TYPE_NAME (rhs
) == objc_object_id
))
867 /* `<class> *' = `<class> *' */
869 else if (TYPED_OBJECT (lhs
) && TYPED_OBJECT (rhs
))
871 tree lname
= TYPE_NAME (lhs
);
872 tree rname
= TYPE_NAME (rhs
);
878 /* If the left hand side is a super class of the right hand side,
880 for (inter
= lookup_interface (rname
); inter
;
881 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
882 if (lname
== CLASS_SUPER_NAME (inter
))
885 /* Allow the reverse when reflexive. */
887 for (inter
= lookup_interface (lname
); inter
;
888 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
889 if (rname
== CLASS_SUPER_NAME (inter
))
895 /* Defer to comptypes. */
899 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
902 objc_check_decl (decl
)
905 tree type
= TREE_TYPE (decl
);
907 if (TREE_CODE (type
) == RECORD_TYPE
908 && TREE_STATIC_TEMPLATE (type
)
909 && type
!= constant_string_type
)
910 error_with_decl (decl
, "`%s' cannot be statically allocated");
914 maybe_objc_check_decl (decl
)
917 objc_check_decl (decl
);
920 /* Implement static typing. At this point, we know we have an interface. */
923 get_static_reference (interface
, protocols
)
927 tree type
= xref_tag (RECORD_TYPE
, interface
);
931 tree t
, m
= TYPE_MAIN_VARIANT (type
);
933 t
= copy_node (type
);
934 TYPE_BINFO (t
) = make_tree_vec (2);
936 /* Add this type to the chain of variants of TYPE. */
937 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
938 TYPE_NEXT_VARIANT (m
) = t
;
940 /* Look up protocols and install in lang specific list. Note
941 that the protocol list can have a different lifetime than T! */
942 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
944 /* This forces a new pointer type to be created later
945 (in build_pointer_type)...so that the new template
946 we just created will actually be used...what a hack! */
947 if (TYPE_POINTER_TO (t
))
948 TYPE_POINTER_TO (t
) = NULL_TREE
;
957 get_object_reference (protocols
)
960 tree type_decl
= lookup_name (objc_id_id
);
963 if (type_decl
&& TREE_CODE (type_decl
) == TYPE_DECL
)
965 type
= TREE_TYPE (type_decl
);
966 if (TYPE_MAIN_VARIANT (type
) != id_type
)
967 warning ("unexpected type for `id' (%s)",
968 gen_declaration (type
, errbuf
));
972 error ("undefined type `id', please import <objc/objc.h>");
973 return error_mark_node
;
976 /* This clause creates a new pointer type that is qualified with
977 the protocol specification...this info is used later to do more
978 elaborate type checking. */
982 tree t
, m
= TYPE_MAIN_VARIANT (type
);
984 t
= copy_node (type
);
985 TYPE_BINFO (t
) = make_tree_vec (2);
987 /* Add this type to the chain of variants of TYPE. */
988 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
989 TYPE_NEXT_VARIANT (m
) = t
;
991 /* Look up protocols...and install in lang specific list */
992 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
994 /* This forces a new pointer type to be created later
995 (in build_pointer_type)...so that the new template
996 we just created will actually be used...what a hack! */
997 if (TYPE_POINTER_TO (t
))
998 TYPE_POINTER_TO (t
) = NULL_TREE
;
1005 /* Check for circular dependencies in protocols. The arguments are
1006 PROTO, the protocol to check, and LIST, a list of protocol it
1010 check_protocol_recursively (proto
, list
)
1016 for (p
= list
; p
; p
= TREE_CHAIN (p
))
1018 tree pp
= TREE_VALUE (p
);
1020 if (TREE_CODE (pp
) == IDENTIFIER_NODE
)
1021 pp
= lookup_protocol (pp
);
1024 fatal_error ("protocol `%s' has circular dependency",
1025 IDENTIFIER_POINTER (PROTOCOL_NAME (pp
)));
1027 check_protocol_recursively (proto
, PROTOCOL_LIST (pp
));
1032 lookup_and_install_protocols (protocols
)
1037 tree return_value
= protocols
;
1039 for (proto
= protocols
; proto
; proto
= TREE_CHAIN (proto
))
1041 tree ident
= TREE_VALUE (proto
);
1042 tree p
= lookup_protocol (ident
);
1046 error ("cannot find protocol declaration for `%s'",
1047 IDENTIFIER_POINTER (ident
));
1049 TREE_CHAIN (prev
) = TREE_CHAIN (proto
);
1051 return_value
= TREE_CHAIN (proto
);
1055 /* Replace identifier with actual protocol node. */
1056 TREE_VALUE (proto
) = p
;
1061 return return_value
;
1064 /* Create and push a decl for a built-in external variable or field NAME.
1066 TYPE is its data type. */
1069 create_builtin_decl (code
, type
, name
)
1070 enum tree_code code
;
1074 tree decl
= build_decl (code
, get_identifier (name
), type
);
1076 if (code
== VAR_DECL
)
1078 TREE_STATIC (decl
) = 1;
1079 make_decl_rtl (decl
, 0);
1083 DECL_ARTIFICIAL (decl
) = 1;
1087 /* Find the decl for the constant string class. */
1090 setup_string_decl ()
1092 if (!string_class_decl
)
1094 if (!constant_string_global_id
)
1095 constant_string_global_id
= get_identifier (STRING_OBJECT_GLOBAL_NAME
);
1096 string_class_decl
= lookup_name (constant_string_global_id
);
1100 /* Purpose: "play" parser, creating/installing representations
1101 of the declarations that are required by Objective-C.
1105 type_spec--------->sc_spec
1106 (tree_list) (tree_list)
1109 identifier_node identifier_node */
1112 synth_module_prologue ()
1117 /* Defined in `objc.h' */
1118 objc_object_id
= get_identifier (TAG_OBJECT
);
1120 objc_object_reference
= xref_tag (RECORD_TYPE
, objc_object_id
);
1122 id_type
= build_pointer_type (objc_object_reference
);
1124 objc_id_id
= get_identifier (TYPE_ID
);
1125 objc_class_id
= get_identifier (TAG_CLASS
);
1127 objc_class_type
= build_pointer_type (xref_tag (RECORD_TYPE
, objc_class_id
));
1128 protocol_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
1129 get_identifier (PROTOCOL_OBJECT_CLASS_NAME
)));
1131 /* Declare type of selector-objects that represent an operation name. */
1133 /* `struct objc_selector *' */
1135 = build_pointer_type (xref_tag (RECORD_TYPE
,
1136 get_identifier (TAG_SELECTOR
)));
1138 /* Forward declare type, or else the prototype for msgSendSuper will
1141 super_p
= build_pointer_type (xref_tag (RECORD_TYPE
,
1142 get_identifier (TAG_SUPER
)));
1145 /* id objc_msgSend (id, SEL, ...); */
1148 = build_function_type (id_type
,
1149 tree_cons (NULL_TREE
, id_type
,
1150 tree_cons (NULL_TREE
, selector_type
,
1153 if (! flag_next_runtime
)
1155 umsg_decl
= build_decl (FUNCTION_DECL
,
1156 get_identifier (TAG_MSGSEND
), temp_type
);
1157 DECL_EXTERNAL (umsg_decl
) = 1;
1158 TREE_PUBLIC (umsg_decl
) = 1;
1159 DECL_INLINE (umsg_decl
) = 1;
1160 DECL_ARTIFICIAL (umsg_decl
) = 1;
1162 if (flag_traditional
&& TAG_MSGSEND
[0] != '_')
1163 DECL_BUILT_IN_NONANSI (umsg_decl
) = 1;
1165 make_decl_rtl (umsg_decl
, NULL
);
1166 pushdecl (umsg_decl
);
1169 umsg_decl
= builtin_function (TAG_MSGSEND
, temp_type
, 0, NOT_BUILT_IN
, 0);
1171 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1174 = build_function_type (id_type
,
1175 tree_cons (NULL_TREE
, super_p
,
1176 tree_cons (NULL_TREE
, selector_type
,
1179 umsg_super_decl
= builtin_function (TAG_MSGSENDSUPER
,
1180 temp_type
, 0, NOT_BUILT_IN
, 0);
1182 /* id objc_getClass (const char *); */
1184 temp_type
= build_function_type (id_type
,
1185 tree_cons (NULL_TREE
,
1186 const_string_type_node
,
1187 tree_cons (NULL_TREE
, void_type_node
,
1191 = builtin_function (TAG_GETCLASS
, temp_type
, 0, NOT_BUILT_IN
, 0);
1193 /* id objc_getMetaClass (const char *); */
1195 objc_get_meta_class_decl
1196 = builtin_function (TAG_GETMETACLASS
, temp_type
, 0, NOT_BUILT_IN
, 0);
1198 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1200 if (! flag_next_runtime
)
1202 if (flag_typed_selectors
)
1204 /* Suppress outputting debug symbols, because
1205 dbxout_init hasn'r been called yet. */
1206 enum debug_info_type save_write_symbols
= write_symbols
;
1207 struct gcc_debug_hooks
*save_hooks
= debug_hooks
;
1208 write_symbols
= NO_DEBUG
;
1209 debug_hooks
= &do_nothing_debug_hooks
;
1211 build_selector_template ();
1212 temp_type
= build_array_type (objc_selector_template
, NULL_TREE
);
1214 write_symbols
= save_write_symbols
;
1215 debug_hooks
= save_hooks
;
1218 temp_type
= build_array_type (selector_type
, NULL_TREE
);
1220 layout_type (temp_type
);
1221 UOBJC_SELECTOR_TABLE_decl
1222 = create_builtin_decl (VAR_DECL
, temp_type
,
1223 "_OBJC_SELECTOR_TABLE");
1225 /* Avoid warning when not sending messages. */
1226 TREE_USED (UOBJC_SELECTOR_TABLE_decl
) = 1;
1229 generate_forward_declaration_to_string_table ();
1231 /* Forward declare constant_string_id and constant_string_type. */
1232 if (!constant_string_class_name
)
1233 constant_string_class_name
= STRING_OBJECT_CLASS_NAME
;
1235 constant_string_id
= get_identifier (constant_string_class_name
);
1236 constant_string_type
= xref_tag (RECORD_TYPE
, constant_string_id
);
1239 /* Custom build_string which sets TREE_TYPE! */
1242 my_build_string (len
, str
)
1247 tree a_string
= build_string (len
, str
);
1249 /* Some code from combine_strings, which is local to c-parse.y. */
1250 if (TREE_TYPE (a_string
) == int_array_type_node
)
1253 TREE_TYPE (a_string
)
1254 = build_array_type (wide_flag
? integer_type_node
: char_type_node
,
1255 build_index_type (build_int_2 (len
- 1, 0)));
1257 TREE_CONSTANT (a_string
) = 1; /* Puts string in the readonly segment */
1258 TREE_STATIC (a_string
) = 1;
1263 /* Given a chain of STRING_CST's, build a static instance of
1264 NXConstantString which points at the concatenation of those strings.
1265 We place the string object in the __string_objects section of the
1266 __OBJC segment. The Objective-C runtime will initialize the isa
1267 pointers of the string objects to point at the NXConstantString
1271 build_objc_string_object (strings
)
1274 tree string
, initlist
, constructor
;
1277 if (lookup_interface (constant_string_id
) == NULL_TREE
)
1279 error ("cannot find interface declaration for `%s'",
1280 IDENTIFIER_POINTER (constant_string_id
));
1281 return error_mark_node
;
1284 add_class_reference (constant_string_id
);
1286 string
= combine_strings (strings
);
1287 TREE_SET_CODE (string
, STRING_CST
);
1288 length
= TREE_STRING_LENGTH (string
) - 1;
1290 /* & ((NXConstantString) {0, string, length}) */
1292 if (flag_next_runtime
)
1294 /* For the NeXT runtime, we can generate a literal reference
1295 to the string class, don't need to run a constructor. */
1296 setup_string_decl ();
1297 if (string_class_decl
== NULL_TREE
)
1299 error ("cannot find reference tag for class `%s'",
1300 IDENTIFIER_POINTER (constant_string_id
));
1301 return error_mark_node
;
1303 initlist
= build_tree_list
1305 copy_node (build_unary_op (ADDR_EXPR
, string_class_decl
, 0)));
1309 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1313 = tree_cons (NULL_TREE
, copy_node (build_unary_op (ADDR_EXPR
, string
, 1)),
1315 initlist
= tree_cons (NULL_TREE
, build_int_2 (length
, 0), initlist
);
1316 constructor
= build_constructor (constant_string_type
, nreverse (initlist
));
1318 if (!flag_next_runtime
)
1321 = objc_add_static_instance (constructor
, constant_string_type
);
1324 return (build_unary_op (ADDR_EXPR
, constructor
, 1));
1327 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1330 objc_add_static_instance (constructor
, class_decl
)
1331 tree constructor
, class_decl
;
1333 static int num_static_inst
;
1337 /* Find the list of static instances for the CLASS_DECL. Create one if
1339 for (chain
= &objc_static_instances
;
1340 *chain
&& TREE_VALUE (*chain
) != class_decl
;
1341 chain
= &TREE_CHAIN (*chain
));
1344 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
1345 add_objc_string (TYPE_NAME (class_decl
), class_names
);
1348 sprintf (buf
, "_OBJC_INSTANCE_%d", num_static_inst
++);
1349 decl
= build_decl (VAR_DECL
, get_identifier (buf
), class_decl
);
1350 DECL_COMMON (decl
) = 1;
1351 TREE_STATIC (decl
) = 1;
1352 DECL_ARTIFICIAL (decl
) = 1;
1353 DECL_INITIAL (decl
) = constructor
;
1355 /* We may be writing something else just now.
1356 Postpone till end of input. */
1357 DECL_DEFER_OUTPUT (decl
) = 1;
1358 pushdecl_top_level (decl
);
1359 rest_of_decl_compilation (decl
, 0, 1, 0);
1361 /* Add the DECL to the head of this CLASS' list. */
1362 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
1367 /* Build a static constant CONSTRUCTOR
1368 with type TYPE and elements ELTS. */
1371 build_constructor (type
, elts
)
1374 tree constructor
, f
, e
;
1376 /* ??? Most of the places that we build constructors, we don't fill in
1377 the type of integers properly. Convert them all en masse. */
1378 if (TREE_CODE (type
) == ARRAY_TYPE
)
1380 f
= TREE_TYPE (type
);
1381 if (TREE_CODE (f
) == POINTER_TYPE
|| TREE_CODE (f
) == INTEGER_TYPE
)
1382 for (e
= elts
; e
; e
= TREE_CHAIN (e
))
1383 TREE_VALUE (e
) = convert (f
, TREE_VALUE (e
));
1387 f
= TYPE_FIELDS (type
);
1388 for (e
= elts
; e
; e
= TREE_CHAIN (e
), f
= TREE_CHAIN (f
))
1389 if (TREE_CODE (TREE_TYPE (f
)) == POINTER_TYPE
1390 || TREE_CODE (TREE_TYPE (f
)) == INTEGER_TYPE
)
1391 TREE_VALUE (e
) = convert (TREE_TYPE (f
), TREE_VALUE (e
));
1394 constructor
= build (CONSTRUCTOR
, type
, NULL_TREE
, elts
);
1395 TREE_CONSTANT (constructor
) = 1;
1396 TREE_STATIC (constructor
) = 1;
1397 TREE_READONLY (constructor
) = 1;
1402 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1404 /* Predefine the following data type:
1412 void *defs[cls_def_cnt + cat_def_cnt];
1416 build_objc_symtab_template ()
1418 tree field_decl
, field_decl_chain
, index
;
1420 objc_symtab_template
1421 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SYMTAB
));
1423 /* long sel_ref_cnt; */
1425 field_decl
= create_builtin_decl (FIELD_DECL
,
1426 long_integer_type_node
,
1428 field_decl_chain
= field_decl
;
1432 field_decl
= create_builtin_decl (FIELD_DECL
,
1433 build_pointer_type (selector_type
),
1435 chainon (field_decl_chain
, field_decl
);
1437 /* short cls_def_cnt; */
1439 field_decl
= create_builtin_decl (FIELD_DECL
,
1440 short_integer_type_node
,
1442 chainon (field_decl_chain
, field_decl
);
1444 /* short cat_def_cnt; */
1446 field_decl
= create_builtin_decl (FIELD_DECL
,
1447 short_integer_type_node
,
1449 chainon (field_decl_chain
, field_decl
);
1451 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1453 if (!flag_next_runtime
)
1454 index
= build_index_type (build_int_2 (imp_count
+ cat_count
, 0));
1456 index
= build_index_type (build_int_2 (imp_count
+ cat_count
- 1,
1457 imp_count
== 0 && cat_count
== 0
1459 field_decl
= create_builtin_decl (FIELD_DECL
,
1460 build_array_type (ptr_type_node
, index
),
1462 chainon (field_decl_chain
, field_decl
);
1464 finish_struct (objc_symtab_template
, field_decl_chain
, NULL_TREE
);
1467 /* Create the initial value for the `defs' field of _objc_symtab.
1468 This is a CONSTRUCTOR. */
1471 init_def_list (type
)
1474 tree expr
, initlist
= NULL_TREE
;
1475 struct imp_entry
*impent
;
1478 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1480 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
1482 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1483 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1488 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1490 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1492 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1493 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1497 if (!flag_next_runtime
)
1499 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1502 if (static_instances_decl
)
1503 expr
= build_unary_op (ADDR_EXPR
, static_instances_decl
, 0);
1505 expr
= build_int_2 (0, 0);
1507 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1510 return build_constructor (type
, nreverse (initlist
));
1513 /* Construct the initial value for all of _objc_symtab. */
1516 init_objc_symtab (type
)
1521 /* sel_ref_cnt = { ..., 5, ... } */
1523 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1525 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1527 if (flag_next_runtime
|| ! sel_ref_chain
)
1528 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1530 initlist
= tree_cons (NULL_TREE
,
1531 build_unary_op (ADDR_EXPR
,
1532 UOBJC_SELECTOR_TABLE_decl
, 1),
1535 /* cls_def_cnt = { ..., 5, ... } */
1537 initlist
= tree_cons (NULL_TREE
, build_int_2 (imp_count
, 0), initlist
);
1539 /* cat_def_cnt = { ..., 5, ... } */
1541 initlist
= tree_cons (NULL_TREE
, build_int_2 (cat_count
, 0), initlist
);
1543 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1545 if (imp_count
|| cat_count
|| static_instances_decl
)
1548 tree field
= TYPE_FIELDS (type
);
1549 field
= TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field
))));
1551 initlist
= tree_cons (NULL_TREE
, init_def_list (TREE_TYPE (field
)),
1555 return build_constructor (type
, nreverse (initlist
));
1558 /* Push forward-declarations of all the categories
1559 so that init_def_list can use them in a CONSTRUCTOR. */
1562 forward_declare_categories ()
1564 struct imp_entry
*impent
;
1565 tree sav
= objc_implementation_context
;
1567 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1569 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1571 /* Set an invisible arg to synth_id_with_class_suffix. */
1572 objc_implementation_context
= impent
->imp_context
;
1574 = create_builtin_decl (VAR_DECL
, objc_category_template
,
1575 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", objc_implementation_context
)));
1578 objc_implementation_context
= sav
;
1581 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1582 and initialized appropriately. */
1585 generate_objc_symtab_decl ()
1589 if (!objc_category_template
)
1590 build_category_template ();
1592 /* forward declare categories */
1594 forward_declare_categories ();
1596 if (!objc_symtab_template
)
1597 build_objc_symtab_template ();
1599 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
1601 UOBJC_SYMBOLS_decl
= start_decl (get_identifier ("_OBJC_SYMBOLS"),
1602 tree_cons (NULL_TREE
,
1603 objc_symtab_template
, sc_spec
),
1607 TREE_USED (UOBJC_SYMBOLS_decl
) = 1;
1608 DECL_IGNORED_P (UOBJC_SYMBOLS_decl
) = 1;
1609 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl
) = 1;
1610 finish_decl (UOBJC_SYMBOLS_decl
,
1611 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)),
1616 init_module_descriptor (type
)
1619 tree initlist
, expr
;
1621 /* version = { 1, ... } */
1623 expr
= build_int_2 (OBJC_VERSION
, 0);
1624 initlist
= build_tree_list (NULL_TREE
, expr
);
1626 /* size = { ..., sizeof (struct objc_module), ... } */
1628 expr
= size_in_bytes (objc_module_template
);
1629 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1631 /* name = { ..., "foo.m", ... } */
1633 expr
= add_objc_string (get_identifier (input_filename
), class_names
);
1634 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1636 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1638 if (UOBJC_SYMBOLS_decl
)
1639 expr
= build_unary_op (ADDR_EXPR
, UOBJC_SYMBOLS_decl
, 0);
1641 expr
= build_int_2 (0, 0);
1642 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1644 return build_constructor (type
, nreverse (initlist
));
1647 /* Write out the data structures to describe Objective C classes defined.
1648 If appropriate, compile and output a setup function to initialize them.
1649 Return a symbol_ref to the function to call to initialize the Objective C
1650 data structures for this file (and perhaps for other files also).
1652 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1655 build_module_descriptor ()
1657 tree decl_specs
, field_decl
, field_decl_chain
;
1659 objc_module_template
1660 = start_struct (RECORD_TYPE
, get_identifier (UTAG_MODULE
));
1664 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1665 field_decl
= get_identifier ("version");
1667 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1668 field_decl_chain
= field_decl
;
1672 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1673 field_decl
= get_identifier ("size");
1675 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1676 chainon (field_decl_chain
, field_decl
);
1680 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
1681 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
1683 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1684 chainon (field_decl_chain
, field_decl
);
1686 /* struct objc_symtab *symtab; */
1688 decl_specs
= get_identifier (UTAG_SYMTAB
);
1689 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
1690 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("symtab"));
1692 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1693 chainon (field_decl_chain
, field_decl
);
1695 finish_struct (objc_module_template
, field_decl_chain
, NULL_TREE
);
1697 /* Create an instance of "objc_module". */
1699 decl_specs
= tree_cons (NULL_TREE
, objc_module_template
,
1700 build_tree_list (NULL_TREE
,
1701 ridpointers
[(int) RID_STATIC
]));
1703 UOBJC_MODULES_decl
= start_decl (get_identifier ("_OBJC_MODULES"),
1704 decl_specs
, 1, NULL_TREE
);
1706 DECL_ARTIFICIAL (UOBJC_MODULES_decl
) = 1;
1707 DECL_IGNORED_P (UOBJC_MODULES_decl
) = 1;
1708 DECL_CONTEXT (UOBJC_MODULES_decl
) = NULL_TREE
;
1710 finish_decl (UOBJC_MODULES_decl
,
1711 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl
)),
1714 /* Mark the decl to avoid "defined but not used" warning. */
1715 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl
) = 1;
1717 /* Generate a constructor call for the module descriptor.
1718 This code was generated by reading the grammar rules
1719 of c-parse.in; Therefore, it may not be the most efficient
1720 way of generating the requisite code. */
1722 if (flag_next_runtime
)
1726 tree parms
, execclass_decl
, decelerator
, void_list_node_1
;
1727 tree init_function_name
, init_function_decl
;
1729 /* Declare void __objc_execClass (void *); */
1731 void_list_node_1
= build_tree_list (NULL_TREE
, void_type_node
);
1732 execclass_decl
= build_decl (FUNCTION_DECL
,
1733 get_identifier (TAG_EXECCLASS
),
1734 build_function_type (void_type_node
,
1735 tree_cons (NULL_TREE
, ptr_type_node
,
1736 void_list_node_1
)));
1737 DECL_EXTERNAL (execclass_decl
) = 1;
1738 DECL_ARTIFICIAL (execclass_decl
) = 1;
1739 TREE_PUBLIC (execclass_decl
) = 1;
1740 pushdecl (execclass_decl
);
1741 rest_of_decl_compilation (execclass_decl
, 0, 0, 0);
1742 assemble_external (execclass_decl
);
1744 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1746 init_function_name
= get_file_function_name ('I');
1747 start_function (void_list_node_1
,
1748 build_nt (CALL_EXPR
, init_function_name
,
1749 tree_cons (NULL_TREE
, NULL_TREE
,
1753 store_parm_decls ();
1755 init_function_decl
= current_function_decl
;
1756 TREE_PUBLIC (init_function_decl
) = ! targetm
.have_ctors_dtors
;
1757 TREE_USED (init_function_decl
) = 1;
1758 current_function_cannot_inline
1759 = "static constructors and destructors cannot be inlined";
1762 = build_tree_list (NULL_TREE
,
1763 build_unary_op (ADDR_EXPR
, UOBJC_MODULES_decl
, 0));
1764 decelerator
= build_function_call (execclass_decl
, parms
);
1766 c_expand_expr_stmt (decelerator
);
1768 finish_function (0);
1770 return XEXP (DECL_RTL (init_function_decl
), 0);
1774 /* extern const char _OBJC_STRINGS[]; */
1777 generate_forward_declaration_to_string_table ()
1779 tree sc_spec
, decl_specs
, expr_decl
;
1781 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_EXTERN
], NULL_TREE
);
1782 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1785 = build_nt (ARRAY_REF
, get_identifier ("_OBJC_STRINGS"), NULL_TREE
);
1787 UOBJC_STRINGS_decl
= define_decl (expr_decl
, decl_specs
);
1790 /* Return the DECL of the string IDENT in the SECTION. */
1793 get_objc_string_decl (ident
, section
)
1795 enum string_section section
;
1799 if (section
== class_names
)
1800 chain
= class_names_chain
;
1801 else if (section
== meth_var_names
)
1802 chain
= meth_var_names_chain
;
1803 else if (section
== meth_var_types
)
1804 chain
= meth_var_types_chain
;
1808 for (; chain
!= 0; chain
= TREE_VALUE (chain
))
1809 if (TREE_VALUE (chain
) == ident
)
1810 return (TREE_PURPOSE (chain
));
1816 /* Output references to all statically allocated objects. Return the DECL
1817 for the array built. */
1820 generate_static_references ()
1822 tree decls
= NULL_TREE
, ident
, decl_spec
, expr_decl
, expr
= NULL_TREE
;
1823 tree class_name
, class, decl
, initlist
;
1824 tree cl_chain
, in_chain
, type
;
1825 int num_inst
, num_class
;
1828 if (flag_next_runtime
)
1831 for (cl_chain
= objc_static_instances
, num_class
= 0;
1832 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
1834 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
1835 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
1837 sprintf (buf
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
1838 ident
= get_identifier (buf
);
1840 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1841 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1842 build_tree_list (NULL_TREE
,
1843 ridpointers
[(int) RID_STATIC
]));
1844 decl
= start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
);
1845 DECL_CONTEXT (decl
) = 0;
1846 DECL_ARTIFICIAL (decl
) = 1;
1848 /* Output {class_name, ...}. */
1849 class = TREE_VALUE (cl_chain
);
1850 class_name
= get_objc_string_decl (TYPE_NAME (class), class_names
);
1851 initlist
= build_tree_list (NULL_TREE
,
1852 build_unary_op (ADDR_EXPR
, class_name
, 1));
1854 /* Output {..., instance, ...}. */
1855 for (in_chain
= TREE_PURPOSE (cl_chain
);
1856 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
1858 expr
= build_unary_op (ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
1859 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1862 /* Output {..., NULL}. */
1863 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1865 expr
= build_constructor (TREE_TYPE (decl
), nreverse (initlist
));
1866 finish_decl (decl
, expr
, NULL_TREE
);
1867 TREE_USED (decl
) = 1;
1869 type
= build_array_type (build_pointer_type (void_type_node
), 0);
1870 decl
= build_decl (VAR_DECL
, ident
, type
);
1871 TREE_USED (decl
) = 1;
1872 TREE_STATIC (decl
) = 1;
1874 = tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, decl
, 1), decls
);
1877 decls
= tree_cons (NULL_TREE
, build_int_2 (0, 0), decls
);
1878 ident
= get_identifier ("_OBJC_STATIC_INSTANCES");
1879 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1880 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1881 build_tree_list (NULL_TREE
,
1882 ridpointers
[(int) RID_STATIC
]));
1883 static_instances_decl
1884 = start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
);
1885 TREE_USED (static_instances_decl
) = 1;
1886 DECL_CONTEXT (static_instances_decl
) = 0;
1887 DECL_ARTIFICIAL (static_instances_decl
) = 1;
1888 expr
= build_constructor (TREE_TYPE (static_instances_decl
),
1890 finish_decl (static_instances_decl
, expr
, NULL_TREE
);
1893 /* Output all strings. */
1898 tree sc_spec
, decl_specs
, expr_decl
;
1899 tree chain
, string_expr
;
1902 for (chain
= class_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1904 string
= TREE_VALUE (chain
);
1905 decl
= TREE_PURPOSE (chain
);
1907 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1908 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1909 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1910 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1911 DECL_CONTEXT (decl
) = NULL_TREE
;
1912 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1913 IDENTIFIER_POINTER (string
));
1914 finish_decl (decl
, string_expr
, NULL_TREE
);
1917 for (chain
= meth_var_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1919 string
= TREE_VALUE (chain
);
1920 decl
= TREE_PURPOSE (chain
);
1922 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1923 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1924 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1925 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1926 DECL_CONTEXT (decl
) = NULL_TREE
;
1927 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1928 IDENTIFIER_POINTER (string
));
1929 finish_decl (decl
, string_expr
, NULL_TREE
);
1932 for (chain
= meth_var_types_chain
; chain
; chain
= TREE_CHAIN (chain
))
1934 string
= TREE_VALUE (chain
);
1935 decl
= TREE_PURPOSE (chain
);
1937 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1938 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1939 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1940 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1941 DECL_CONTEXT (decl
) = NULL_TREE
;
1942 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1943 IDENTIFIER_POINTER (string
));
1944 finish_decl (decl
, string_expr
, NULL_TREE
);
1949 build_selector_reference_decl ()
1955 sprintf (buf
, "_OBJC_SELECTOR_REFERENCES_%d", idx
++);
1957 ident
= get_identifier (buf
);
1959 decl
= build_decl (VAR_DECL
, ident
, selector_type
);
1960 DECL_EXTERNAL (decl
) = 1;
1961 TREE_PUBLIC (decl
) = 1;
1962 TREE_USED (decl
) = 1;
1963 TREE_READONLY (decl
) = 1;
1964 DECL_ARTIFICIAL (decl
) = 1;
1965 DECL_CONTEXT (decl
) = 0;
1967 make_decl_rtl (decl
, 0);
1968 pushdecl_top_level (decl
);
1973 /* Just a handy wrapper for add_objc_string. */
1976 build_selector (ident
)
1979 tree expr
= add_objc_string (ident
, meth_var_names
);
1980 if (flag_typed_selectors
)
1983 return build_c_cast (selector_type
, expr
); /* cast! */
1987 build_selector_translation_table ()
1989 tree sc_spec
, decl_specs
;
1990 tree chain
, initlist
= NULL_TREE
;
1992 tree decl
= NULL_TREE
, var_decl
, name
;
1994 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
1998 expr
= build_selector (TREE_VALUE (chain
));
2000 if (flag_next_runtime
)
2002 name
= DECL_NAME (TREE_PURPOSE (chain
));
2004 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
2006 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2007 decl_specs
= tree_cons (NULL_TREE
, selector_type
, sc_spec
);
2011 /* The `decl' that is returned from start_decl is the one that we
2012 forward declared in `build_selector_reference' */
2013 decl
= start_decl (var_decl
, decl_specs
, 1, NULL_TREE
);
2016 /* add one for the '\0' character */
2017 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (chain
)) + 1;
2019 if (flag_next_runtime
)
2020 finish_decl (decl
, expr
, NULL_TREE
);
2023 if (flag_typed_selectors
)
2025 tree eltlist
= NULL_TREE
;
2026 tree encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
2027 eltlist
= tree_cons (NULL_TREE
, expr
, NULL_TREE
);
2028 eltlist
= tree_cons (NULL_TREE
, encoding
, eltlist
);
2029 expr
= build_constructor (objc_selector_template
,
2030 nreverse (eltlist
));
2032 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2037 if (! flag_next_runtime
)
2039 /* Cause the variable and its initial value to be actually output. */
2040 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl
) = 0;
2041 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl
) = 1;
2042 /* NULL terminate the list and fix the decl for output. */
2043 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
2044 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl
) = objc_ellipsis_node
;
2045 initlist
= build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
2046 nreverse (initlist
));
2047 finish_decl (UOBJC_SELECTOR_TABLE_decl
, initlist
, NULL_TREE
);
2048 current_function_decl
= NULL_TREE
;
2053 get_proto_encoding (proto
)
2061 if (! METHOD_ENCODING (proto
))
2063 tmp_decl
= build_tmp_function_decl ();
2064 hack_method_prototype (proto
, tmp_decl
);
2065 encoding
= encode_method_prototype (proto
, tmp_decl
);
2066 METHOD_ENCODING (proto
) = encoding
;
2069 encoding
= METHOD_ENCODING (proto
);
2071 return add_objc_string (encoding
, meth_var_types
);
2074 return build_int_2 (0, 0);
2077 /* sel_ref_chain is a list whose "value" fields will be instances of
2078 identifier_node that represent the selector. */
2081 build_typed_selector_reference (ident
, proto
)
2084 tree
*chain
= &sel_ref_chain
;
2090 if (TREE_PURPOSE (*chain
) == ident
&& TREE_VALUE (*chain
) == proto
)
2091 goto return_at_index
;
2094 chain
= &TREE_CHAIN (*chain
);
2097 *chain
= tree_cons (proto
, ident
, NULL_TREE
);
2100 expr
= build_unary_op (ADDR_EXPR
,
2101 build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2102 build_int_2 (index
, 0)),
2104 return build_c_cast (selector_type
, expr
);
2108 build_selector_reference (ident
)
2111 tree
*chain
= &sel_ref_chain
;
2117 if (TREE_VALUE (*chain
) == ident
)
2118 return (flag_next_runtime
2119 ? TREE_PURPOSE (*chain
)
2120 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2121 build_int_2 (index
, 0)));
2124 chain
= &TREE_CHAIN (*chain
);
2127 expr
= build_selector_reference_decl ();
2129 *chain
= tree_cons (expr
, ident
, NULL_TREE
);
2131 return (flag_next_runtime
2133 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2134 build_int_2 (index
, 0)));
2138 build_class_reference_decl ()
2144 sprintf (buf
, "_OBJC_CLASS_REFERENCES_%d", idx
++);
2146 ident
= get_identifier (buf
);
2148 decl
= build_decl (VAR_DECL
, ident
, objc_class_type
);
2149 DECL_EXTERNAL (decl
) = 1;
2150 TREE_PUBLIC (decl
) = 1;
2151 TREE_USED (decl
) = 1;
2152 TREE_READONLY (decl
) = 1;
2153 DECL_CONTEXT (decl
) = 0;
2154 DECL_ARTIFICIAL (decl
) = 1;
2156 make_decl_rtl (decl
, 0);
2157 pushdecl_top_level (decl
);
2162 /* Create a class reference, but don't create a variable to reference
2166 add_class_reference (ident
)
2171 if ((chain
= cls_ref_chain
))
2176 if (ident
== TREE_VALUE (chain
))
2180 chain
= TREE_CHAIN (chain
);
2184 /* Append to the end of the list */
2185 TREE_CHAIN (tail
) = tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2188 cls_ref_chain
= tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2191 /* Get a class reference, creating it if necessary. Also create the
2192 reference variable. */
2195 get_class_reference (ident
)
2198 if (flag_next_runtime
)
2203 for (chain
= &cls_ref_chain
; *chain
; chain
= &TREE_CHAIN (*chain
))
2204 if (TREE_VALUE (*chain
) == ident
)
2206 if (! TREE_PURPOSE (*chain
))
2207 TREE_PURPOSE (*chain
) = build_class_reference_decl ();
2209 return TREE_PURPOSE (*chain
);
2212 decl
= build_class_reference_decl ();
2213 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2220 add_class_reference (ident
);
2222 params
= build_tree_list (NULL_TREE
,
2223 my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
2224 IDENTIFIER_POINTER (ident
)));
2226 assemble_external (objc_get_class_decl
);
2227 return build_function_call (objc_get_class_decl
, params
);
2231 /* For each string section we have a chain which maps identifier nodes
2232 to decls for the strings. */
2235 add_objc_string (ident
, section
)
2237 enum string_section section
;
2241 if (section
== class_names
)
2242 chain
= &class_names_chain
;
2243 else if (section
== meth_var_names
)
2244 chain
= &meth_var_names_chain
;
2245 else if (section
== meth_var_types
)
2246 chain
= &meth_var_types_chain
;
2252 if (TREE_VALUE (*chain
) == ident
)
2253 return build_unary_op (ADDR_EXPR
, TREE_PURPOSE (*chain
), 1);
2255 chain
= &TREE_CHAIN (*chain
);
2258 decl
= build_objc_string_decl (section
);
2260 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2262 return build_unary_op (ADDR_EXPR
, decl
, 1);
2266 build_objc_string_decl (section
)
2267 enum string_section section
;
2271 static int class_names_idx
= 0;
2272 static int meth_var_names_idx
= 0;
2273 static int meth_var_types_idx
= 0;
2275 if (section
== class_names
)
2276 sprintf (buf
, "_OBJC_CLASS_NAME_%d", class_names_idx
++);
2277 else if (section
== meth_var_names
)
2278 sprintf (buf
, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx
++);
2279 else if (section
== meth_var_types
)
2280 sprintf (buf
, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx
++);
2282 ident
= get_identifier (buf
);
2284 decl
= build_decl (VAR_DECL
, ident
, build_array_type (char_type_node
, 0));
2285 DECL_EXTERNAL (decl
) = 1;
2286 TREE_PUBLIC (decl
) = 1;
2287 TREE_USED (decl
) = 1;
2288 TREE_READONLY (decl
) = 1;
2289 TREE_CONSTANT (decl
) = 1;
2290 DECL_CONTEXT (decl
) = 0;
2291 DECL_ARTIFICIAL (decl
) = 1;
2293 make_decl_rtl (decl
, 0);
2294 pushdecl_top_level (decl
);
2301 objc_declare_alias (alias_ident
, class_ident
)
2305 if (is_class_name (class_ident
) != class_ident
)
2306 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident
));
2307 else if (is_class_name (alias_ident
))
2308 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident
));
2310 alias_chain
= tree_cons (class_ident
, alias_ident
, alias_chain
);
2314 objc_declare_class (ident_list
)
2319 for (list
= ident_list
; list
; list
= TREE_CHAIN (list
))
2321 tree ident
= TREE_VALUE (list
);
2324 if ((decl
= lookup_name (ident
)))
2326 error ("`%s' redeclared as different kind of symbol",
2327 IDENTIFIER_POINTER (ident
));
2328 error_with_decl (decl
, "previous declaration of `%s'");
2331 if (! is_class_name (ident
))
2333 tree record
= xref_tag (RECORD_TYPE
, ident
);
2334 TREE_STATIC_TEMPLATE (record
) = 1;
2335 class_chain
= tree_cons (NULL_TREE
, ident
, class_chain
);
2341 is_class_name (ident
)
2346 if (lookup_interface (ident
))
2349 for (chain
= class_chain
; chain
; chain
= TREE_CHAIN (chain
))
2351 if (ident
== TREE_VALUE (chain
))
2355 for (chain
= alias_chain
; chain
; chain
= TREE_CHAIN (chain
))
2357 if (ident
== TREE_VALUE (chain
))
2358 return TREE_PURPOSE (chain
);
2365 lookup_interface (ident
)
2370 for (chain
= interface_chain
; chain
; chain
= TREE_CHAIN (chain
))
2372 if (ident
== CLASS_NAME (chain
))
2379 objc_copy_list (list
, head
)
2383 tree newlist
= NULL_TREE
, tail
= NULL_TREE
;
2387 tail
= copy_node (list
);
2389 /* The following statement fixes a bug when inheriting instance
2390 variables that are declared to be bitfields. finish_struct
2391 expects to find the width of the bitfield in DECL_INITIAL. */
2392 if (DECL_BIT_FIELD (tail
) && DECL_INITIAL (tail
) == 0)
2393 DECL_INITIAL (tail
) = DECL_SIZE (tail
);
2395 newlist
= chainon (newlist
, tail
);
2396 list
= TREE_CHAIN (list
);
2403 /* Used by: build_private_template, get_class_ivars, and
2404 continue_class. COPY is 1 when called from @defs. In this case
2405 copy all fields. Otherwise don't copy leaf ivars since we rely on
2406 them being side-effected exactly once by finish_struct. */
2409 build_ivar_chain (interface
, copy
)
2413 tree my_name
, super_name
, ivar_chain
;
2415 my_name
= CLASS_NAME (interface
);
2416 super_name
= CLASS_SUPER_NAME (interface
);
2418 /* Possibly copy leaf ivars. */
2420 objc_copy_list (CLASS_IVARS (interface
), &ivar_chain
);
2422 ivar_chain
= CLASS_IVARS (interface
);
2427 tree super_interface
= lookup_interface (super_name
);
2429 if (!super_interface
)
2431 /* fatal did not work with 2 args...should fix */
2432 error ("cannot find interface declaration for `%s', superclass of `%s'",
2433 IDENTIFIER_POINTER (super_name
),
2434 IDENTIFIER_POINTER (my_name
));
2435 exit (FATAL_EXIT_CODE
);
2438 if (super_interface
== interface
)
2439 fatal_error ("circular inheritance in interface declaration for `%s'",
2440 IDENTIFIER_POINTER (super_name
));
2442 interface
= super_interface
;
2443 my_name
= CLASS_NAME (interface
);
2444 super_name
= CLASS_SUPER_NAME (interface
);
2446 op1
= CLASS_IVARS (interface
);
2449 tree head
, tail
= objc_copy_list (op1
, &head
);
2451 /* Prepend super class ivars...make a copy of the list, we
2452 do not want to alter the original. */
2453 TREE_CHAIN (tail
) = ivar_chain
;
2460 /* struct <classname> {
2461 struct objc_class *isa;
2466 build_private_template (class)
2471 if (CLASS_STATIC_TEMPLATE (class))
2473 uprivate_record
= CLASS_STATIC_TEMPLATE (class);
2474 ivar_context
= TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2478 uprivate_record
= start_struct (RECORD_TYPE
, CLASS_NAME (class));
2480 ivar_context
= build_ivar_chain (class, 0);
2482 finish_struct (uprivate_record
, ivar_context
, NULL_TREE
);
2484 CLASS_STATIC_TEMPLATE (class) = uprivate_record
;
2486 /* mark this record as class template - for class type checking */
2487 TREE_STATIC_TEMPLATE (uprivate_record
) = 1;
2491 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
2493 build1 (INDIRECT_REF
, NULL_TREE
,
2496 return ivar_context
;
2499 /* Begin code generation for protocols... */
2501 /* struct objc_protocol {
2502 char *protocol_name;
2503 struct objc_protocol **protocol_list;
2504 struct objc_method_desc *instance_methods;
2505 struct objc_method_desc *class_methods;
2509 build_protocol_template ()
2511 tree decl_specs
, field_decl
, field_decl_chain
;
2514 template = start_struct (RECORD_TYPE
, get_identifier (UTAG_PROTOCOL
));
2516 /* struct objc_class *isa; */
2518 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2519 get_identifier (UTAG_CLASS
)));
2520 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
2522 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2523 field_decl_chain
= field_decl
;
2525 /* char *protocol_name; */
2527 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
2529 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_name"));
2531 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2532 chainon (field_decl_chain
, field_decl
);
2534 /* struct objc_protocol **protocol_list; */
2536 decl_specs
= build_tree_list (NULL_TREE
, template);
2538 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
2539 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
2541 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2542 chainon (field_decl_chain
, field_decl
);
2544 /* struct objc_method_list *instance_methods; */
2547 = build_tree_list (NULL_TREE
,
2548 xref_tag (RECORD_TYPE
,
2549 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2551 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
2553 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2554 chainon (field_decl_chain
, field_decl
);
2556 /* struct objc_method_list *class_methods; */
2559 = build_tree_list (NULL_TREE
,
2560 xref_tag (RECORD_TYPE
,
2561 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2563 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
2565 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2566 chainon (field_decl_chain
, field_decl
);
2568 return finish_struct (template, field_decl_chain
, NULL_TREE
);
2572 build_descriptor_table_initializer (type
, entries
)
2576 tree initlist
= NULL_TREE
;
2580 tree eltlist
= NULL_TREE
;
2583 = tree_cons (NULL_TREE
,
2584 build_selector (METHOD_SEL_NAME (entries
)), NULL_TREE
);
2586 = tree_cons (NULL_TREE
,
2587 add_objc_string (METHOD_ENCODING (entries
),
2592 = tree_cons (NULL_TREE
,
2593 build_constructor (type
, nreverse (eltlist
)), initlist
);
2595 entries
= TREE_CHAIN (entries
);
2599 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
2602 /* struct objc_method_prototype_list {
2604 struct objc_method_prototype {
2611 build_method_prototype_list_template (list_type
, size
)
2615 tree objc_ivar_list_record
;
2616 tree decl_specs
, field_decl
, field_decl_chain
;
2618 /* Generate an unnamed struct definition. */
2620 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
2622 /* int method_count; */
2624 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
2625 field_decl
= get_identifier ("method_count");
2628 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2629 field_decl_chain
= field_decl
;
2631 /* struct objc_method method_list[]; */
2633 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
2634 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
2635 build_int_2 (size
, 0));
2638 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2639 chainon (field_decl_chain
, field_decl
);
2641 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
2643 return objc_ivar_list_record
;
2647 build_method_prototype_template ()
2650 tree decl_specs
, field_decl
, field_decl_chain
;
2653 = start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD_PROTOTYPE
));
2655 /* struct objc_selector *_cmd; */
2656 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
2657 get_identifier (TAG_SELECTOR
)), NULL_TREE
);
2658 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
2661 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2662 field_decl_chain
= field_decl
;
2664 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
2666 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_types"));
2668 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2669 chainon (field_decl_chain
, field_decl
);
2671 finish_struct (proto_record
, field_decl_chain
, NULL_TREE
);
2673 return proto_record
;
2676 /* True if last call to forwarding_offset yielded a register offset. */
2677 static int offset_is_register
;
2680 forwarding_offset (parm
)
2683 int offset_in_bytes
;
2685 if (GET_CODE (DECL_INCOMING_RTL (parm
)) == MEM
)
2687 rtx addr
= XEXP (DECL_INCOMING_RTL (parm
), 0);
2689 /* ??? Here we assume that the parm address is indexed
2690 off the frame pointer or arg pointer.
2691 If that is not true, we produce meaningless results,
2692 but do not crash. */
2693 if (GET_CODE (addr
) == PLUS
2694 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
2695 offset_in_bytes
= INTVAL (XEXP (addr
, 1));
2697 offset_in_bytes
= 0;
2699 offset_in_bytes
+= OBJC_FORWARDING_STACK_OFFSET
;
2700 offset_is_register
= 0;
2702 else if (GET_CODE (DECL_INCOMING_RTL (parm
)) == REG
)
2704 int regno
= REGNO (DECL_INCOMING_RTL (parm
));
2705 offset_in_bytes
= apply_args_register_offset (regno
);
2706 offset_is_register
= 1;
2711 /* This is the case where the parm is passed as an int or double
2712 and it is converted to a char, short or float and stored back
2713 in the parmlist. In this case, describe the parm
2714 with the variable's declared type, and adjust the address
2715 if the least significant bytes (which we are using) are not
2717 if (BYTES_BIG_ENDIAN
&& TREE_TYPE (parm
) != DECL_ARG_TYPE (parm
))
2718 offset_in_bytes
+= (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm
)))
2719 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm
))));
2721 return offset_in_bytes
;
2725 encode_method_prototype (method_decl
, func_decl
)
2732 HOST_WIDE_INT max_parm_end
= 0;
2736 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2737 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl
)));
2740 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
2741 obstack_object_size (&util_obstack
),
2742 OBJC_ENCODE_INLINE_DEFS
);
2745 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
2746 parms
= TREE_CHAIN (parms
))
2748 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
2749 + int_size_in_bytes (TREE_TYPE (parms
)));
2751 if (!offset_is_register
&& max_parm_end
< parm_end
)
2752 max_parm_end
= parm_end
;
2755 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
2757 sprintf (buf
, "%d", stack_size
);
2758 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2760 user_args
= METHOD_SEL_ARGS (method_decl
);
2762 /* Argument types. */
2763 for (parms
= DECL_ARGUMENTS (func_decl
), i
= 0; parms
;
2764 parms
= TREE_CHAIN (parms
), i
++)
2766 /* Process argument qualifiers for user supplied arguments. */
2769 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args
)));
2770 user_args
= TREE_CHAIN (user_args
);
2774 encode_type (TREE_TYPE (parms
),
2775 obstack_object_size (&util_obstack
),
2776 OBJC_ENCODE_INLINE_DEFS
);
2778 /* Compute offset. */
2779 sprintf (buf
, "%d", forwarding_offset (parms
));
2781 /* Indicate register. */
2782 if (offset_is_register
)
2783 obstack_1grow (&util_obstack
, '+');
2785 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2788 obstack_1grow (&util_obstack
, '\0');
2789 result
= get_identifier (obstack_finish (&util_obstack
));
2790 obstack_free (&util_obstack
, util_firstobj
);
2795 generate_descriptor_table (type
, name
, size
, list
, proto
)
2802 tree sc_spec
, decl_specs
, decl
, initlist
;
2804 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2805 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
2807 decl
= start_decl (synth_id_with_class_suffix (name
, proto
),
2808 decl_specs
, 1, NULL_TREE
);
2809 DECL_CONTEXT (decl
) = NULL_TREE
;
2811 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
2812 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
2814 finish_decl (decl
, build_constructor (type
, nreverse (initlist
)),
2821 generate_method_descriptors (protocol
) /* generate_dispatch_tables */
2824 tree initlist
, chain
, method_list_template
;
2825 tree cast
, variable_length_type
;
2828 if (!objc_method_prototype_template
)
2830 objc_method_prototype_template
= build_method_prototype_template ();
2833 cast
= build_tree_list (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2834 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
))),
2836 variable_length_type
= groktypename (cast
);
2838 chain
= PROTOCOL_CLS_METHODS (protocol
);
2841 size
= list_length (chain
);
2843 method_list_template
2844 = build_method_prototype_list_template (objc_method_prototype_template
,
2848 = build_descriptor_table_initializer (objc_method_prototype_template
,
2851 UOBJC_CLASS_METHODS_decl
2852 = generate_descriptor_table (method_list_template
,
2853 "_OBJC_PROTOCOL_CLASS_METHODS",
2854 size
, initlist
, protocol
);
2855 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
2858 UOBJC_CLASS_METHODS_decl
= 0;
2860 chain
= PROTOCOL_NST_METHODS (protocol
);
2863 size
= list_length (chain
);
2865 method_list_template
2866 = build_method_prototype_list_template (objc_method_prototype_template
,
2869 = build_descriptor_table_initializer (objc_method_prototype_template
,
2872 UOBJC_INSTANCE_METHODS_decl
2873 = generate_descriptor_table (method_list_template
,
2874 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2875 size
, initlist
, protocol
);
2876 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
2879 UOBJC_INSTANCE_METHODS_decl
= 0;
2882 /* Generate a temporary FUNCTION_DECL node to be used in
2883 hack_method_prototype below. */
2886 build_tmp_function_decl ()
2888 tree decl_specs
, expr_decl
, parms
;
2892 /* struct objc_object *objc_xxx (id, SEL, ...); */
2894 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
2895 push_parm_decl (build_tree_list
2896 (build_tree_list (decl_specs
,
2897 build1 (INDIRECT_REF
, NULL_TREE
,
2901 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2902 get_identifier (TAG_SELECTOR
)));
2903 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
);
2905 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, expr_decl
),
2907 parms
= get_parm_info (0);
2910 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
2911 sprintf (buffer
, "__objc_tmp_%x", xxx
++);
2912 expr_decl
= build_nt (CALL_EXPR
, get_identifier (buffer
), parms
, NULL_TREE
);
2913 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
2915 return define_decl (expr_decl
, decl_specs
);
2918 /* Generate the prototypes for protocol methods. This is used to
2919 generate method encodings for these.
2921 NST_METHODS is the method to generate a _DECL node for TMP_DECL is
2922 a decl node to be used. This is also where the return value is
2926 hack_method_prototype (nst_methods
, tmp_decl
)
2933 /* Hack to avoid problem with static typing of self arg. */
2934 TREE_SET_CODE (nst_methods
, CLASS_METHOD_DECL
);
2935 start_method_def (nst_methods
);
2936 TREE_SET_CODE (nst_methods
, INSTANCE_METHOD_DECL
);
2938 if (METHOD_ADD_ARGS (nst_methods
) == objc_ellipsis_node
)
2939 parms
= get_parm_info (0); /* we have a `, ...' */
2941 parms
= get_parm_info (1); /* place a `void_at_end' */
2943 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2945 /* Usually called from store_parm_decls -> init_function_start. */
2947 DECL_ARGUMENTS (tmp_decl
) = TREE_PURPOSE (parms
);
2948 current_function_decl
= tmp_decl
;
2951 /* Code taken from start_function. */
2952 tree restype
= TREE_TYPE (TREE_TYPE (tmp_decl
));
2953 /* Promote the value to int before returning it. */
2954 if (TREE_CODE (restype
) == INTEGER_TYPE
2955 && TYPE_PRECISION (restype
) < TYPE_PRECISION (integer_type_node
))
2956 restype
= integer_type_node
;
2957 DECL_RESULT (tmp_decl
) = build_decl (RESULT_DECL
, 0, restype
);
2960 for (parm
= DECL_ARGUMENTS (tmp_decl
); parm
; parm
= TREE_CHAIN (parm
))
2961 DECL_CONTEXT (parm
) = tmp_decl
;
2963 init_function_start (tmp_decl
, "objc-act", 0);
2965 /* Typically called from expand_function_start for function definitions. */
2966 assign_parms (tmp_decl
);
2968 /* install return type */
2969 TREE_TYPE (TREE_TYPE (tmp_decl
)) = groktypename (TREE_TYPE (nst_methods
));
2974 generate_protocol_references (plist
)
2979 /* Forward declare protocols referenced. */
2980 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
2982 tree proto
= TREE_VALUE (lproto
);
2984 if (TREE_CODE (proto
) == PROTOCOL_INTERFACE_TYPE
2985 && PROTOCOL_NAME (proto
))
2987 if (! PROTOCOL_FORWARD_DECL (proto
))
2988 build_protocol_reference (proto
);
2990 if (PROTOCOL_LIST (proto
))
2991 generate_protocol_references (PROTOCOL_LIST (proto
));
2997 generate_protocols ()
2999 tree p
, tmp_decl
, encoding
;
3000 tree sc_spec
, decl_specs
, decl
;
3001 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
3004 tmp_decl
= build_tmp_function_decl ();
3006 if (! objc_protocol_template
)
3007 objc_protocol_template
= build_protocol_template ();
3009 /* If a protocol was directly referenced, pull in indirect references. */
3010 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3011 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
3012 generate_protocol_references (PROTOCOL_LIST (p
));
3014 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3016 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
3017 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
3019 /* If protocol wasn't referenced, don't generate any code. */
3020 if (! PROTOCOL_FORWARD_DECL (p
))
3023 /* Make sure we link in the Protocol class. */
3024 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
3028 if (! METHOD_ENCODING (nst_methods
))
3030 hack_method_prototype (nst_methods
, tmp_decl
);
3031 encoding
= encode_method_prototype (nst_methods
, tmp_decl
);
3032 METHOD_ENCODING (nst_methods
) = encoding
;
3034 nst_methods
= TREE_CHAIN (nst_methods
);
3039 if (! METHOD_ENCODING (cls_methods
))
3041 hack_method_prototype (cls_methods
, tmp_decl
);
3042 encoding
= encode_method_prototype (cls_methods
, tmp_decl
);
3043 METHOD_ENCODING (cls_methods
) = encoding
;
3046 cls_methods
= TREE_CHAIN (cls_methods
);
3048 generate_method_descriptors (p
);
3050 if (PROTOCOL_LIST (p
))
3051 refs_decl
= generate_protocol_list (p
);
3055 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3057 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
],
3059 decl_specs
= tree_cons (NULL_TREE
, objc_protocol_template
, sc_spec
);
3061 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
),
3062 decl_specs
, 1, NULL_TREE
);
3064 DECL_CONTEXT (decl
) = NULL_TREE
;
3066 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
3072 (build_tree_list (build_tree_list (NULL_TREE
,
3073 objc_protocol_template
),
3074 build1 (INDIRECT_REF
, NULL_TREE
,
3075 build1 (INDIRECT_REF
, NULL_TREE
,
3078 refs_expr
= build_unary_op (ADDR_EXPR
, refs_decl
, 0);
3079 TREE_TYPE (refs_expr
) = cast_type2
;
3082 refs_expr
= build_int_2 (0, 0);
3084 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3085 by generate_method_descriptors, which is called above. */
3086 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
3087 protocol_name_expr
, refs_expr
,
3088 UOBJC_INSTANCE_METHODS_decl
,
3089 UOBJC_CLASS_METHODS_decl
);
3090 finish_decl (decl
, initlist
, NULL_TREE
);
3092 /* Mark the decl as used to avoid "defined but not used" warning. */
3093 TREE_USED (decl
) = 1;
3098 build_protocol_initializer (type
, protocol_name
, protocol_list
,
3099 instance_methods
, class_methods
)
3103 tree instance_methods
;
3106 tree initlist
= NULL_TREE
, expr
;
3109 cast_type
= groktypename
3111 (build_tree_list (NULL_TREE
,
3112 xref_tag (RECORD_TYPE
,
3113 get_identifier (UTAG_CLASS
))),
3114 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
3116 /* Filling the "isa" in with one allows the runtime system to
3117 detect that the version change...should remove before final release. */
3119 expr
= build_int_2 (PROTOCOL_VERSION
, 0);
3120 TREE_TYPE (expr
) = cast_type
;
3121 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3122 initlist
= tree_cons (NULL_TREE
, protocol_name
, initlist
);
3123 initlist
= tree_cons (NULL_TREE
, protocol_list
, initlist
);
3125 if (!instance_methods
)
3126 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3129 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
3130 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3134 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3137 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
3138 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3141 return build_constructor (type
, nreverse (initlist
));
3144 /* struct objc_category {
3145 char *category_name;
3147 struct objc_method_list *instance_methods;
3148 struct objc_method_list *class_methods;
3149 struct objc_protocol_list *protocols;
3153 build_category_template ()
3155 tree decl_specs
, field_decl
, field_decl_chain
;
3157 objc_category_template
= start_struct (RECORD_TYPE
,
3158 get_identifier (UTAG_CATEGORY
));
3159 /* char *category_name; */
3161 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3163 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("category_name"));
3165 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3166 field_decl_chain
= field_decl
;
3168 /* char *class_name; */
3170 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3171 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_name"));
3173 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3174 chainon (field_decl_chain
, field_decl
);
3176 /* struct objc_method_list *instance_methods; */
3178 decl_specs
= build_tree_list (NULL_TREE
,
3179 xref_tag (RECORD_TYPE
,
3180 get_identifier (UTAG_METHOD_LIST
)));
3182 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
3184 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3185 chainon (field_decl_chain
, field_decl
);
3187 /* struct objc_method_list *class_methods; */
3189 decl_specs
= build_tree_list (NULL_TREE
,
3190 xref_tag (RECORD_TYPE
,
3191 get_identifier (UTAG_METHOD_LIST
)));
3193 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
3195 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3196 chainon (field_decl_chain
, field_decl
);
3198 /* struct objc_protocol **protocol_list; */
3200 decl_specs
= build_tree_list (NULL_TREE
,
3201 xref_tag (RECORD_TYPE
,
3202 get_identifier (UTAG_PROTOCOL
)));
3204 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3205 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3207 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3208 chainon (field_decl_chain
, field_decl
);
3210 finish_struct (objc_category_template
, field_decl_chain
, NULL_TREE
);
3213 /* struct objc_selector {
3219 build_selector_template ()
3222 tree decl_specs
, field_decl
, field_decl_chain
;
3224 objc_selector_template
3225 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SELECTOR
));
3229 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3230 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3232 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3233 field_decl_chain
= field_decl
;
3235 /* char *sel_type; */
3237 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3238 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_type"));
3240 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3241 chainon (field_decl_chain
, field_decl
);
3243 finish_struct (objc_selector_template
, field_decl_chain
, NULL_TREE
);
3246 /* struct objc_class {
3247 struct objc_class *isa;
3248 struct objc_class *super_class;
3253 struct objc_ivar_list *ivars;
3254 struct objc_method_list *methods;
3255 if (flag_next_runtime)
3256 struct objc_cache *cache;
3258 struct sarray *dtable;
3259 struct objc_class *subclass_list;
3260 struct objc_class *sibling_class;
3262 struct objc_protocol_list *protocols;
3263 void *gc_object_type;
3267 build_class_template ()
3269 tree decl_specs
, field_decl
, field_decl_chain
;
3272 = start_struct (RECORD_TYPE
, get_identifier (UTAG_CLASS
));
3274 /* struct objc_class *isa; */
3276 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3277 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
3279 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3280 field_decl_chain
= field_decl
;
3282 /* struct objc_class *super_class; */
3284 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3286 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("super_class"));
3288 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3289 chainon (field_decl_chain
, field_decl
);
3293 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3294 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
3296 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3297 chainon (field_decl_chain
, field_decl
);
3301 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3302 field_decl
= get_identifier ("version");
3304 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3305 chainon (field_decl_chain
, field_decl
);
3309 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3310 field_decl
= get_identifier ("info");
3312 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3313 chainon (field_decl_chain
, field_decl
);
3315 /* long instance_size; */
3317 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3318 field_decl
= get_identifier ("instance_size");
3320 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3321 chainon (field_decl_chain
, field_decl
);
3323 /* struct objc_ivar_list *ivars; */
3325 decl_specs
= build_tree_list (NULL_TREE
,
3326 xref_tag (RECORD_TYPE
,
3327 get_identifier (UTAG_IVAR_LIST
)));
3328 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivars"));
3330 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3331 chainon (field_decl_chain
, field_decl
);
3333 /* struct objc_method_list *methods; */
3335 decl_specs
= build_tree_list (NULL_TREE
,
3336 xref_tag (RECORD_TYPE
,
3337 get_identifier (UTAG_METHOD_LIST
)));
3338 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("methods"));
3340 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3341 chainon (field_decl_chain
, field_decl
);
3343 if (flag_next_runtime
)
3345 /* struct objc_cache *cache; */
3347 decl_specs
= build_tree_list (NULL_TREE
,
3348 xref_tag (RECORD_TYPE
,
3349 get_identifier ("objc_cache")));
3350 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("cache"));
3351 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3352 decl_specs
, NULL_TREE
);
3353 chainon (field_decl_chain
, field_decl
);
3357 /* struct sarray *dtable; */
3359 decl_specs
= build_tree_list (NULL_TREE
,
3360 xref_tag (RECORD_TYPE
,
3361 get_identifier ("sarray")));
3362 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("dtable"));
3363 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3364 decl_specs
, NULL_TREE
);
3365 chainon (field_decl_chain
, field_decl
);
3367 /* struct objc_class *subclass_list; */
3369 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3371 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("subclass_list"));
3372 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3373 decl_specs
, NULL_TREE
);
3374 chainon (field_decl_chain
, field_decl
);
3376 /* struct objc_class *sibling_class; */
3378 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3380 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sibling_class"));
3381 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3382 decl_specs
, NULL_TREE
);
3383 chainon (field_decl_chain
, field_decl
);
3386 /* struct objc_protocol **protocol_list; */
3388 decl_specs
= build_tree_list (NULL_TREE
,
3389 xref_tag (RECORD_TYPE
,
3390 get_identifier (UTAG_PROTOCOL
)));
3392 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3394 = build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3395 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3396 decl_specs
, NULL_TREE
);
3397 chainon (field_decl_chain
, field_decl
);
3401 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3402 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3404 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3405 chainon (field_decl_chain
, field_decl
);
3407 /* void *gc_object_type; */
3409 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3410 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("gc_object_type"));
3412 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3413 chainon (field_decl_chain
, field_decl
);
3415 finish_struct (objc_class_template
, field_decl_chain
, NULL_TREE
);
3418 /* Generate appropriate forward declarations for an implementation. */
3421 synth_forward_declarations ()
3423 tree sc_spec
, decl_specs
, an_id
;
3425 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3427 an_id
= synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context
);
3429 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
3430 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
3431 UOBJC_CLASS_decl
= define_decl (an_id
, decl_specs
);
3432 TREE_USED (UOBJC_CLASS_decl
) = 1;
3433 DECL_ARTIFICIAL (UOBJC_CLASS_decl
) = 1;
3435 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3437 an_id
= synth_id_with_class_suffix ("_OBJC_METACLASS",
3438 objc_implementation_context
);
3440 UOBJC_METACLASS_decl
= define_decl (an_id
, decl_specs
);
3441 TREE_USED (UOBJC_METACLASS_decl
) = 1;
3442 DECL_ARTIFICIAL(UOBJC_METACLASS_decl
) = 1;
3444 /* Pre-build the following entities - for speed/convenience. */
3446 an_id
= get_identifier ("super_class");
3447 ucls_super_ref
= build_component_ref (UOBJC_CLASS_decl
, an_id
);
3448 uucls_super_ref
= build_component_ref (UOBJC_METACLASS_decl
, an_id
);
3452 error_with_ivar (message
, decl
, rawdecl
)
3453 const char *message
;
3459 report_error_function (DECL_SOURCE_FILE (decl
));
3461 error_with_file_and_line (DECL_SOURCE_FILE (decl
),
3462 DECL_SOURCE_LINE (decl
),
3464 message
, gen_declaration (rawdecl
, errbuf
));
3468 #define USERTYPE(t) \
3469 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3470 || TREE_CODE (t) == ENUMERAL_TYPE)
3473 check_ivars (inter
, imp
)
3477 tree intdecls
= CLASS_IVARS (inter
);
3478 tree impdecls
= CLASS_IVARS (imp
);
3479 tree rawintdecls
= CLASS_RAW_IVARS (inter
);
3480 tree rawimpdecls
= CLASS_RAW_IVARS (imp
);
3486 if (intdecls
== 0 && impdecls
== 0)
3488 if (intdecls
== 0 || impdecls
== 0)
3490 error ("inconsistent instance variable specification");
3494 t1
= TREE_TYPE (intdecls
); t2
= TREE_TYPE (impdecls
);
3496 if (!comptypes (t1
, t2
))
3498 if (DECL_NAME (intdecls
) == DECL_NAME (impdecls
))
3500 error_with_ivar ("conflicting instance variable type",
3501 impdecls
, rawimpdecls
);
3502 error_with_ivar ("previous declaration of",
3503 intdecls
, rawintdecls
);
3505 else /* both the type and the name don't match */
3507 error ("inconsistent instance variable specification");
3512 else if (DECL_NAME (intdecls
) != DECL_NAME (impdecls
))
3514 error_with_ivar ("conflicting instance variable name",
3515 impdecls
, rawimpdecls
);
3516 error_with_ivar ("previous declaration of",
3517 intdecls
, rawintdecls
);
3520 intdecls
= TREE_CHAIN (intdecls
);
3521 impdecls
= TREE_CHAIN (impdecls
);
3522 rawintdecls
= TREE_CHAIN (rawintdecls
);
3523 rawimpdecls
= TREE_CHAIN (rawimpdecls
);
3527 /* Set super_type to the data type node for struct objc_super *,
3528 first defining struct objc_super itself.
3529 This needs to be done just once per compilation. */
3532 build_super_template ()
3534 tree record
, decl_specs
, field_decl
, field_decl_chain
;
3536 record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_SUPER
));
3538 /* struct objc_object *self; */
3540 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3541 field_decl
= get_identifier ("self");
3542 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3543 field_decl
= grokfield (input_filename
, lineno
,
3544 field_decl
, decl_specs
, NULL_TREE
);
3545 field_decl_chain
= field_decl
;
3547 /* struct objc_class *class; */
3549 decl_specs
= get_identifier (UTAG_CLASS
);
3550 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
3551 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class"));
3553 field_decl
= grokfield (input_filename
, lineno
,
3554 field_decl
, decl_specs
, NULL_TREE
);
3555 chainon (field_decl_chain
, field_decl
);
3557 finish_struct (record
, field_decl_chain
, NULL_TREE
);
3559 /* `struct objc_super *' */
3560 super_type
= groktypename (build_tree_list (build_tree_list (NULL_TREE
,
3562 build1 (INDIRECT_REF
,
3563 NULL_TREE
, NULL_TREE
)));
3567 /* struct objc_ivar {
3574 build_ivar_template ()
3576 tree objc_ivar_id
, objc_ivar_record
;
3577 tree decl_specs
, field_decl
, field_decl_chain
;
3579 objc_ivar_id
= get_identifier (UTAG_IVAR
);
3580 objc_ivar_record
= start_struct (RECORD_TYPE
, objc_ivar_id
);
3582 /* char *ivar_name; */
3584 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3585 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_name"));
3587 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3588 decl_specs
, NULL_TREE
);
3589 field_decl_chain
= field_decl
;
3591 /* char *ivar_type; */
3593 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3594 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_type"));
3596 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3597 decl_specs
, NULL_TREE
);
3598 chainon (field_decl_chain
, field_decl
);
3600 /* int ivar_offset; */
3602 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3603 field_decl
= get_identifier ("ivar_offset");
3605 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3606 decl_specs
, NULL_TREE
);
3607 chainon (field_decl_chain
, field_decl
);
3609 finish_struct (objc_ivar_record
, field_decl_chain
, NULL_TREE
);
3611 return objc_ivar_record
;
3616 struct objc_ivar ivar_list[ivar_count];
3620 build_ivar_list_template (list_type
, size
)
3624 tree objc_ivar_list_record
;
3625 tree decl_specs
, field_decl
, field_decl_chain
;
3627 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3629 /* int ivar_count; */
3631 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3632 field_decl
= get_identifier ("ivar_count");
3634 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3635 decl_specs
, NULL_TREE
);
3636 field_decl_chain
= field_decl
;
3638 /* struct objc_ivar ivar_list[]; */
3640 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3641 field_decl
= build_nt (ARRAY_REF
, get_identifier ("ivar_list"),
3642 build_int_2 (size
, 0));
3644 field_decl
= grokfield (input_filename
, lineno
,
3645 field_decl
, decl_specs
, NULL_TREE
);
3646 chainon (field_decl_chain
, field_decl
);
3648 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3650 return objc_ivar_list_record
;
3656 struct objc_method method_list[method_count];
3660 build_method_list_template (list_type
, size
)
3664 tree objc_ivar_list_record
;
3665 tree decl_specs
, field_decl
, field_decl_chain
;
3667 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3669 /* int method_next; */
3674 xref_tag (RECORD_TYPE
,
3675 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
3677 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_next"));
3678 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3679 decl_specs
, NULL_TREE
);
3680 field_decl_chain
= field_decl
;
3682 /* int method_count; */
3684 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3685 field_decl
= get_identifier ("method_count");
3687 field_decl
= grokfield (input_filename
, lineno
,
3688 field_decl
, decl_specs
, NULL_TREE
);
3689 chainon (field_decl_chain
, field_decl
);
3691 /* struct objc_method method_list[]; */
3693 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3694 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
3695 build_int_2 (size
, 0));
3697 field_decl
= grokfield (input_filename
, lineno
,
3698 field_decl
, decl_specs
, NULL_TREE
);
3699 chainon (field_decl_chain
, field_decl
);
3701 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3703 return objc_ivar_list_record
;
3707 build_ivar_list_initializer (type
, field_decl
)
3711 tree initlist
= NULL_TREE
;
3715 tree ivar
= NULL_TREE
;
3718 if (DECL_NAME (field_decl
))
3719 ivar
= tree_cons (NULL_TREE
,
3720 add_objc_string (DECL_NAME (field_decl
),
3724 /* Unnamed bit-field ivar (yuck). */
3725 ivar
= tree_cons (NULL_TREE
, build_int_2 (0, 0), ivar
);
3728 encode_field_decl (field_decl
,
3729 obstack_object_size (&util_obstack
),
3730 OBJC_ENCODE_DONT_INLINE_DEFS
);
3732 /* Null terminate string. */
3733 obstack_1grow (&util_obstack
, 0);
3737 add_objc_string (get_identifier (obstack_finish (&util_obstack
)),
3740 obstack_free (&util_obstack
, util_firstobj
);
3743 ivar
= tree_cons (NULL_TREE
, byte_position (field_decl
), ivar
);
3744 initlist
= tree_cons (NULL_TREE
,
3745 build_constructor (type
, nreverse (ivar
)),
3748 field_decl
= TREE_CHAIN (field_decl
);
3752 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3756 generate_ivars_list (type
, name
, size
, list
)
3762 tree sc_spec
, decl_specs
, decl
, initlist
;
3764 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3765 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
3767 decl
= start_decl (synth_id_with_class_suffix (name
, objc_implementation_context
),
3768 decl_specs
, 1, NULL_TREE
);
3770 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
3771 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3774 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3781 generate_ivar_lists ()
3783 tree initlist
, ivar_list_template
, chain
;
3784 tree cast
, variable_length_type
;
3787 generating_instance_variables
= 1;
3789 if (!objc_ivar_template
)
3790 objc_ivar_template
= build_ivar_template ();
3794 (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3795 get_identifier (UTAG_IVAR_LIST
))),
3797 variable_length_type
= groktypename (cast
);
3799 /* Only generate class variables for the root of the inheritance
3800 hierarchy since these will be the same for every class. */
3802 if (CLASS_SUPER_NAME (implementation_template
) == NULL_TREE
3803 && (chain
= TYPE_FIELDS (objc_class_template
)))
3805 size
= list_length (chain
);
3807 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3808 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3810 UOBJC_CLASS_VARIABLES_decl
3811 = generate_ivars_list (ivar_list_template
, "_OBJC_CLASS_VARIABLES",
3813 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl
) = variable_length_type
;
3816 UOBJC_CLASS_VARIABLES_decl
= 0;
3818 chain
= CLASS_IVARS (implementation_template
);
3821 size
= list_length (chain
);
3822 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3823 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3825 UOBJC_INSTANCE_VARIABLES_decl
3826 = generate_ivars_list (ivar_list_template
, "_OBJC_INSTANCE_VARIABLES",
3828 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl
) = variable_length_type
;
3831 UOBJC_INSTANCE_VARIABLES_decl
= 0;
3833 generating_instance_variables
= 0;
3837 build_dispatch_table_initializer (type
, entries
)
3841 tree initlist
= NULL_TREE
;
3845 tree elemlist
= NULL_TREE
;
3847 elemlist
= tree_cons (NULL_TREE
,
3848 build_selector (METHOD_SEL_NAME (entries
)),
3851 elemlist
= tree_cons (NULL_TREE
,
3852 add_objc_string (METHOD_ENCODING (entries
),
3856 elemlist
= tree_cons (NULL_TREE
,
3857 build_unary_op (ADDR_EXPR
,
3858 METHOD_DEFINITION (entries
), 1),
3861 initlist
= tree_cons (NULL_TREE
,
3862 build_constructor (type
, nreverse (elemlist
)),
3865 entries
= TREE_CHAIN (entries
);
3869 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3872 /* To accomplish method prototyping without generating all kinds of
3873 inane warnings, the definition of the dispatch table entries were
3876 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3878 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3881 build_method_template ()
3884 tree decl_specs
, field_decl
, field_decl_chain
;
3886 _SLT_record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD
));
3888 /* struct objc_selector *_cmd; */
3889 decl_specs
= tree_cons (NULL_TREE
,
3890 xref_tag (RECORD_TYPE
,
3891 get_identifier (TAG_SELECTOR
)),
3893 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
3895 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3896 decl_specs
, NULL_TREE
);
3897 field_decl_chain
= field_decl
;
3899 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
3900 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
,
3901 get_identifier ("method_types"));
3902 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3903 decl_specs
, NULL_TREE
);
3904 chainon (field_decl_chain
, field_decl
);
3908 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_VOID
], NULL_TREE
);
3909 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_imp"));
3910 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3911 decl_specs
, NULL_TREE
);
3912 chainon (field_decl_chain
, field_decl
);
3914 finish_struct (_SLT_record
, field_decl_chain
, NULL_TREE
);
3921 generate_dispatch_table (type
, name
, size
, list
)
3927 tree sc_spec
, decl_specs
, decl
, initlist
;
3929 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3930 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
3932 decl
= start_decl (synth_id_with_class_suffix (name
, objc_implementation_context
),
3933 decl_specs
, 1, NULL_TREE
);
3935 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
3936 initlist
= tree_cons (NULL_TREE
, build_int_2 (size
, 0), initlist
);
3937 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3940 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3947 generate_dispatch_tables ()
3949 tree initlist
, chain
, method_list_template
;
3950 tree cast
, variable_length_type
;
3953 if (!objc_method_template
)
3954 objc_method_template
= build_method_template ();
3958 (build_tree_list (NULL_TREE
,
3959 xref_tag (RECORD_TYPE
,
3960 get_identifier (UTAG_METHOD_LIST
))),
3963 variable_length_type
= groktypename (cast
);
3965 chain
= CLASS_CLS_METHODS (objc_implementation_context
);
3968 size
= list_length (chain
);
3970 method_list_template
3971 = build_method_list_template (objc_method_template
, size
);
3973 = build_dispatch_table_initializer (objc_method_template
, chain
);
3975 UOBJC_CLASS_METHODS_decl
3976 = generate_dispatch_table (method_list_template
,
3977 ((TREE_CODE (objc_implementation_context
)
3978 == CLASS_IMPLEMENTATION_TYPE
)
3979 ? "_OBJC_CLASS_METHODS"
3980 : "_OBJC_CATEGORY_CLASS_METHODS"),
3982 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
3985 UOBJC_CLASS_METHODS_decl
= 0;
3987 chain
= CLASS_NST_METHODS (objc_implementation_context
);
3990 size
= list_length (chain
);
3992 method_list_template
3993 = build_method_list_template (objc_method_template
, size
);
3995 = build_dispatch_table_initializer (objc_method_template
, chain
);
3997 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
3998 UOBJC_INSTANCE_METHODS_decl
3999 = generate_dispatch_table (method_list_template
,
4000 "_OBJC_INSTANCE_METHODS",
4003 /* We have a category. */
4004 UOBJC_INSTANCE_METHODS_decl
4005 = generate_dispatch_table (method_list_template
,
4006 "_OBJC_CATEGORY_INSTANCE_METHODS",
4008 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
4011 UOBJC_INSTANCE_METHODS_decl
= 0;
4015 generate_protocol_list (i_or_p
)
4018 tree initlist
, decl_specs
, sc_spec
;
4019 tree refs_decl
, expr_decl
, lproto
, e
, plist
;
4023 if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
4024 || TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4025 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
4026 else if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4027 plist
= PROTOCOL_LIST (i_or_p
);
4031 cast_type
= groktypename
4033 (build_tree_list (NULL_TREE
,
4034 xref_tag (RECORD_TYPE
,
4035 get_identifier (UTAG_PROTOCOL
))),
4036 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
4039 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4040 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
4041 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
4044 /* Build initializer. */
4045 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), NULL_TREE
);
4047 e
= build_int_2 (size
, 0);
4048 TREE_TYPE (e
) = cast_type
;
4049 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4051 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4053 tree pval
= TREE_VALUE (lproto
);
4055 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
4056 && PROTOCOL_FORWARD_DECL (pval
))
4058 e
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (pval
), 0);
4059 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4063 /* static struct objc_protocol *refs[n]; */
4065 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4066 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
4067 get_identifier (UTAG_PROTOCOL
)),
4070 if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4071 expr_decl
= build_nt (ARRAY_REF
,
4072 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4074 build_int_2 (size
+ 2, 0));
4075 else if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
)
4076 expr_decl
= build_nt (ARRAY_REF
,
4077 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4079 build_int_2 (size
+ 2, 0));
4080 else if (TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4082 = build_nt (ARRAY_REF
,
4083 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4085 build_int_2 (size
+ 2, 0));
4089 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
4091 refs_decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
4092 DECL_CONTEXT (refs_decl
) = NULL_TREE
;
4094 finish_decl (refs_decl
, build_constructor (TREE_TYPE (refs_decl
),
4095 nreverse (initlist
)),
4102 build_category_initializer (type
, cat_name
, class_name
,
4103 instance_methods
, class_methods
, protocol_list
)
4107 tree instance_methods
;
4111 tree initlist
= NULL_TREE
, expr
;
4113 initlist
= tree_cons (NULL_TREE
, cat_name
, initlist
);
4114 initlist
= tree_cons (NULL_TREE
, class_name
, initlist
);
4116 if (!instance_methods
)
4117 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4120 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
4121 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4124 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4127 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
4128 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4131 /* protocol_list = */
4133 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4136 tree cast_type2
= groktypename
4138 (build_tree_list (NULL_TREE
,
4139 xref_tag (RECORD_TYPE
,
4140 get_identifier (UTAG_PROTOCOL
))),
4141 build1 (INDIRECT_REF
, NULL_TREE
,
4142 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4144 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4145 TREE_TYPE (expr
) = cast_type2
;
4146 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4149 return build_constructor (type
, nreverse (initlist
));
4152 /* struct objc_class {
4153 struct objc_class *isa;
4154 struct objc_class *super_class;
4159 struct objc_ivar_list *ivars;
4160 struct objc_method_list *methods;
4161 if (flag_next_runtime)
4162 struct objc_cache *cache;
4164 struct sarray *dtable;
4165 struct objc_class *subclass_list;
4166 struct objc_class *sibling_class;
4168 struct objc_protocol_list *protocols;
4169 void *gc_object_type;
4173 build_shared_structure_initializer (type
, isa
, super
, name
, size
, status
,
4174 dispatch_table
, ivar_list
, protocol_list
)
4181 tree dispatch_table
;
4185 tree initlist
= NULL_TREE
, expr
;
4188 initlist
= tree_cons (NULL_TREE
, isa
, initlist
);
4191 initlist
= tree_cons (NULL_TREE
, super
, initlist
);
4194 initlist
= tree_cons (NULL_TREE
, default_conversion (name
), initlist
);
4197 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4200 initlist
= tree_cons (NULL_TREE
, build_int_2 (status
, 0), initlist
);
4202 /* instance_size = */
4203 initlist
= tree_cons (NULL_TREE
, size
, initlist
);
4205 /* objc_ivar_list = */
4207 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4210 expr
= build_unary_op (ADDR_EXPR
, ivar_list
, 0);
4211 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4214 /* objc_method_list = */
4215 if (!dispatch_table
)
4216 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4219 expr
= build_unary_op (ADDR_EXPR
, dispatch_table
, 0);
4220 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4223 if (flag_next_runtime
)
4224 /* method_cache = */
4225 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4229 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4231 /* subclass_list = */
4232 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4234 /* sibling_class = */
4235 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4238 /* protocol_list = */
4239 if (! protocol_list
)
4240 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4246 (build_tree_list (NULL_TREE
,
4247 xref_tag (RECORD_TYPE
,
4248 get_identifier (UTAG_PROTOCOL
))),
4249 build1 (INDIRECT_REF
, NULL_TREE
,
4250 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4252 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4253 TREE_TYPE (expr
) = cast_type2
;
4254 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4257 /* gc_object_type = NULL */
4258 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4260 return build_constructor (type
, nreverse (initlist
));
4263 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4266 generate_category (cat
)
4269 tree sc_spec
, decl_specs
, decl
;
4270 tree initlist
, cat_name_expr
, class_name_expr
;
4271 tree protocol_decl
, category
;
4273 add_class_reference (CLASS_NAME (cat
));
4274 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
4276 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
4278 category
= CLASS_CATEGORY_LIST (implementation_template
);
4280 /* find the category interface from the class it is associated with */
4283 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
4285 category
= CLASS_CATEGORY_LIST (category
);
4288 if (category
&& CLASS_PROTOCOL_LIST (category
))
4290 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
4291 protocol_decl
= generate_protocol_list (category
);
4296 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4297 decl_specs
= tree_cons (NULL_TREE
, objc_category_template
, sc_spec
);
4299 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4300 objc_implementation_context
),
4301 decl_specs
, 1, NULL_TREE
);
4303 initlist
= build_category_initializer (TREE_TYPE (decl
),
4304 cat_name_expr
, class_name_expr
,
4305 UOBJC_INSTANCE_METHODS_decl
,
4306 UOBJC_CLASS_METHODS_decl
,
4309 TREE_USED (decl
) = 1;
4310 finish_decl (decl
, initlist
, NULL_TREE
);
4313 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4314 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4317 generate_shared_structures ()
4319 tree sc_spec
, decl_specs
, decl
;
4320 tree name_expr
, super_expr
, root_expr
;
4321 tree my_root_id
= NULL_TREE
, my_super_id
= NULL_TREE
;
4322 tree cast_type
, initlist
, protocol_decl
;
4324 my_super_id
= CLASS_SUPER_NAME (implementation_template
);
4327 add_class_reference (my_super_id
);
4329 /* Compute "my_root_id" - this is required for code generation.
4330 the "isa" for all meta class structures points to the root of
4331 the inheritance hierarchy (e.g. "__Object")... */
4332 my_root_id
= my_super_id
;
4335 tree my_root_int
= lookup_interface (my_root_id
);
4337 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
4338 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
4345 /* No super class. */
4346 my_root_id
= CLASS_NAME (implementation_template
);
4349 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
4350 objc_class_template
),
4351 build1 (INDIRECT_REF
,
4352 NULL_TREE
, NULL_TREE
)));
4354 name_expr
= add_objc_string (CLASS_NAME (implementation_template
),
4357 /* Install class `isa' and `super' pointers at runtime. */
4360 super_expr
= add_objc_string (my_super_id
, class_names
);
4361 super_expr
= build_c_cast (cast_type
, super_expr
); /* cast! */
4364 super_expr
= build_int_2 (0, 0);
4366 root_expr
= add_objc_string (my_root_id
, class_names
);
4367 root_expr
= build_c_cast (cast_type
, root_expr
); /* cast! */
4369 if (CLASS_PROTOCOL_LIST (implementation_template
))
4371 generate_protocol_references
4372 (CLASS_PROTOCOL_LIST (implementation_template
));
4373 protocol_decl
= generate_protocol_list (implementation_template
);
4378 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4380 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
4381 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
4383 decl
= start_decl (DECL_NAME (UOBJC_METACLASS_decl
), decl_specs
, 1,
4387 = build_shared_structure_initializer
4389 root_expr
, super_expr
, name_expr
,
4390 convert (integer_type_node
, TYPE_SIZE_UNIT (objc_class_template
)),
4392 UOBJC_CLASS_METHODS_decl
,
4393 UOBJC_CLASS_VARIABLES_decl
,
4396 finish_decl (decl
, initlist
, NULL_TREE
);
4398 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4400 decl
= start_decl (DECL_NAME (UOBJC_CLASS_decl
), decl_specs
, 1,
4404 = build_shared_structure_initializer
4406 build_unary_op (ADDR_EXPR
, UOBJC_METACLASS_decl
, 0),
4407 super_expr
, name_expr
,
4408 convert (integer_type_node
,
4409 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4410 (implementation_template
))),
4412 UOBJC_INSTANCE_METHODS_decl
,
4413 UOBJC_INSTANCE_VARIABLES_decl
,
4416 finish_decl (decl
, initlist
, NULL_TREE
);
4420 synth_id_with_class_suffix (preamble
, ctxt
)
4421 const char *preamble
;
4425 if (TREE_CODE (ctxt
) == CLASS_IMPLEMENTATION_TYPE
4426 || TREE_CODE (ctxt
) == CLASS_INTERFACE_TYPE
)
4428 const char *const class_name
4429 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
4430 string
= (char *) alloca (strlen (preamble
) + strlen (class_name
) + 3);
4431 sprintf (string
, "%s_%s", preamble
,
4432 IDENTIFIER_POINTER (CLASS_NAME (ctxt
)));
4434 else if (TREE_CODE (ctxt
) == CATEGORY_IMPLEMENTATION_TYPE
4435 || TREE_CODE (ctxt
) == CATEGORY_INTERFACE_TYPE
)
4437 /* We have a category. */
4438 const char *const class_name
4439 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
4440 const char *const class_super_name
4441 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
));
4442 string
= (char *) alloca (strlen (preamble
)
4443 + strlen (class_name
)
4444 + strlen (class_super_name
)
4446 sprintf (string
, "%s_%s_%s", preamble
, class_name
, class_super_name
);
4448 else if (TREE_CODE (ctxt
) == PROTOCOL_INTERFACE_TYPE
)
4450 const char *protocol_name
= IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt
));
4452 = (char *) alloca (strlen (preamble
) + strlen (protocol_name
) + 3);
4453 sprintf (string
, "%s_%s", preamble
, protocol_name
);
4458 return get_identifier (string
);
4462 is_objc_type_qualifier (node
)
4465 return (TREE_CODE (node
) == IDENTIFIER_NODE
4466 && (node
== ridpointers
[(int) RID_CONST
]
4467 || node
== ridpointers
[(int) RID_VOLATILE
]
4468 || node
== ridpointers
[(int) RID_IN
]
4469 || node
== ridpointers
[(int) RID_OUT
]
4470 || node
== ridpointers
[(int) RID_INOUT
]
4471 || node
== ridpointers
[(int) RID_BYCOPY
]
4472 || node
== ridpointers
[(int) RID_BYREF
]
4473 || node
== ridpointers
[(int) RID_ONEWAY
]));
4476 /* If type is empty or only type qualifiers are present, add default
4477 type of id (otherwise grokdeclarator will default to int). */
4480 adjust_type_for_id_default (type
)
4483 tree declspecs
, chain
;
4486 return build_tree_list (build_tree_list (NULL_TREE
, objc_object_reference
),
4487 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4489 declspecs
= TREE_PURPOSE (type
);
4491 /* Determine if a typespec is present. */
4492 for (chain
= declspecs
;
4494 chain
= TREE_CHAIN (chain
))
4496 if (!is_objc_type_qualifier (TREE_VALUE (chain
)))
4500 return build_tree_list (tree_cons (NULL_TREE
, objc_object_reference
,
4502 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4507 selector ':' '(' typename ')' identifier
4510 Transform an Objective-C keyword argument into
4511 the C equivalent parameter declarator.
4513 In: key_name, an "identifier_node" (optional).
4514 arg_type, a "tree_list" (optional).
4515 arg_name, an "identifier_node".
4517 Note: It would be really nice to strongly type the preceding
4518 arguments in the function prototype; however, then I
4519 could not use the "accessor" macros defined in "tree.h".
4521 Out: an instance of "keyword_decl". */
4524 build_keyword_decl (key_name
, arg_type
, arg_name
)
4531 /* If no type is specified, default to "id". */
4532 arg_type
= adjust_type_for_id_default (arg_type
);
4534 keyword_decl
= make_node (KEYWORD_DECL
);
4536 TREE_TYPE (keyword_decl
) = arg_type
;
4537 KEYWORD_ARG_NAME (keyword_decl
) = arg_name
;
4538 KEYWORD_KEY_NAME (keyword_decl
) = key_name
;
4540 return keyword_decl
;
4543 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4546 build_keyword_selector (selector
)
4550 tree key_chain
, key_name
;
4553 /* Scan the selector to see how much space we'll need. */
4554 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4556 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4557 key_name
= KEYWORD_KEY_NAME (key_chain
);
4558 else if (TREE_CODE (selector
) == TREE_LIST
)
4559 key_name
= TREE_PURPOSE (key_chain
);
4564 len
+= IDENTIFIER_LENGTH (key_name
) + 1;
4566 /* Just a ':' arg. */
4570 buf
= (char *) alloca (len
+ 1);
4571 /* Start the buffer out as an empty string. */
4574 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4576 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4577 key_name
= KEYWORD_KEY_NAME (key_chain
);
4578 else if (TREE_CODE (selector
) == TREE_LIST
)
4579 key_name
= TREE_PURPOSE (key_chain
);
4584 strcat (buf
, IDENTIFIER_POINTER (key_name
));
4588 return get_identifier (buf
);
4591 /* Used for declarations and definitions. */
4594 build_method_decl (code
, ret_type
, selector
, add_args
)
4595 enum tree_code code
;
4602 /* If no type is specified, default to "id". */
4603 ret_type
= adjust_type_for_id_default (ret_type
);
4605 method_decl
= make_node (code
);
4606 TREE_TYPE (method_decl
) = ret_type
;
4608 /* If we have a keyword selector, create an identifier_node that
4609 represents the full selector name (`:' included)... */
4610 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4612 METHOD_SEL_NAME (method_decl
) = build_keyword_selector (selector
);
4613 METHOD_SEL_ARGS (method_decl
) = selector
;
4614 METHOD_ADD_ARGS (method_decl
) = add_args
;
4618 METHOD_SEL_NAME (method_decl
) = selector
;
4619 METHOD_SEL_ARGS (method_decl
) = NULL_TREE
;
4620 METHOD_ADD_ARGS (method_decl
) = NULL_TREE
;
4626 #define METHOD_DEF 0
4627 #define METHOD_REF 1
4629 /* Used by `build_objc_method_call' and `comp_method_types'. Return
4630 an argument list for method METH. CONTEXT is either METHOD_DEF or
4631 METHOD_REF, saying whether we are trying to define a method or call
4632 one. SUPERFLAG says this is for a send to super; this makes a
4633 difference for the NeXT calling sequence in which the lookup and
4634 the method call are done together. */
4637 get_arg_type_list (meth
, context
, superflag
)
4644 /* Receiver type. */
4645 if (flag_next_runtime
&& superflag
)
4646 arglist
= build_tree_list (NULL_TREE
, super_type
);
4647 else if (context
== METHOD_DEF
)
4648 arglist
= build_tree_list (NULL_TREE
, TREE_TYPE (self_decl
));
4650 arglist
= build_tree_list (NULL_TREE
, id_type
);
4652 /* Selector type - will eventually change to `int'. */
4653 chainon (arglist
, build_tree_list (NULL_TREE
, selector_type
));
4655 /* Build a list of argument types. */
4656 for (akey
= METHOD_SEL_ARGS (meth
); akey
; akey
= TREE_CHAIN (akey
))
4658 tree arg_decl
= groktypename_in_parm_context (TREE_TYPE (akey
));
4659 chainon (arglist
, build_tree_list (NULL_TREE
, TREE_TYPE (arg_decl
)));
4662 if (METHOD_ADD_ARGS (meth
) == objc_ellipsis_node
)
4663 /* We have a `, ...' immediately following the selector,
4664 finalize the arglist...simulate get_parm_info (0). */
4666 else if (METHOD_ADD_ARGS (meth
))
4668 /* we have a variable length selector */
4669 tree add_arg_list
= TREE_CHAIN (METHOD_ADD_ARGS (meth
));
4670 chainon (arglist
, add_arg_list
);
4673 /* finalize the arglist...simulate get_parm_info (1) */
4674 chainon (arglist
, build_tree_list (NULL_TREE
, void_type_node
));
4680 check_duplicates (hsh
)
4683 tree meth
= NULL_TREE
;
4691 /* We have two methods with the same name and different types. */
4693 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
) ? '-' : '+';
4695 warning ("multiple declarations for method `%s'",
4696 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
4698 warn_with_method ("using", type
, meth
);
4699 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
4700 warn_with_method ("also found", type
, loop
->value
);
4706 /* If RECEIVER is a class reference, return the identifier node for
4707 the referenced class. RECEIVER is created by get_class_reference,
4708 so we check the exact form created depending on which runtimes are
4712 receiver_is_class_object (receiver
)
4715 tree chain
, exp
, arg
;
4717 /* The receiver is 'self' in the context of a class method. */
4718 if (objc_method_context
4719 && receiver
== self_decl
4720 && TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
4722 return CLASS_NAME (objc_implementation_context
);
4725 if (flag_next_runtime
)
4727 /* The receiver is a variable created by
4728 build_class_reference_decl. */
4729 if (TREE_CODE (receiver
) == VAR_DECL
4730 && TREE_TYPE (receiver
) == objc_class_type
)
4731 /* Look up the identifier. */
4732 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
4733 if (TREE_PURPOSE (chain
) == receiver
)
4734 return TREE_VALUE (chain
);
4738 /* The receiver is a function call that returns an id. Check if
4739 it is a call to objc_getClass, if so, pick up the class name. */
4740 if (TREE_CODE (receiver
) == CALL_EXPR
4741 && (exp
= TREE_OPERAND (receiver
, 0))
4742 && TREE_CODE (exp
) == ADDR_EXPR
4743 && (exp
= TREE_OPERAND (exp
, 0))
4744 && TREE_CODE (exp
) == FUNCTION_DECL
4745 && exp
== objc_get_class_decl
4746 /* We have a call to objc_getClass! */
4747 && (arg
= TREE_OPERAND (receiver
, 1))
4748 && TREE_CODE (arg
) == TREE_LIST
4749 && (arg
= TREE_VALUE (arg
)))
4752 if (TREE_CODE (arg
) == ADDR_EXPR
4753 && (arg
= TREE_OPERAND (arg
, 0))
4754 && TREE_CODE (arg
) == STRING_CST
)
4755 /* Finally, we have the class name. */
4756 return get_identifier (TREE_STRING_POINTER (arg
));
4762 /* If we are currently building a message expr, this holds
4763 the identifier of the selector of the message. This is
4764 used when printing warnings about argument mismatches. */
4766 static tree building_objc_message_expr
= 0;
4769 maybe_building_objc_message_expr ()
4771 return building_objc_message_expr
;
4774 /* Construct an expression for sending a message.
4775 MESS has the object to send to in TREE_PURPOSE
4776 and the argument list (including selector) in TREE_VALUE.
4778 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4779 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4782 build_message_expr (mess
)
4785 tree receiver
= TREE_PURPOSE (mess
);
4787 tree args
= TREE_VALUE (mess
);
4788 tree method_params
= NULL_TREE
;
4790 if (TREE_CODE (receiver
) == ERROR_MARK
)
4791 return error_mark_node
;
4793 /* Obtain the full selector name. */
4794 if (TREE_CODE (args
) == IDENTIFIER_NODE
)
4795 /* A unary selector. */
4797 else if (TREE_CODE (args
) == TREE_LIST
)
4798 sel_name
= build_keyword_selector (args
);
4802 /* Build the parameter list to give to the method. */
4803 if (TREE_CODE (args
) == TREE_LIST
)
4805 tree chain
= args
, prev
= NULL_TREE
;
4807 /* We have a keyword selector--check for comma expressions. */
4810 tree element
= TREE_VALUE (chain
);
4812 /* We have a comma expression, must collapse... */
4813 if (TREE_CODE (element
) == TREE_LIST
)
4816 TREE_CHAIN (prev
) = element
;
4821 chain
= TREE_CHAIN (chain
);
4823 method_params
= args
;
4826 return finish_message_expr (receiver
, sel_name
, method_params
);
4829 /* The 'finish_message_expr' routine is called from within
4830 'build_message_expr' for non-template functions. In the case of
4831 C++ template functions, it is called from 'build_expr_from_tree'
4832 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
4835 finish_message_expr (receiver
, sel_name
, method_params
)
4836 tree receiver
, sel_name
, method_params
;
4838 tree method_prototype
= NULL_TREE
, class_ident
= NULL_TREE
;
4839 tree selector
, self_object
, retval
;
4840 int statically_typed
= 0, statically_allocated
= 0;
4842 /* Determine receiver type. */
4843 tree rtype
= TREE_TYPE (receiver
);
4844 int super
= IS_SUPER (rtype
);
4848 if (TREE_STATIC_TEMPLATE (rtype
))
4849 statically_allocated
= 1;
4850 else if (TREE_CODE (rtype
) == POINTER_TYPE
4851 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype
)))
4852 statically_typed
= 1;
4853 else if ((flag_next_runtime
4855 && (class_ident
= receiver_is_class_object (receiver
)))))
4857 else if (! IS_ID (rtype
)
4858 /* Allow any type that matches objc_class_type. */
4859 && ! comptypes (rtype
, objc_class_type
))
4861 warning ("invalid receiver type `%s'",
4862 gen_declaration (rtype
, errbuf
));
4864 if (statically_allocated
)
4865 receiver
= build_unary_op (ADDR_EXPR
, receiver
, 0);
4867 /* Don't evaluate the receiver twice. */
4868 receiver
= save_expr (receiver
);
4869 self_object
= receiver
;
4872 /* If sending to `super', use current self as the object. */
4873 self_object
= self_decl
;
4875 /* Determine operation return type. */
4881 if (CLASS_SUPER_NAME (implementation_template
))
4884 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
4886 if (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
)
4887 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4889 method_prototype
= lookup_class_method_static (iface
, sel_name
);
4891 if (iface
&& !method_prototype
)
4892 warning ("`%s' does not respond to `%s'",
4893 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template
)),
4894 IDENTIFIER_POINTER (sel_name
));
4898 error ("no super class declared in interface for `%s'",
4899 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
4900 return error_mark_node
;
4904 else if (statically_allocated
)
4906 tree ctype
= TREE_TYPE (rtype
);
4907 tree iface
= lookup_interface (TYPE_NAME (rtype
));
4910 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4912 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
4914 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
4917 if (!method_prototype
)
4918 warning ("`%s' does not respond to `%s'",
4919 IDENTIFIER_POINTER (TYPE_NAME (rtype
)),
4920 IDENTIFIER_POINTER (sel_name
));
4922 else if (statically_typed
)
4924 tree ctype
= TREE_TYPE (rtype
);
4926 /* `self' is now statically_typed. All methods should be visible
4927 within the context of the implementation. */
4928 if (objc_implementation_context
4929 && CLASS_NAME (objc_implementation_context
) == TYPE_NAME (ctype
))
4932 = lookup_instance_method_static (implementation_template
,
4935 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
4937 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
4940 if (! method_prototype
4941 && implementation_template
!= objc_implementation_context
)
4942 /* The method is not published in the interface. Check
4945 = lookup_method (CLASS_NST_METHODS (objc_implementation_context
),
4952 if ((iface
= lookup_interface (TYPE_NAME (ctype
))))
4953 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4955 if (! method_prototype
)
4957 tree protocol_list
= TYPE_PROTOCOL_LIST (ctype
);
4960 = lookup_method_in_protocol_list (protocol_list
,
4965 if (!method_prototype
)
4966 warning ("`%s' does not respond to `%s'",
4967 IDENTIFIER_POINTER (TYPE_NAME (ctype
)),
4968 IDENTIFIER_POINTER (sel_name
));
4970 else if (class_ident
)
4972 if (objc_implementation_context
4973 && CLASS_NAME (objc_implementation_context
) == class_ident
)
4976 = lookup_class_method_static (implementation_template
, sel_name
);
4978 if (!method_prototype
4979 && implementation_template
!= objc_implementation_context
)
4980 /* The method is not published in the interface. Check
4983 = lookup_method (CLASS_CLS_METHODS (objc_implementation_context
),
4990 if ((iface
= lookup_interface (class_ident
)))
4991 method_prototype
= lookup_class_method_static (iface
, sel_name
);
4994 if (!method_prototype
)
4996 warning ("cannot find class (factory) method");
4997 warning ("return type for `%s' defaults to id",
4998 IDENTIFIER_POINTER (sel_name
));
5001 else if (IS_PROTOCOL_QUALIFIED_ID (rtype
))
5003 /* An anonymous object that has been qualified with a protocol. */
5005 tree protocol_list
= TYPE_PROTOCOL_LIST (rtype
);
5007 method_prototype
= lookup_method_in_protocol_list (protocol_list
,
5010 if (!method_prototype
)
5014 warning ("method `%s' not implemented by protocol",
5015 IDENTIFIER_POINTER (sel_name
));
5017 /* Try and find the method signature in the global pools. */
5019 if (!(hsh
= hash_lookup (nst_method_hash_list
, sel_name
)))
5020 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5022 if (!(method_prototype
= check_duplicates (hsh
)))
5023 warning ("return type defaults to id");
5030 /* We think we have an instance...loophole: extern id Object; */
5031 hsh
= hash_lookup (nst_method_hash_list
, sel_name
);
5034 /* For various loopholes */
5035 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5037 method_prototype
= check_duplicates (hsh
);
5038 if (!method_prototype
)
5040 warning ("cannot find method");
5041 warning ("return type for `%s' defaults to id",
5042 IDENTIFIER_POINTER (sel_name
));
5046 /* Save the selector name for printing error messages. */
5047 building_objc_message_expr
= sel_name
;
5049 /* Build the parameters list for looking up the method.
5050 These are the object itself and the selector. */
5052 if (flag_typed_selectors
)
5053 selector
= build_typed_selector_reference (sel_name
, method_prototype
);
5055 selector
= build_selector_reference (sel_name
);
5057 retval
= build_objc_method_call (super
, method_prototype
,
5058 receiver
, self_object
,
5059 selector
, method_params
);
5061 building_objc_message_expr
= 0;
5066 /* Build a tree expression to send OBJECT the operation SELECTOR,
5067 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5068 assuming the method has prototype METHOD_PROTOTYPE.
5069 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5070 Use METHOD_PARAMS as list of args to pass to the method.
5071 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5074 build_objc_method_call (super_flag
, method_prototype
, lookup_object
, object
,
5075 selector
, method_params
)
5077 tree method_prototype
, lookup_object
, object
, selector
, method_params
;
5079 tree sender
= (super_flag
? umsg_super_decl
: umsg_decl
);
5080 tree rcv_p
= (super_flag
5081 ? build_pointer_type (xref_tag (RECORD_TYPE
,
5082 get_identifier (TAG_SUPER
)))
5085 if (flag_next_runtime
)
5087 if (! method_prototype
)
5089 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5090 tree_cons (NULL_TREE
, selector
,
5092 assemble_external (sender
);
5093 return build_function_call (sender
, method_params
);
5097 /* This is a real kludge, but it is used only for the Next.
5098 Clobber the data type of SENDER temporarily to accept
5099 all the arguments for this operation, and to return
5100 whatever this operation returns. */
5101 tree arglist
= NULL_TREE
, retval
, savarg
, savret
;
5102 tree ret_type
= groktypename (TREE_TYPE (method_prototype
));
5104 /* Save the proper contents of SENDER's data type. */
5105 savarg
= TYPE_ARG_TYPES (TREE_TYPE (sender
));
5106 savret
= TREE_TYPE (TREE_TYPE (sender
));
5108 /* Install this method's argument types. */
5109 arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5111 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = arglist
;
5113 /* Install this method's return type. */
5114 TREE_TYPE (TREE_TYPE (sender
)) = ret_type
;
5116 /* Call SENDER with all the parameters. This will do type
5117 checking using the arg types for this method. */
5118 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5119 tree_cons (NULL_TREE
, selector
,
5121 assemble_external (sender
);
5122 retval
= build_function_call (sender
, method_params
);
5124 /* Restore SENDER's return/argument types. */
5125 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = savarg
;
5126 TREE_TYPE (TREE_TYPE (sender
)) = savret
;
5132 /* This is the portable way.
5133 First call the lookup function to get a pointer to the method,
5134 then cast the pointer, then call it with the method arguments. */
5137 /* Avoid trouble since we may evaluate each of these twice. */
5138 object
= save_expr (object
);
5139 selector
= save_expr (selector
);
5141 lookup_object
= build_c_cast (rcv_p
, lookup_object
);
5143 assemble_external (sender
);
5145 = build_function_call (sender
,
5146 tree_cons (NULL_TREE
, lookup_object
,
5147 tree_cons (NULL_TREE
, selector
,
5150 /* If we have a method prototype, construct the data type this
5151 method needs, and cast what we got from SENDER into a pointer
5153 if (method_prototype
)
5155 tree arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5157 tree valtype
= groktypename (TREE_TYPE (method_prototype
));
5158 tree fake_function_type
= build_function_type (valtype
, arglist
);
5159 TREE_TYPE (method
) = build_pointer_type (fake_function_type
);
5163 = build_pointer_type (build_function_type (ptr_type_node
, NULL_TREE
));
5165 /* Pass the object to the method. */
5166 assemble_external (method
);
5167 return build_function_call (method
,
5168 tree_cons (NULL_TREE
, object
,
5169 tree_cons (NULL_TREE
, selector
,
5175 build_protocol_reference (p
)
5178 tree decl
, ident
, ptype
;
5180 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5182 ident
= synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
);
5184 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
5185 objc_protocol_template
),
5188 if (IDENTIFIER_GLOBAL_VALUE (ident
))
5189 decl
= IDENTIFIER_GLOBAL_VALUE (ident
); /* Set by pushdecl. */
5192 decl
= build_decl (VAR_DECL
, ident
, ptype
);
5193 DECL_EXTERNAL (decl
) = 1;
5194 TREE_PUBLIC (decl
) = 1;
5195 TREE_USED (decl
) = 1;
5196 DECL_ARTIFICIAL (decl
) = 1;
5198 make_decl_rtl (decl
, 0);
5199 pushdecl_top_level (decl
);
5202 PROTOCOL_FORWARD_DECL (p
) = decl
;
5206 build_protocol_expr (protoname
)
5210 tree p
= lookup_protocol (protoname
);
5214 error ("cannot find protocol declaration for `%s'",
5215 IDENTIFIER_POINTER (protoname
));
5216 return error_mark_node
;
5219 if (!PROTOCOL_FORWARD_DECL (p
))
5220 build_protocol_reference (p
);
5222 expr
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
5224 TREE_TYPE (expr
) = protocol_type
;
5230 build_selector_expr (selnamelist
)
5235 /* Obtain the full selector name. */
5236 if (TREE_CODE (selnamelist
) == IDENTIFIER_NODE
)
5237 /* A unary selector. */
5238 selname
= selnamelist
;
5239 else if (TREE_CODE (selnamelist
) == TREE_LIST
)
5240 selname
= build_keyword_selector (selnamelist
);
5244 if (flag_typed_selectors
)
5245 return build_typed_selector_reference (selname
, 0);
5247 return build_selector_reference (selname
);
5251 build_encode_expr (type
)
5257 encode_type (type
, obstack_object_size (&util_obstack
),
5258 OBJC_ENCODE_INLINE_DEFS
);
5259 obstack_1grow (&util_obstack
, 0); /* null terminate string */
5260 string
= obstack_finish (&util_obstack
);
5262 /* Synthesize a string that represents the encoded struct/union. */
5263 result
= my_build_string (strlen (string
) + 1, string
);
5264 obstack_free (&util_obstack
, util_firstobj
);
5269 build_ivar_reference (id
)
5272 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
5274 /* Historically, a class method that produced objects (factory
5275 method) would assign `self' to the instance that it
5276 allocated. This would effectively turn the class method into
5277 an instance method. Following this assignment, the instance
5278 variables could be accessed. That practice, while safe,
5279 violates the simple rule that a class method should not refer
5280 to an instance variable. It's better to catch the cases
5281 where this is done unknowingly than to support the above
5283 warning ("instance variable `%s' accessed in class method",
5284 IDENTIFIER_POINTER (id
));
5285 TREE_TYPE (self_decl
) = instance_type
; /* cast */
5288 return build_component_ref (build_indirect_ref (self_decl
, "->"), id
);
5291 /* Compute a hash value for a given method SEL_NAME. */
5294 hash_func (sel_name
)
5297 const unsigned char *s
5298 = (const unsigned char *)IDENTIFIER_POINTER (sel_name
);
5302 h
= h
* 67 + *s
++ - 113;
5309 nst_method_hash_list
= (hash
*) xcalloc (SIZEHASHTABLE
, sizeof (hash
));
5310 cls_method_hash_list
= (hash
*) xcalloc (SIZEHASHTABLE
, sizeof (hash
));
5313 /* WARNING!!!! hash_enter is called with a method, and will peek
5314 inside to find its selector! But hash_lookup is given a selector
5315 directly, and looks for the selector that's inside the found
5316 entry's key (method) for comparison. */
5319 hash_enter (hashlist
, method
)
5323 static hash hash_alloc_list
= 0;
5324 static int hash_alloc_index
= 0;
5326 int slot
= hash_func (METHOD_SEL_NAME (method
)) % SIZEHASHTABLE
;
5328 if (! hash_alloc_list
|| hash_alloc_index
>= HASH_ALLOC_LIST_SIZE
)
5330 hash_alloc_index
= 0;
5331 hash_alloc_list
= (hash
) xmalloc (sizeof (struct hashed_entry
)
5332 * HASH_ALLOC_LIST_SIZE
);
5334 obj
= &hash_alloc_list
[hash_alloc_index
++];
5336 obj
->next
= hashlist
[slot
];
5339 hashlist
[slot
] = obj
; /* append to front */
5343 hash_lookup (hashlist
, sel_name
)
5349 target
= hashlist
[hash_func (sel_name
) % SIZEHASHTABLE
];
5353 if (sel_name
== METHOD_SEL_NAME (target
->key
))
5356 target
= target
->next
;
5362 hash_add_attr (entry
, value
)
5366 static attr attr_alloc_list
= 0;
5367 static int attr_alloc_index
= 0;
5370 if (! attr_alloc_list
|| attr_alloc_index
>= ATTR_ALLOC_LIST_SIZE
)
5372 attr_alloc_index
= 0;
5373 attr_alloc_list
= (attr
) xmalloc (sizeof (struct hashed_attribute
)
5374 * ATTR_ALLOC_LIST_SIZE
);
5376 obj
= &attr_alloc_list
[attr_alloc_index
++];
5377 obj
->next
= entry
->list
;
5380 entry
->list
= obj
; /* append to front */
5384 lookup_method (mchain
, method
)
5390 if (TREE_CODE (method
) == IDENTIFIER_NODE
)
5393 key
= METHOD_SEL_NAME (method
);
5397 if (METHOD_SEL_NAME (mchain
) == key
)
5399 mchain
= TREE_CHAIN (mchain
);
5405 lookup_instance_method_static (interface
, ident
)
5409 tree inter
= interface
;
5410 tree chain
= CLASS_NST_METHODS (inter
);
5411 tree meth
= NULL_TREE
;
5415 if ((meth
= lookup_method (chain
, ident
)))
5418 if (CLASS_CATEGORY_LIST (inter
))
5420 tree category
= CLASS_CATEGORY_LIST (inter
);
5421 chain
= CLASS_NST_METHODS (category
);
5425 if ((meth
= lookup_method (chain
, ident
)))
5428 /* Check for instance methods in protocols in categories. */
5429 if (CLASS_PROTOCOL_LIST (category
))
5431 if ((meth
= (lookup_method_in_protocol_list
5432 (CLASS_PROTOCOL_LIST (category
), ident
, 0))))
5436 if ((category
= CLASS_CATEGORY_LIST (category
)))
5437 chain
= CLASS_NST_METHODS (category
);
5442 if (CLASS_PROTOCOL_LIST (inter
))
5444 if ((meth
= (lookup_method_in_protocol_list
5445 (CLASS_PROTOCOL_LIST (inter
), ident
, 0))))
5449 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5450 chain
= CLASS_NST_METHODS (inter
);
5458 lookup_class_method_static (interface
, ident
)
5462 tree inter
= interface
;
5463 tree chain
= CLASS_CLS_METHODS (inter
);
5464 tree meth
= NULL_TREE
;
5465 tree root_inter
= NULL_TREE
;
5469 if ((meth
= lookup_method (chain
, ident
)))
5472 if (CLASS_CATEGORY_LIST (inter
))
5474 tree category
= CLASS_CATEGORY_LIST (inter
);
5475 chain
= CLASS_CLS_METHODS (category
);
5479 if ((meth
= lookup_method (chain
, ident
)))
5482 /* Check for class methods in protocols in categories. */
5483 if (CLASS_PROTOCOL_LIST (category
))
5485 if ((meth
= (lookup_method_in_protocol_list
5486 (CLASS_PROTOCOL_LIST (category
), ident
, 1))))
5490 if ((category
= CLASS_CATEGORY_LIST (category
)))
5491 chain
= CLASS_CLS_METHODS (category
);
5496 /* Check for class methods in protocols. */
5497 if (CLASS_PROTOCOL_LIST (inter
))
5499 if ((meth
= (lookup_method_in_protocol_list
5500 (CLASS_PROTOCOL_LIST (inter
), ident
, 1))))
5505 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5506 chain
= CLASS_CLS_METHODS (inter
);
5510 /* If no class (factory) method was found, check if an _instance_
5511 method of the same name exists in the root class. This is what
5512 the Objective-C runtime will do. */
5513 return lookup_instance_method_static (root_inter
, ident
);
5517 add_class_method (class, method
)
5524 if (!(mth
= lookup_method (CLASS_CLS_METHODS (class), method
)))
5526 /* put method on list in reverse order */
5527 TREE_CHAIN (method
) = CLASS_CLS_METHODS (class);
5528 CLASS_CLS_METHODS (class) = method
;
5532 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5533 error ("duplicate definition of class method `%s'",
5534 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5537 /* Check types; if different, complain. */
5538 if (!comp_proto_with_proto (method
, mth
))
5539 error ("duplicate declaration of class method `%s'",
5540 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5544 if (!(hsh
= hash_lookup (cls_method_hash_list
, METHOD_SEL_NAME (method
))))
5546 /* Install on a global chain. */
5547 hash_enter (cls_method_hash_list
, method
);
5551 /* Check types; if different, add to a list. */
5552 if (!comp_proto_with_proto (method
, hsh
->key
))
5553 hash_add_attr (hsh
, method
);
5559 add_instance_method (class, method
)
5566 if (!(mth
= lookup_method (CLASS_NST_METHODS (class), method
)))
5568 /* Put method on list in reverse order. */
5569 TREE_CHAIN (method
) = CLASS_NST_METHODS (class);
5570 CLASS_NST_METHODS (class) = method
;
5574 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5575 error ("duplicate definition of instance method `%s'",
5576 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5579 /* Check types; if different, complain. */
5580 if (!comp_proto_with_proto (method
, mth
))
5581 error ("duplicate declaration of instance method `%s'",
5582 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5586 if (!(hsh
= hash_lookup (nst_method_hash_list
, METHOD_SEL_NAME (method
))))
5588 /* Install on a global chain. */
5589 hash_enter (nst_method_hash_list
, method
);
5593 /* Check types; if different, add to a list. */
5594 if (!comp_proto_with_proto (method
, hsh
->key
))
5595 hash_add_attr (hsh
, method
);
5604 /* Put interfaces on list in reverse order. */
5605 TREE_CHAIN (class) = interface_chain
;
5606 interface_chain
= class;
5607 return interface_chain
;
5611 add_category (class, category
)
5615 /* Put categories on list in reverse order. */
5616 tree cat
= CLASS_CATEGORY_LIST (class);
5620 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
5621 warning ("duplicate interface declaration for category `%s(%s)'",
5622 IDENTIFIER_POINTER (CLASS_NAME (class)),
5623 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category
)));
5624 cat
= CLASS_CATEGORY_LIST (cat
);
5627 CLASS_CATEGORY_LIST (category
) = CLASS_CATEGORY_LIST (class);
5628 CLASS_CATEGORY_LIST (class) = category
;
5631 /* Called after parsing each instance variable declaration. Necessary to
5632 preserve typedefs and implement public/private...
5634 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5637 add_instance_variable (class, public, declarator
, declspecs
, width
)
5644 tree field_decl
, raw_decl
;
5646 raw_decl
= build_tree_list (declspecs
, declarator
);
5648 if (CLASS_RAW_IVARS (class))
5649 chainon (CLASS_RAW_IVARS (class), raw_decl
);
5651 CLASS_RAW_IVARS (class) = raw_decl
;
5653 field_decl
= grokfield (input_filename
, lineno
,
5654 declarator
, declspecs
, width
);
5656 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5660 TREE_PUBLIC (field_decl
) = 0;
5661 TREE_PRIVATE (field_decl
) = 0;
5662 TREE_PROTECTED (field_decl
) = 1;
5666 TREE_PUBLIC (field_decl
) = 1;
5667 TREE_PRIVATE (field_decl
) = 0;
5668 TREE_PROTECTED (field_decl
) = 0;
5672 TREE_PUBLIC (field_decl
) = 0;
5673 TREE_PRIVATE (field_decl
) = 1;
5674 TREE_PROTECTED (field_decl
) = 0;
5679 if (CLASS_IVARS (class))
5680 chainon (CLASS_IVARS (class), field_decl
);
5682 CLASS_IVARS (class) = field_decl
;
5688 is_ivar (decl_chain
, ident
)
5692 for ( ; decl_chain
; decl_chain
= TREE_CHAIN (decl_chain
))
5693 if (DECL_NAME (decl_chain
) == ident
)
5698 /* True if the ivar is private and we are not in its implementation. */
5704 if (TREE_PRIVATE (decl
)
5705 && ! is_ivar (CLASS_IVARS (implementation_template
), DECL_NAME (decl
)))
5707 error ("instance variable `%s' is declared private",
5708 IDENTIFIER_POINTER (DECL_NAME (decl
)));
5715 /* We have an instance variable reference;, check to see if it is public. */
5718 is_public (expr
, identifier
)
5722 tree basetype
= TREE_TYPE (expr
);
5723 enum tree_code code
= TREE_CODE (basetype
);
5726 if (code
== RECORD_TYPE
)
5728 if (TREE_STATIC_TEMPLATE (basetype
))
5730 if (!lookup_interface (TYPE_NAME (basetype
)))
5732 error ("cannot find interface declaration for `%s'",
5733 IDENTIFIER_POINTER (TYPE_NAME (basetype
)));
5737 if ((decl
= is_ivar (TYPE_FIELDS (basetype
), identifier
)))
5739 if (TREE_PUBLIC (decl
))
5742 /* Important difference between the Stepstone translator:
5743 all instance variables should be public within the context
5744 of the implementation. */
5745 if (objc_implementation_context
5746 && (((TREE_CODE (objc_implementation_context
)
5747 == CLASS_IMPLEMENTATION_TYPE
)
5748 || (TREE_CODE (objc_implementation_context
)
5749 == CATEGORY_IMPLEMENTATION_TYPE
))
5750 && (CLASS_NAME (objc_implementation_context
)
5751 == TYPE_NAME (basetype
))))
5752 return ! is_private (decl
);
5754 error ("instance variable `%s' is declared %s",
5755 IDENTIFIER_POINTER (identifier
),
5756 TREE_PRIVATE (decl
) ? "private" : "protected");
5761 else if (objc_implementation_context
&& (basetype
== objc_object_reference
))
5763 TREE_TYPE (expr
) = uprivate_record
;
5764 warning ("static access to object of type `id'");
5771 /* Implement @defs (<classname>) within struct bodies. */
5774 get_class_ivars (interface
)
5777 /* Make sure we copy the leaf ivars in case @defs is used in a local
5778 context. Otherwise finish_struct will overwrite the layout info
5779 using temporary storage. */
5780 return build_ivar_chain (interface
, 1);
5783 /* Make sure all entries in CHAIN are also in LIST. */
5786 check_methods (chain
, list
, mtype
)
5795 if (!lookup_method (list
, chain
))
5799 if (TREE_CODE (objc_implementation_context
)
5800 == CLASS_IMPLEMENTATION_TYPE
)
5801 warning ("incomplete implementation of class `%s'",
5802 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
)));
5803 else if (TREE_CODE (objc_implementation_context
)
5804 == CATEGORY_IMPLEMENTATION_TYPE
)
5805 warning ("incomplete implementation of category `%s'",
5806 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
5810 warning ("method definition for `%c%s' not found",
5811 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
5814 chain
= TREE_CHAIN (chain
);
5820 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
5823 conforms_to_protocol (class, protocol
)
5827 if (TREE_CODE (protocol
) == PROTOCOL_INTERFACE_TYPE
)
5829 tree p
= CLASS_PROTOCOL_LIST (class);
5830 while (p
&& TREE_VALUE (p
) != protocol
)
5835 tree super
= (CLASS_SUPER_NAME (class)
5836 ? lookup_interface (CLASS_SUPER_NAME (class))
5838 int tmp
= super
? conforms_to_protocol (super
, protocol
) : 0;
5847 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5848 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5851 check_methods_accessible (chain
, context
, mtype
)
5858 tree base_context
= context
;
5862 context
= base_context
;
5866 list
= CLASS_CLS_METHODS (context
);
5868 list
= CLASS_NST_METHODS (context
);
5870 if (lookup_method (list
, chain
))
5873 else if (TREE_CODE (context
) == CLASS_IMPLEMENTATION_TYPE
5874 || TREE_CODE (context
) == CLASS_INTERFACE_TYPE
)
5875 context
= (CLASS_SUPER_NAME (context
)
5876 ? lookup_interface (CLASS_SUPER_NAME (context
))
5879 else if (TREE_CODE (context
) == CATEGORY_IMPLEMENTATION_TYPE
5880 || TREE_CODE (context
) == CATEGORY_INTERFACE_TYPE
)
5881 context
= (CLASS_NAME (context
)
5882 ? lookup_interface (CLASS_NAME (context
))
5888 if (context
== NULL_TREE
)
5892 if (TREE_CODE (objc_implementation_context
)
5893 == CLASS_IMPLEMENTATION_TYPE
)
5894 warning ("incomplete implementation of class `%s'",
5896 (CLASS_NAME (objc_implementation_context
)));
5897 else if (TREE_CODE (objc_implementation_context
)
5898 == CATEGORY_IMPLEMENTATION_TYPE
)
5899 warning ("incomplete implementation of category `%s'",
5901 (CLASS_SUPER_NAME (objc_implementation_context
)));
5904 warning ("method definition for `%c%s' not found",
5905 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
5908 chain
= TREE_CHAIN (chain
); /* next method... */
5913 /* Check whether the current interface (accessible via
5914 'objc_implementation_context') actually implements protocol P, along
5915 with any protocols that P inherits. */
5918 check_protocol (p
, type
, name
)
5923 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
5927 /* Ensure that all protocols have bodies! */
5928 if (flag_warn_protocol
)
5930 f1
= check_methods (PROTOCOL_CLS_METHODS (p
),
5931 CLASS_CLS_METHODS (objc_implementation_context
),
5933 f2
= check_methods (PROTOCOL_NST_METHODS (p
),
5934 CLASS_NST_METHODS (objc_implementation_context
),
5939 f1
= check_methods_accessible (PROTOCOL_CLS_METHODS (p
),
5940 objc_implementation_context
,
5942 f2
= check_methods_accessible (PROTOCOL_NST_METHODS (p
),
5943 objc_implementation_context
,
5948 warning ("%s `%s' does not fully implement the `%s' protocol",
5949 type
, name
, IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
5952 /* Check protocols recursively. */
5953 if (PROTOCOL_LIST (p
))
5955 tree subs
= PROTOCOL_LIST (p
);
5957 lookup_interface (CLASS_SUPER_NAME (implementation_template
));
5960 tree sub
= TREE_VALUE (subs
);
5962 /* If the superclass does not conform to the protocols
5963 inherited by P, then we must! */
5964 if (!super_class
|| !conforms_to_protocol (super_class
, sub
))
5965 check_protocol (sub
, type
, name
);
5966 subs
= TREE_CHAIN (subs
);
5971 /* Check whether the current interface (accessible via
5972 'objc_implementation_context') actually implements the protocols listed
5976 check_protocols (proto_list
, type
, name
)
5981 for ( ; proto_list
; proto_list
= TREE_CHAIN (proto_list
))
5983 tree p
= TREE_VALUE (proto_list
);
5985 check_protocol (p
, type
, name
);
5989 /* Make sure that the class CLASS_NAME is defined
5990 CODE says which kind of thing CLASS_NAME ought to be.
5991 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
5992 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
5995 start_class (code
, class_name
, super_name
, protocol_list
)
5996 enum tree_code code
;
6003 if (objc_implementation_context
)
6005 warning ("`@end' missing in implementation context");
6006 finish_class (objc_implementation_context
);
6007 objc_ivar_chain
= NULL_TREE
;
6008 objc_implementation_context
= NULL_TREE
;
6011 class = make_node (code
);
6012 TYPE_BINFO (class) = make_tree_vec (5);
6014 CLASS_NAME (class) = class_name
;
6015 CLASS_SUPER_NAME (class) = super_name
;
6016 CLASS_CLS_METHODS (class) = NULL_TREE
;
6018 if (! is_class_name (class_name
) && (decl
= lookup_name (class_name
)))
6020 error ("`%s' redeclared as different kind of symbol",
6021 IDENTIFIER_POINTER (class_name
));
6022 error_with_decl (decl
, "previous declaration of `%s'");
6025 if (code
== CLASS_IMPLEMENTATION_TYPE
)
6030 for (chain
= implemented_classes
; chain
; chain
= TREE_CHAIN (chain
))
6031 if (TREE_VALUE (chain
) == class_name
)
6033 error ("reimplementation of class `%s'",
6034 IDENTIFIER_POINTER (class_name
));
6035 return error_mark_node
;
6037 implemented_classes
= tree_cons (NULL_TREE
, class_name
,
6038 implemented_classes
);
6041 /* Pre-build the following entities - for speed/convenience. */
6043 self_id
= get_identifier ("self");
6045 ucmd_id
= get_identifier ("_cmd");
6048 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6049 if (!objc_super_template
)
6050 objc_super_template
= build_super_template ();
6052 /* Reset for multiple classes per file. */
6055 objc_implementation_context
= class;
6057 /* Lookup the interface for this implementation. */
6059 if (!(implementation_template
= lookup_interface (class_name
)))
6061 warning ("cannot find interface declaration for `%s'",
6062 IDENTIFIER_POINTER (class_name
));
6063 add_class (implementation_template
= objc_implementation_context
);
6066 /* If a super class has been specified in the implementation,
6067 insure it conforms to the one specified in the interface. */
6070 && (super_name
!= CLASS_SUPER_NAME (implementation_template
)))
6072 tree previous_name
= CLASS_SUPER_NAME (implementation_template
);
6073 const char *const name
=
6074 previous_name
? IDENTIFIER_POINTER (previous_name
) : "";
6075 error ("conflicting super class name `%s'",
6076 IDENTIFIER_POINTER (super_name
));
6077 error ("previous declaration of `%s'", name
);
6080 else if (! super_name
)
6082 CLASS_SUPER_NAME (objc_implementation_context
)
6083 = CLASS_SUPER_NAME (implementation_template
);
6087 else if (code
== CLASS_INTERFACE_TYPE
)
6089 if (lookup_interface (class_name
))
6090 warning ("duplicate interface declaration for class `%s'",
6091 IDENTIFIER_POINTER (class_name
));
6096 CLASS_PROTOCOL_LIST (class)
6097 = lookup_and_install_protocols (protocol_list
);
6100 else if (code
== CATEGORY_INTERFACE_TYPE
)
6102 tree class_category_is_assoc_with
;
6104 /* For a category, class_name is really the name of the class that
6105 the following set of methods will be associated with. We must
6106 find the interface so that can derive the objects template. */
6108 if (!(class_category_is_assoc_with
= lookup_interface (class_name
)))
6110 error ("cannot find interface declaration for `%s'",
6111 IDENTIFIER_POINTER (class_name
));
6112 exit (FATAL_EXIT_CODE
);
6115 add_category (class_category_is_assoc_with
, class);
6118 CLASS_PROTOCOL_LIST (class)
6119 = lookup_and_install_protocols (protocol_list
);
6122 else if (code
== CATEGORY_IMPLEMENTATION_TYPE
)
6124 /* Pre-build the following entities for speed/convenience. */
6126 self_id
= get_identifier ("self");
6128 ucmd_id
= get_identifier ("_cmd");
6131 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6132 if (!objc_super_template
)
6133 objc_super_template
= build_super_template ();
6135 /* Reset for multiple classes per file. */
6138 objc_implementation_context
= class;
6140 /* For a category, class_name is really the name of the class that
6141 the following set of methods will be associated with. We must
6142 find the interface so that can derive the objects template. */
6144 if (!(implementation_template
= lookup_interface (class_name
)))
6146 error ("cannot find interface declaration for `%s'",
6147 IDENTIFIER_POINTER (class_name
));
6148 exit (FATAL_EXIT_CODE
);
6155 continue_class (class)
6158 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6159 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6161 struct imp_entry
*imp_entry
;
6164 /* Check consistency of the instance variables. */
6166 if (CLASS_IVARS (class))
6167 check_ivars (implementation_template
, class);
6169 /* code generation */
6171 ivar_context
= build_private_template (implementation_template
);
6173 if (!objc_class_template
)
6174 build_class_template ();
6176 imp_entry
= (struct imp_entry
*) xmalloc (sizeof (struct imp_entry
));
6178 imp_entry
->next
= imp_list
;
6179 imp_entry
->imp_context
= class;
6180 imp_entry
->imp_template
= implementation_template
;
6182 synth_forward_declarations ();
6183 imp_entry
->class_decl
= UOBJC_CLASS_decl
;
6184 imp_entry
->meta_decl
= UOBJC_METACLASS_decl
;
6186 /* Append to front and increment count. */
6187 imp_list
= imp_entry
;
6188 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6193 return ivar_context
;
6196 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6198 tree record
= xref_tag (RECORD_TYPE
, CLASS_NAME (class));
6200 if (!TYPE_FIELDS (record
))
6202 finish_struct (record
, build_ivar_chain (class, 0), NULL_TREE
);
6203 CLASS_STATIC_TEMPLATE (class) = record
;
6205 /* Mark this record as a class template for static typing. */
6206 TREE_STATIC_TEMPLATE (record
) = 1;
6213 return error_mark_node
;
6216 /* This is called once we see the "@end" in an interface/implementation. */
6219 finish_class (class)
6222 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6224 /* All code generation is done in finish_objc. */
6226 if (implementation_template
!= objc_implementation_context
)
6228 /* Ensure that all method listed in the interface contain bodies. */
6229 check_methods (CLASS_CLS_METHODS (implementation_template
),
6230 CLASS_CLS_METHODS (objc_implementation_context
), '+');
6231 check_methods (CLASS_NST_METHODS (implementation_template
),
6232 CLASS_NST_METHODS (objc_implementation_context
), '-');
6234 if (CLASS_PROTOCOL_LIST (implementation_template
))
6235 check_protocols (CLASS_PROTOCOL_LIST (implementation_template
),
6237 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
)));
6241 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6243 tree category
= CLASS_CATEGORY_LIST (implementation_template
);
6245 /* Find the category interface from the class it is associated with. */
6248 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category
))
6250 category
= CLASS_CATEGORY_LIST (category
);
6255 /* Ensure all method listed in the interface contain bodies. */
6256 check_methods (CLASS_CLS_METHODS (category
),
6257 CLASS_CLS_METHODS (objc_implementation_context
), '+');
6258 check_methods (CLASS_NST_METHODS (category
),
6259 CLASS_NST_METHODS (objc_implementation_context
), '-');
6261 if (CLASS_PROTOCOL_LIST (category
))
6262 check_protocols (CLASS_PROTOCOL_LIST (category
),
6264 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
6268 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6271 const char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (class));
6272 char *string
= (char *) alloca (strlen (class_name
) + 3);
6274 /* extern struct objc_object *_<my_name>; */
6276 sprintf (string
, "_%s", class_name
);
6278 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
6279 decl_specs
= tree_cons (NULL_TREE
, objc_object_reference
, decl_specs
);
6280 define_decl (build1 (INDIRECT_REF
, NULL_TREE
, get_identifier (string
)),
6286 add_protocol (protocol
)
6289 /* Put protocol on list in reverse order. */
6290 TREE_CHAIN (protocol
) = protocol_chain
;
6291 protocol_chain
= protocol
;
6292 return protocol_chain
;
6296 lookup_protocol (ident
)
6301 for (chain
= protocol_chain
; chain
; chain
= TREE_CHAIN (chain
))
6303 if (ident
== PROTOCOL_NAME (chain
))
6310 /* This function forward declares the protocols named by NAMES. If
6311 they are already declared or defined, the function has no effect. */
6314 objc_declare_protocols (names
)
6319 for (list
= names
; list
; list
= TREE_CHAIN (list
))
6321 tree name
= TREE_VALUE (list
);
6323 if (lookup_protocol (name
) == NULL_TREE
)
6325 tree protocol
= make_node (PROTOCOL_INTERFACE_TYPE
);
6327 TYPE_BINFO (protocol
) = make_tree_vec (2);
6328 PROTOCOL_NAME (protocol
) = name
;
6329 PROTOCOL_LIST (protocol
) = NULL_TREE
;
6330 add_protocol (protocol
);
6331 PROTOCOL_DEFINED (protocol
) = 0;
6332 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6338 start_protocol (code
, name
, list
)
6339 enum tree_code code
;
6345 /* This is as good a place as any. Need to invoke
6346 push_tag_toplevel. */
6347 if (!objc_protocol_template
)
6348 objc_protocol_template
= build_protocol_template ();
6350 protocol
= lookup_protocol (name
);
6354 protocol
= make_node (code
);
6355 TYPE_BINFO (protocol
) = make_tree_vec (2);
6357 PROTOCOL_NAME (protocol
) = name
;
6358 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
6359 add_protocol (protocol
);
6360 PROTOCOL_DEFINED (protocol
) = 1;
6361 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6363 check_protocol_recursively (protocol
, list
);
6365 else if (! PROTOCOL_DEFINED (protocol
))
6367 PROTOCOL_DEFINED (protocol
) = 1;
6368 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
6370 check_protocol_recursively (protocol
, list
);
6374 warning ("duplicate declaration for protocol `%s'",
6375 IDENTIFIER_POINTER (name
));
6381 finish_protocol (protocol
)
6382 tree protocol ATTRIBUTE_UNUSED
;
6387 /* "Encode" a data type into a string, which grows in util_obstack.
6388 ??? What is the FORMAT? Someone please document this! */
6391 encode_type_qualifiers (declspecs
)
6396 for (spec
= declspecs
; spec
; spec
= TREE_CHAIN (spec
))
6398 if (ridpointers
[(int) RID_CONST
] == TREE_VALUE (spec
))
6399 obstack_1grow (&util_obstack
, 'r');
6400 else if (ridpointers
[(int) RID_IN
] == TREE_VALUE (spec
))
6401 obstack_1grow (&util_obstack
, 'n');
6402 else if (ridpointers
[(int) RID_INOUT
] == TREE_VALUE (spec
))
6403 obstack_1grow (&util_obstack
, 'N');
6404 else if (ridpointers
[(int) RID_OUT
] == TREE_VALUE (spec
))
6405 obstack_1grow (&util_obstack
, 'o');
6406 else if (ridpointers
[(int) RID_BYCOPY
] == TREE_VALUE (spec
))
6407 obstack_1grow (&util_obstack
, 'O');
6408 else if (ridpointers
[(int) RID_BYREF
] == TREE_VALUE (spec
))
6409 obstack_1grow (&util_obstack
, 'R');
6410 else if (ridpointers
[(int) RID_ONEWAY
] == TREE_VALUE (spec
))
6411 obstack_1grow (&util_obstack
, 'V');
6415 /* Encode a pointer type. */
6418 encode_pointer (type
, curtype
, format
)
6423 tree pointer_to
= TREE_TYPE (type
);
6425 if (TREE_CODE (pointer_to
) == RECORD_TYPE
)
6427 if (TYPE_NAME (pointer_to
)
6428 && TREE_CODE (TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
)
6430 const char *name
= IDENTIFIER_POINTER (TYPE_NAME (pointer_to
));
6432 if (strcmp (name
, TAG_OBJECT
) == 0) /* '@' */
6434 obstack_1grow (&util_obstack
, '@');
6437 else if (TREE_STATIC_TEMPLATE (pointer_to
))
6439 if (generating_instance_variables
)
6441 obstack_1grow (&util_obstack
, '@');
6442 obstack_1grow (&util_obstack
, '"');
6443 obstack_grow (&util_obstack
, name
, strlen (name
));
6444 obstack_1grow (&util_obstack
, '"');
6449 obstack_1grow (&util_obstack
, '@');
6453 else if (strcmp (name
, TAG_CLASS
) == 0) /* '#' */
6455 obstack_1grow (&util_obstack
, '#');
6458 else if (strcmp (name
, TAG_SELECTOR
) == 0) /* ':' */
6460 obstack_1grow (&util_obstack
, ':');
6465 else if (TREE_CODE (pointer_to
) == INTEGER_TYPE
6466 && TYPE_MODE (pointer_to
) == QImode
)
6468 obstack_1grow (&util_obstack
, '*');
6472 /* We have a type that does not get special treatment. */
6474 /* NeXT extension */
6475 obstack_1grow (&util_obstack
, '^');
6476 encode_type (pointer_to
, curtype
, format
);
6480 encode_array (type
, curtype
, format
)
6485 tree an_int_cst
= TYPE_SIZE (type
);
6486 tree array_of
= TREE_TYPE (type
);
6489 /* An incomplete array is treated like a pointer. */
6490 if (an_int_cst
== NULL
)
6492 encode_pointer (type
, curtype
, format
);
6496 sprintf (buffer
, "[%ld",
6497 (long) (TREE_INT_CST_LOW (an_int_cst
)
6498 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
6500 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6501 encode_type (array_of
, curtype
, format
);
6502 obstack_1grow (&util_obstack
, ']');
6507 encode_aggregate_within (type
, curtype
, format
, left
, right
)
6514 /* The RECORD_TYPE may in fact be a typedef! For purposes
6515 of encoding, we need the real underlying enchilada. */
6516 if (TYPE_MAIN_VARIANT (type
))
6517 type
= TYPE_MAIN_VARIANT (type
);
6519 if (obstack_object_size (&util_obstack
) > 0
6520 && *(obstack_next_free (&util_obstack
) - 1) == '^')
6522 tree name
= TYPE_NAME (type
);
6524 /* we have a reference; this is a NeXT extension. */
6526 if (obstack_object_size (&util_obstack
) - curtype
== 1
6527 && format
== OBJC_ENCODE_INLINE_DEFS
)
6529 /* Output format of struct for first level only. */
6530 tree fields
= TYPE_FIELDS (type
);
6532 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6534 obstack_1grow (&util_obstack
, left
);
6535 obstack_grow (&util_obstack
,
6536 IDENTIFIER_POINTER (name
),
6537 strlen (IDENTIFIER_POINTER (name
)));
6538 obstack_1grow (&util_obstack
, '=');
6542 obstack_1grow (&util_obstack
, left
);
6543 obstack_grow (&util_obstack
, "?=", 2);
6546 for ( ; fields
; fields
= TREE_CHAIN (fields
))
6547 encode_field_decl (fields
, curtype
, format
);
6549 obstack_1grow (&util_obstack
, right
);
6552 else if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6554 obstack_1grow (&util_obstack
, left
);
6555 obstack_grow (&util_obstack
,
6556 IDENTIFIER_POINTER (name
),
6557 strlen (IDENTIFIER_POINTER (name
)));
6558 obstack_1grow (&util_obstack
, right
);
6563 /* We have an untagged structure or a typedef. */
6564 obstack_1grow (&util_obstack
, left
);
6565 obstack_1grow (&util_obstack
, '?');
6566 obstack_1grow (&util_obstack
, right
);
6572 tree name
= TYPE_NAME (type
);
6573 tree fields
= TYPE_FIELDS (type
);
6575 if (format
== OBJC_ENCODE_INLINE_DEFS
6576 || generating_instance_variables
)
6578 obstack_1grow (&util_obstack
, left
);
6579 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6580 obstack_grow (&util_obstack
,
6581 IDENTIFIER_POINTER (name
),
6582 strlen (IDENTIFIER_POINTER (name
)));
6584 obstack_1grow (&util_obstack
, '?');
6586 obstack_1grow (&util_obstack
, '=');
6588 for (; fields
; fields
= TREE_CHAIN (fields
))
6590 if (generating_instance_variables
)
6592 tree fname
= DECL_NAME (fields
);
6594 obstack_1grow (&util_obstack
, '"');
6595 if (fname
&& TREE_CODE (fname
) == IDENTIFIER_NODE
)
6597 obstack_grow (&util_obstack
,
6598 IDENTIFIER_POINTER (fname
),
6599 strlen (IDENTIFIER_POINTER (fname
)));
6602 obstack_1grow (&util_obstack
, '"');
6605 encode_field_decl (fields
, curtype
, format
);
6608 obstack_1grow (&util_obstack
, right
);
6613 obstack_1grow (&util_obstack
, left
);
6614 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6615 obstack_grow (&util_obstack
,
6616 IDENTIFIER_POINTER (name
),
6617 strlen (IDENTIFIER_POINTER (name
)));
6619 /* We have an untagged structure or a typedef. */
6620 obstack_1grow (&util_obstack
, '?');
6622 obstack_1grow (&util_obstack
, right
);
6628 encode_aggregate (type
, curtype
, format
)
6633 enum tree_code code
= TREE_CODE (type
);
6639 encode_aggregate_within(type
, curtype
, format
, '{', '}');
6644 encode_aggregate_within(type
, curtype
, format
, '(', ')');
6649 obstack_1grow (&util_obstack
, 'i');
6657 /* Support bitfields. The current version of Objective-C does not support
6658 them. The string will consist of one or more "b:n"'s where n is an
6659 integer describing the width of the bitfield. Currently, classes in
6660 the kit implement a method "-(char *)describeBitfieldStruct:" that
6661 simulates this. If they do not implement this method, the archiver
6662 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6663 according to the GNU compiler. After looking at the "kit", it appears
6664 that all classes currently rely on this default behavior, rather than
6665 hand generating this string (which is tedious). */
6668 encode_bitfield (width
)
6672 sprintf (buffer
, "b%d", width
);
6673 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6676 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6679 encode_type (type
, curtype
, format
)
6684 enum tree_code code
= TREE_CODE (type
);
6686 if (code
== INTEGER_TYPE
)
6688 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6690 /* Unsigned integer types. */
6692 if (TYPE_MODE (type
) == QImode
)
6693 obstack_1grow (&util_obstack
, 'C');
6694 else if (TYPE_MODE (type
) == HImode
)
6695 obstack_1grow (&util_obstack
, 'S');
6696 else if (TYPE_MODE (type
) == SImode
)
6698 if (type
== long_unsigned_type_node
)
6699 obstack_1grow (&util_obstack
, 'L');
6701 obstack_1grow (&util_obstack
, 'I');
6703 else if (TYPE_MODE (type
) == DImode
)
6704 obstack_1grow (&util_obstack
, 'Q');
6708 /* Signed integer types. */
6710 if (TYPE_MODE (type
) == QImode
)
6711 obstack_1grow (&util_obstack
, 'c');
6712 else if (TYPE_MODE (type
) == HImode
)
6713 obstack_1grow (&util_obstack
, 's');
6714 else if (TYPE_MODE (type
) == SImode
)
6716 if (type
== long_integer_type_node
)
6717 obstack_1grow (&util_obstack
, 'l');
6719 obstack_1grow (&util_obstack
, 'i');
6722 else if (TYPE_MODE (type
) == DImode
)
6723 obstack_1grow (&util_obstack
, 'q');
6727 else if (code
== REAL_TYPE
)
6729 /* Floating point types. */
6731 if (TYPE_MODE (type
) == SFmode
)
6732 obstack_1grow (&util_obstack
, 'f');
6733 else if (TYPE_MODE (type
) == DFmode
6734 || TYPE_MODE (type
) == TFmode
)
6735 obstack_1grow (&util_obstack
, 'd');
6738 else if (code
== VOID_TYPE
)
6739 obstack_1grow (&util_obstack
, 'v');
6741 else if (code
== ARRAY_TYPE
)
6742 encode_array (type
, curtype
, format
);
6744 else if (code
== POINTER_TYPE
)
6745 encode_pointer (type
, curtype
, format
);
6747 else if (code
== RECORD_TYPE
|| code
== UNION_TYPE
|| code
== ENUMERAL_TYPE
)
6748 encode_aggregate (type
, curtype
, format
);
6750 else if (code
== FUNCTION_TYPE
) /* '?' */
6751 obstack_1grow (&util_obstack
, '?');
6755 encode_complete_bitfield (int position
, tree type
, int size
)
6757 enum tree_code code
= TREE_CODE (type
);
6759 char charType
= '?';
6761 if (code
== INTEGER_TYPE
)
6763 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6765 /* Unsigned integer types. */
6767 if (TYPE_MODE (type
) == QImode
)
6769 else if (TYPE_MODE (type
) == HImode
)
6771 else if (TYPE_MODE (type
) == SImode
)
6773 if (type
== long_unsigned_type_node
)
6778 else if (TYPE_MODE (type
) == DImode
)
6783 /* Signed integer types. */
6785 if (TYPE_MODE (type
) == QImode
)
6787 else if (TYPE_MODE (type
) == HImode
)
6789 else if (TYPE_MODE (type
) == SImode
)
6791 if (type
== long_integer_type_node
)
6797 else if (TYPE_MODE (type
) == DImode
)
6805 sprintf (buffer
, "b%d%c%d", position
, charType
, size
);
6806 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6810 encode_field_decl (field_decl
, curtype
, format
)
6817 type
= TREE_TYPE (field_decl
);
6819 /* If this field is obviously a bitfield, or is a bitfield that has been
6820 clobbered to look like a ordinary integer mode, go ahead and generate
6821 the bitfield typing information. */
6822 if (flag_next_runtime
)
6824 if (DECL_BIT_FIELD (field_decl
))
6825 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl
), 1));
6827 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6831 if (DECL_BIT_FIELD (field_decl
))
6832 encode_complete_bitfield (int_bit_position (field_decl
),
6833 DECL_BIT_FIELD_TYPE (field_decl
),
6834 tree_low_cst (DECL_SIZE (field_decl
), 1));
6836 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6841 expr_last (complex_expr
)
6847 while ((next
= TREE_OPERAND (complex_expr
, 0)))
6848 complex_expr
= next
;
6850 return complex_expr
;
6853 /* Transform a method definition into a function definition as follows:
6854 - synthesize the first two arguments, "self" and "_cmd". */
6857 start_method_def (method
)
6862 /* Required to implement _msgSuper. */
6863 objc_method_context
= method
;
6864 UOBJC_SUPER_decl
= NULL_TREE
;
6866 /* Must be called BEFORE start_function. */
6869 /* Generate prototype declarations for arguments..."new-style". */
6871 if (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
)
6872 decl_specs
= build_tree_list (NULL_TREE
, uprivate_record
);
6874 /* Really a `struct objc_class *'. However, we allow people to
6875 assign to self, which changes its type midstream. */
6876 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
6878 push_parm_decl (build_tree_list
6879 (build_tree_list (decl_specs
,
6880 build1 (INDIRECT_REF
, NULL_TREE
, self_id
)),
6883 decl_specs
= build_tree_list (NULL_TREE
,
6884 xref_tag (RECORD_TYPE
,
6885 get_identifier (TAG_SELECTOR
)));
6886 push_parm_decl (build_tree_list
6887 (build_tree_list (decl_specs
,
6888 build1 (INDIRECT_REF
, NULL_TREE
, ucmd_id
)),
6891 /* Generate argument declarations if a keyword_decl. */
6892 if (METHOD_SEL_ARGS (method
))
6894 tree arglist
= METHOD_SEL_ARGS (method
);
6897 tree arg_spec
= TREE_PURPOSE (TREE_TYPE (arglist
));
6898 tree arg_decl
= TREE_VALUE (TREE_TYPE (arglist
));
6902 tree last_expr
= expr_last (arg_decl
);
6904 /* Unite the abstract decl with its name. */
6905 TREE_OPERAND (last_expr
, 0) = KEYWORD_ARG_NAME (arglist
);
6906 push_parm_decl (build_tree_list
6907 (build_tree_list (arg_spec
, arg_decl
),
6910 /* Unhook: restore the abstract declarator. */
6911 TREE_OPERAND (last_expr
, 0) = NULL_TREE
;
6915 push_parm_decl (build_tree_list
6916 (build_tree_list (arg_spec
,
6917 KEYWORD_ARG_NAME (arglist
)),
6920 arglist
= TREE_CHAIN (arglist
);
6925 if (METHOD_ADD_ARGS (method
) != NULL_TREE
6926 && METHOD_ADD_ARGS (method
) != objc_ellipsis_node
)
6928 /* We have a variable length selector - in "prototype" format. */
6929 tree akey
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
6932 /* This must be done prior to calling pushdecl. pushdecl is
6933 going to change our chain on us. */
6934 tree nextkey
= TREE_CHAIN (akey
);
6942 warn_with_method (message
, mtype
, method
)
6943 const char *message
;
6947 if (count_error (1) == 0)
6950 report_error_function (DECL_SOURCE_FILE (method
));
6952 /* Add a readable method name to the warning. */
6953 warning_with_file_and_line (DECL_SOURCE_FILE (method
),
6954 DECL_SOURCE_LINE (method
),
6957 gen_method_decl (method
, errbuf
));
6960 /* Return 1 if METHOD is consistent with PROTO. */
6963 comp_method_with_proto (method
, proto
)
6966 /* Create a function template node at most once. */
6967 if (!function1_template
)
6968 function1_template
= make_node (FUNCTION_TYPE
);
6970 /* Install argument types - normally set by build_function_type. */
6971 TYPE_ARG_TYPES (function1_template
) = get_arg_type_list (proto
, METHOD_DEF
, 0);
6973 /* install return type */
6974 TREE_TYPE (function1_template
) = groktypename (TREE_TYPE (proto
));
6976 return comptypes (TREE_TYPE (METHOD_DEFINITION (method
)), function1_template
);
6979 /* Return 1 if PROTO1 is consistent with PROTO2. */
6982 comp_proto_with_proto (proto0
, proto1
)
6983 tree proto0
, proto1
;
6985 /* Create a couple of function_template nodes at most once. */
6986 if (!function1_template
)
6987 function1_template
= make_node (FUNCTION_TYPE
);
6988 if (!function2_template
)
6989 function2_template
= make_node (FUNCTION_TYPE
);
6991 /* Install argument types; normally set by build_function_type. */
6992 TYPE_ARG_TYPES (function1_template
) = get_arg_type_list (proto0
, METHOD_REF
, 0);
6993 TYPE_ARG_TYPES (function2_template
) = get_arg_type_list (proto1
, METHOD_REF
, 0);
6995 /* Install return type. */
6996 TREE_TYPE (function1_template
) = groktypename (TREE_TYPE (proto0
));
6997 TREE_TYPE (function2_template
) = groktypename (TREE_TYPE (proto1
));
6999 return comptypes (function1_template
, function2_template
);
7002 /* - Generate an identifier for the function. the format is "_n_cls",
7003 where 1 <= n <= nMethods, and cls is the name the implementation we
7005 - Install the return type from the method declaration.
7006 - If we have a prototype, check for type consistency. */
7009 really_start_method (method
, parmlist
)
7010 tree method
, parmlist
;
7012 tree sc_spec
, ret_spec
, ret_decl
, decl_specs
;
7013 tree method_decl
, method_id
;
7014 const char *sel_name
, *class_name
, *cat_name
;
7017 /* Synth the storage class & assemble the return type. */
7018 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
7019 ret_spec
= TREE_PURPOSE (TREE_TYPE (method
));
7020 decl_specs
= chainon (sc_spec
, ret_spec
);
7022 sel_name
= IDENTIFIER_POINTER (METHOD_SEL_NAME (method
));
7023 class_name
= IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
7024 cat_name
= ((TREE_CODE (objc_implementation_context
)
7025 == CLASS_IMPLEMENTATION_TYPE
)
7027 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
7030 /* Make sure this is big enough for any plausible method label. */
7031 buf
= (char *) alloca (50 + strlen (sel_name
) + strlen (class_name
)
7032 + (cat_name
? strlen (cat_name
) : 0));
7034 OBJC_GEN_METHOD_LABEL (buf
, TREE_CODE (method
) == INSTANCE_METHOD_DECL
,
7035 class_name
, cat_name
, sel_name
, method_slot
);
7037 method_id
= get_identifier (buf
);
7039 method_decl
= build_nt (CALL_EXPR
, method_id
, parmlist
, NULL_TREE
);
7041 /* Check the declarator portion of the return type for the method. */
7042 if ((ret_decl
= TREE_VALUE (TREE_TYPE (method
))))
7044 /* Unite the complex decl (specified in the abstract decl) with the
7045 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7046 tree save_expr
= expr_last (ret_decl
);
7048 TREE_OPERAND (save_expr
, 0) = method_decl
;
7049 method_decl
= ret_decl
;
7051 /* Fool the parser into thinking it is starting a function. */
7052 start_function (decl_specs
, method_decl
, NULL_TREE
);
7054 /* Unhook: this has the effect of restoring the abstract declarator. */
7055 TREE_OPERAND (save_expr
, 0) = NULL_TREE
;
7060 TREE_VALUE (TREE_TYPE (method
)) = method_decl
;
7062 /* Fool the parser into thinking it is starting a function. */
7063 start_function (decl_specs
, method_decl
, NULL_TREE
);
7065 /* Unhook: this has the effect of restoring the abstract declarator. */
7066 TREE_VALUE (TREE_TYPE (method
)) = NULL_TREE
;
7069 METHOD_DEFINITION (method
) = current_function_decl
;
7071 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7073 if (implementation_template
!= objc_implementation_context
)
7077 if (TREE_CODE (method
) == INSTANCE_METHOD_DECL
)
7078 proto
= lookup_instance_method_static (implementation_template
,
7079 METHOD_SEL_NAME (method
));
7081 proto
= lookup_class_method_static (implementation_template
,
7082 METHOD_SEL_NAME (method
));
7084 if (proto
&& ! comp_method_with_proto (method
, proto
))
7086 char type
= (TREE_CODE (method
) == INSTANCE_METHOD_DECL
? '-' : '+');
7088 warn_with_method ("conflicting types for", type
, method
);
7089 warn_with_method ("previous declaration of", type
, proto
);
7094 /* The following routine is always called...this "architecture" is to
7095 accommodate "old-style" variable length selectors.
7097 - a:a b:b // prototype ; id c; id d; // old-style. */
7100 continue_method_def ()
7104 if (METHOD_ADD_ARGS (objc_method_context
) == objc_ellipsis_node
)
7105 /* We have a `, ...' immediately following the selector. */
7106 parmlist
= get_parm_info (0);
7108 parmlist
= get_parm_info (1); /* place a `void_at_end' */
7110 /* Set self_decl from the first argument...this global is used by
7111 build_ivar_reference calling build_indirect_ref. */
7112 self_decl
= TREE_PURPOSE (parmlist
);
7115 really_start_method (objc_method_context
, parmlist
);
7116 store_parm_decls ();
7119 /* Called by the parser, from the `pushlevel' production. */
7124 if (!UOBJC_SUPER_decl
)
7126 UOBJC_SUPER_decl
= start_decl (get_identifier (UTAG_SUPER
),
7127 build_tree_list (NULL_TREE
,
7128 objc_super_template
),
7131 finish_decl (UOBJC_SUPER_decl
, NULL_TREE
, NULL_TREE
);
7133 /* This prevents `unused variable' warnings when compiling with -Wall. */
7134 TREE_USED (UOBJC_SUPER_decl
) = 1;
7135 DECL_ARTIFICIAL (UOBJC_SUPER_decl
) = 1;
7139 /* _n_Method (id self, SEL sel, ...)
7141 struct objc_super _S;
7142 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7146 get_super_receiver ()
7148 if (objc_method_context
)
7150 tree super_expr
, super_expr_list
;
7152 /* Set receiver to self. */
7153 super_expr
= build_component_ref (UOBJC_SUPER_decl
, self_id
);
7154 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, self_decl
);
7155 super_expr_list
= build_tree_list (NULL_TREE
, super_expr
);
7157 /* Set class to begin searching. */
7158 super_expr
= build_component_ref (UOBJC_SUPER_decl
,
7159 get_identifier ("class"));
7161 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
7163 /* [_cls, __cls]Super are "pre-built" in
7164 synth_forward_declarations. */
7166 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
,
7167 ((TREE_CODE (objc_method_context
)
7168 == INSTANCE_METHOD_DECL
)
7170 : uucls_super_ref
));
7174 /* We have a category. */
7176 tree super_name
= CLASS_SUPER_NAME (implementation_template
);
7179 /* Barf if super used in a category of Object. */
7182 error ("no super class declared in interface for `%s'",
7183 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
7184 return error_mark_node
;
7187 if (flag_next_runtime
)
7189 super_class
= get_class_reference (super_name
);
7190 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
7192 = build_component_ref (build_indirect_ref (super_class
, "->"),
7193 get_identifier ("isa"));
7197 add_class_reference (super_name
);
7198 super_class
= (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
7199 ? objc_get_class_decl
: objc_get_meta_class_decl
);
7200 assemble_external (super_class
);
7202 = build_function_call
7206 my_build_string (IDENTIFIER_LENGTH (super_name
) + 1,
7207 IDENTIFIER_POINTER (super_name
))));
7210 TREE_TYPE (super_class
) = TREE_TYPE (ucls_super_ref
);
7211 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, super_class
);
7214 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7216 super_expr
= build_unary_op (ADDR_EXPR
, UOBJC_SUPER_decl
, 0);
7217 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7219 return build_compound_expr (super_expr_list
);
7223 error ("[super ...] must appear in a method context");
7224 return error_mark_node
;
7229 encode_method_def (func_decl
)
7234 HOST_WIDE_INT max_parm_end
= 0;
7239 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
7240 obstack_object_size (&util_obstack
),
7241 OBJC_ENCODE_INLINE_DEFS
);
7244 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7245 parms
= TREE_CHAIN (parms
))
7247 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
7248 + int_size_in_bytes (TREE_TYPE (parms
)));
7250 if (! offset_is_register
&& parm_end
> max_parm_end
)
7251 max_parm_end
= parm_end
;
7254 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
7256 sprintf (buffer
, "%d", stack_size
);
7257 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7259 /* Argument types. */
7260 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7261 parms
= TREE_CHAIN (parms
))
7264 encode_type (TREE_TYPE (parms
),
7265 obstack_object_size (&util_obstack
),
7266 OBJC_ENCODE_INLINE_DEFS
);
7268 /* Compute offset. */
7269 sprintf (buffer
, "%d", forwarding_offset (parms
));
7271 /* Indicate register. */
7272 if (offset_is_register
)
7273 obstack_1grow (&util_obstack
, '+');
7275 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7278 /* Null terminate string. */
7279 obstack_1grow (&util_obstack
, 0);
7280 result
= get_identifier (obstack_finish (&util_obstack
));
7281 obstack_free (&util_obstack
, util_firstobj
);
7286 objc_expand_function_end ()
7288 METHOD_ENCODING (objc_method_context
) = encode_method_def (current_function_decl
);
7292 finish_method_def ()
7294 lang_expand_function_end
= objc_expand_function_end
;
7295 finish_function (0);
7296 lang_expand_function_end
= NULL
;
7298 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7299 since the optimizer may find "may be used before set" errors. */
7300 objc_method_context
= NULL_TREE
;
7305 lang_report_error_function (decl
)
7308 if (objc_method_context
)
7310 fprintf (stderr
, "In method `%s'\n",
7311 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context
)));
7321 is_complex_decl (type
)
7324 return (TREE_CODE (type
) == ARRAY_TYPE
7325 || TREE_CODE (type
) == FUNCTION_TYPE
7326 || (TREE_CODE (type
) == POINTER_TYPE
&& ! IS_ID (type
)));
7330 /* Code to convert a decl node into text for a declaration in C. */
7332 static char tmpbuf
[256];
7335 adorn_decl (decl
, str
)
7339 enum tree_code code
= TREE_CODE (decl
);
7341 if (code
== ARRAY_REF
)
7343 tree an_int_cst
= TREE_OPERAND (decl
, 1);
7345 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_CST
)
7346 sprintf (str
+ strlen (str
), "[%ld]",
7347 (long) TREE_INT_CST_LOW (an_int_cst
));
7352 else if (code
== ARRAY_TYPE
)
7354 tree an_int_cst
= TYPE_SIZE (decl
);
7355 tree array_of
= TREE_TYPE (decl
);
7357 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_TYPE
)
7358 sprintf (str
+ strlen (str
), "[%ld]",
7359 (long) (TREE_INT_CST_LOW (an_int_cst
)
7360 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
7365 else if (code
== CALL_EXPR
)
7367 tree chain
= TREE_PURPOSE (TREE_OPERAND (decl
, 1));
7372 gen_declaration_1 (chain
, str
);
7373 chain
= TREE_CHAIN (chain
);
7380 else if (code
== FUNCTION_TYPE
)
7382 tree chain
= TYPE_ARG_TYPES (decl
);
7385 while (chain
&& TREE_VALUE (chain
) != void_type_node
)
7387 gen_declaration_1 (TREE_VALUE (chain
), str
);
7388 chain
= TREE_CHAIN (chain
);
7389 if (chain
&& TREE_VALUE (chain
) != void_type_node
)
7395 else if (code
== INDIRECT_REF
)
7397 strcpy (tmpbuf
, "*");
7398 if (TREE_TYPE (decl
) && TREE_CODE (TREE_TYPE (decl
)) == TREE_LIST
)
7402 for (chain
= nreverse (copy_list (TREE_TYPE (decl
)));
7404 chain
= TREE_CHAIN (chain
))
7406 if (TREE_CODE (TREE_VALUE (chain
)) == IDENTIFIER_NODE
)
7408 strcat (tmpbuf
, " ");
7409 strcat (tmpbuf
, IDENTIFIER_POINTER (TREE_VALUE (chain
)));
7413 strcat (tmpbuf
, " ");
7415 strcat (tmpbuf
, str
);
7416 strcpy (str
, tmpbuf
);
7419 else if (code
== POINTER_TYPE
)
7421 strcpy (tmpbuf
, "*");
7422 if (TREE_READONLY (decl
) || TYPE_VOLATILE (decl
))
7424 if (TREE_READONLY (decl
))
7425 strcat (tmpbuf
, " const");
7426 if (TYPE_VOLATILE (decl
))
7427 strcat (tmpbuf
, " volatile");
7429 strcat (tmpbuf
, " ");
7431 strcat (tmpbuf
, str
);
7432 strcpy (str
, tmpbuf
);
7437 gen_declarator (decl
, buf
, name
)
7444 enum tree_code code
= TREE_CODE (decl
);
7454 op
= TREE_OPERAND (decl
, 0);
7456 /* We have a pointer to a function or array...(*)(), (*)[] */
7457 if ((code
== ARRAY_REF
|| code
== CALL_EXPR
)
7458 && op
&& TREE_CODE (op
) == INDIRECT_REF
)
7461 str
= gen_declarator (op
, buf
, name
);
7465 strcpy (tmpbuf
, "(");
7466 strcat (tmpbuf
, str
);
7467 strcat (tmpbuf
, ")");
7468 strcpy (str
, tmpbuf
);
7471 adorn_decl (decl
, str
);
7480 /* This clause is done iteratively rather than recursively. */
7483 op
= (is_complex_decl (TREE_TYPE (decl
))
7484 ? TREE_TYPE (decl
) : NULL_TREE
);
7486 adorn_decl (decl
, str
);
7488 /* We have a pointer to a function or array...(*)(), (*)[] */
7489 if (code
== POINTER_TYPE
7490 && op
&& (TREE_CODE (op
) == FUNCTION_TYPE
7491 || TREE_CODE (op
) == ARRAY_TYPE
))
7493 strcpy (tmpbuf
, "(");
7494 strcat (tmpbuf
, str
);
7495 strcat (tmpbuf
, ")");
7496 strcpy (str
, tmpbuf
);
7499 decl
= (is_complex_decl (TREE_TYPE (decl
))
7500 ? TREE_TYPE (decl
) : NULL_TREE
);
7503 while (decl
&& (code
= TREE_CODE (decl
)))
7508 case IDENTIFIER_NODE
:
7509 /* Will only happen if we are processing a "raw" expr-decl. */
7510 strcpy (buf
, IDENTIFIER_POINTER (decl
));
7521 /* We have an abstract declarator or a _DECL node. */
7529 gen_declspecs (declspecs
, buf
, raw
)
7538 for (chain
= nreverse (copy_list (declspecs
));
7539 chain
; chain
= TREE_CHAIN (chain
))
7541 tree aspec
= TREE_VALUE (chain
);
7543 if (TREE_CODE (aspec
) == IDENTIFIER_NODE
)
7544 strcat (buf
, IDENTIFIER_POINTER (aspec
));
7545 else if (TREE_CODE (aspec
) == RECORD_TYPE
)
7547 if (TYPE_NAME (aspec
))
7549 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7551 if (! TREE_STATIC_TEMPLATE (aspec
))
7552 strcat (buf
, "struct ");
7553 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7558 tree chain
= protocol_list
;
7565 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7566 chain
= TREE_CHAIN (chain
);
7575 strcat (buf
, "untagged struct");
7578 else if (TREE_CODE (aspec
) == UNION_TYPE
)
7580 if (TYPE_NAME (aspec
))
7582 if (! TREE_STATIC_TEMPLATE (aspec
))
7583 strcat (buf
, "union ");
7584 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7587 strcat (buf
, "untagged union");
7590 else if (TREE_CODE (aspec
) == ENUMERAL_TYPE
)
7592 if (TYPE_NAME (aspec
))
7594 if (! TREE_STATIC_TEMPLATE (aspec
))
7595 strcat (buf
, "enum ");
7596 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7599 strcat (buf
, "untagged enum");
7602 else if (TREE_CODE (aspec
) == TYPE_DECL
&& DECL_NAME (aspec
))
7603 strcat (buf
, IDENTIFIER_POINTER (DECL_NAME (aspec
)));
7605 else if (IS_ID (aspec
))
7607 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7612 tree chain
= protocol_list
;
7619 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7620 chain
= TREE_CHAIN (chain
);
7627 if (TREE_CHAIN (chain
))
7633 /* Type qualifiers. */
7634 if (TREE_READONLY (declspecs
))
7635 strcat (buf
, "const ");
7636 if (TYPE_VOLATILE (declspecs
))
7637 strcat (buf
, "volatile ");
7639 switch (TREE_CODE (declspecs
))
7641 /* Type specifiers. */
7644 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7646 /* Signed integer types. */
7648 if (declspecs
== short_integer_type_node
)
7649 strcat (buf
, "short int ");
7650 else if (declspecs
== integer_type_node
)
7651 strcat (buf
, "int ");
7652 else if (declspecs
== long_integer_type_node
)
7653 strcat (buf
, "long int ");
7654 else if (declspecs
== long_long_integer_type_node
)
7655 strcat (buf
, "long long int ");
7656 else if (declspecs
== signed_char_type_node
7657 || declspecs
== char_type_node
)
7658 strcat (buf
, "char ");
7660 /* Unsigned integer types. */
7662 else if (declspecs
== short_unsigned_type_node
)
7663 strcat (buf
, "unsigned short ");
7664 else if (declspecs
== unsigned_type_node
)
7665 strcat (buf
, "unsigned int ");
7666 else if (declspecs
== long_unsigned_type_node
)
7667 strcat (buf
, "unsigned long ");
7668 else if (declspecs
== long_long_unsigned_type_node
)
7669 strcat (buf
, "unsigned long long ");
7670 else if (declspecs
== unsigned_char_type_node
)
7671 strcat (buf
, "unsigned char ");
7675 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7677 if (declspecs
== float_type_node
)
7678 strcat (buf
, "float ");
7679 else if (declspecs
== double_type_node
)
7680 strcat (buf
, "double ");
7681 else if (declspecs
== long_double_type_node
)
7682 strcat (buf
, "long double ");
7686 if (TYPE_NAME (declspecs
)
7687 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7689 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7691 if (! TREE_STATIC_TEMPLATE (declspecs
))
7692 strcat (buf
, "struct ");
7693 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7697 tree chain
= protocol_list
;
7704 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7705 chain
= TREE_CHAIN (chain
);
7714 strcat (buf
, "untagged struct");
7720 if (TYPE_NAME (declspecs
)
7721 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7723 strcat (buf
, "union ");
7724 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7729 strcat (buf
, "untagged union ");
7733 if (TYPE_NAME (declspecs
)
7734 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7736 strcat (buf
, "enum ");
7737 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7742 strcat (buf
, "untagged enum ");
7746 strcat (buf
, "void ");
7751 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7756 tree chain
= protocol_list
;
7763 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7764 chain
= TREE_CHAIN (chain
);
7780 /* Given a tree node, produce a printable description of it in the given
7781 buffer, overwriting the buffer. */
7784 gen_declaration (atype_or_adecl
, buf
)
7785 tree atype_or_adecl
;
7789 gen_declaration_1 (atype_or_adecl
, buf
);
7793 /* Given a tree node, append a printable description to the end of the
7797 gen_declaration_1 (atype_or_adecl
, buf
)
7798 tree atype_or_adecl
;
7803 if (TREE_CODE (atype_or_adecl
) == TREE_LIST
)
7805 tree declspecs
; /* "identifier_node", "record_type" */
7806 tree declarator
; /* "array_ref", "indirect_ref", "call_expr"... */
7808 /* We have a "raw", abstract declarator (typename). */
7809 declarator
= TREE_VALUE (atype_or_adecl
);
7810 declspecs
= TREE_PURPOSE (atype_or_adecl
);
7812 gen_declspecs (declspecs
, buf
, 1);
7816 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7823 tree declspecs
; /* "integer_type", "real_type", "record_type"... */
7824 tree declarator
; /* "array_type", "function_type", "pointer_type". */
7826 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7827 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7828 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7829 atype
= TREE_TYPE (atype_or_adecl
);
7831 /* Assume we have a *_type node. */
7832 atype
= atype_or_adecl
;
7834 if (is_complex_decl (atype
))
7838 /* Get the declaration specifier; it is at the end of the list. */
7839 declarator
= chain
= atype
;
7841 chain
= TREE_TYPE (chain
); /* not TREE_CHAIN (chain); */
7842 while (is_complex_decl (chain
));
7849 declarator
= NULL_TREE
;
7852 gen_declspecs (declspecs
, buf
, 0);
7854 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7855 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7856 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7858 const char *const decl_name
=
7859 (DECL_NAME (atype_or_adecl
)
7860 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl
)) : "");
7865 strcat (buf
, gen_declarator (declarator
, declbuf
, decl_name
));
7868 else if (decl_name
[0])
7871 strcat (buf
, decl_name
);
7874 else if (declarator
)
7877 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7882 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7884 /* Given a method tree, put a printable description into the given
7885 buffer (overwriting) and return a pointer to the buffer. */
7888 gen_method_decl (method
, buf
)
7895 if (RAW_TYPESPEC (method
) != objc_object_reference
)
7898 gen_declaration_1 (TREE_TYPE (method
), buf
);
7902 chain
= METHOD_SEL_ARGS (method
);
7905 /* We have a chain of keyword_decls. */
7908 if (KEYWORD_KEY_NAME (chain
))
7909 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain
)));
7912 if (RAW_TYPESPEC (chain
) != objc_object_reference
)
7915 gen_declaration_1 (TREE_TYPE (chain
), buf
);
7919 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain
)));
7920 if ((chain
= TREE_CHAIN (chain
)))
7925 if (METHOD_ADD_ARGS (method
) == objc_ellipsis_node
)
7926 strcat (buf
, ", ...");
7927 else if (METHOD_ADD_ARGS (method
))
7929 /* We have a tree list node as generate by get_parm_info. */
7930 chain
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
7932 /* Know we have a chain of parm_decls. */
7936 gen_declaration_1 (chain
, buf
);
7937 chain
= TREE_CHAIN (chain
);
7943 /* We have a unary selector. */
7944 strcat (buf
, IDENTIFIER_POINTER (METHOD_SEL_NAME (method
)));
7952 dump_interface (fp
, chain
)
7956 char *buf
= (char *)xmalloc (256);
7957 const char *my_name
= IDENTIFIER_POINTER (CLASS_NAME (chain
));
7958 tree ivar_decls
= CLASS_RAW_IVARS (chain
);
7959 tree nst_methods
= CLASS_NST_METHODS (chain
);
7960 tree cls_methods
= CLASS_CLS_METHODS (chain
);
7962 fprintf (fp
, "\n@interface %s", my_name
);
7964 if (CLASS_SUPER_NAME (chain
))
7966 const char *super_name
= IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain
));
7967 fprintf (fp
, " : %s\n", super_name
);
7974 fprintf (fp
, "{\n");
7977 fprintf (fp
, "\t%s;\n", gen_declaration (ivar_decls
, buf
));
7978 ivar_decls
= TREE_CHAIN (ivar_decls
);
7981 fprintf (fp
, "}\n");
7986 fprintf (fp
, "- %s;\n", gen_method_decl (nst_methods
, buf
));
7987 nst_methods
= TREE_CHAIN (nst_methods
);
7992 fprintf (fp
, "+ %s;\n", gen_method_decl (cls_methods
, buf
));
7993 cls_methods
= TREE_CHAIN (cls_methods
);
7995 fprintf (fp
, "\n@end");
7998 /* Demangle function for Objective-C */
8000 objc_demangle (mangled
)
8001 const char *mangled
;
8003 char *demangled
, *cp
;
8005 if (mangled
[0] == '_' &&
8006 (mangled
[1] == 'i' || mangled
[1] == 'c') &&
8009 cp
= demangled
= xmalloc(strlen(mangled
) + 2);
8010 if (mangled
[1] == 'i')
8011 *cp
++ = '-'; /* for instance method */
8013 *cp
++ = '+'; /* for class method */
8014 *cp
++ = '['; /* opening left brace */
8015 strcpy(cp
, mangled
+3); /* tack on the rest of the mangled name */
8016 while (*cp
&& *cp
== '_')
8017 cp
++; /* skip any initial underbars in class name */
8018 cp
= strchr(cp
, '_'); /* find first non-initial underbar */
8021 free(demangled
); /* not mangled name */
8024 if (cp
[1] == '_') /* easy case: no category name */
8026 *cp
++ = ' '; /* replace two '_' with one ' ' */
8027 strcpy(cp
, mangled
+ (cp
- demangled
) + 2);
8031 *cp
++ = '('; /* less easy case: category name */
8032 cp
= strchr(cp
, '_');
8035 free(demangled
); /* not mangled name */
8039 *cp
++ = ' '; /* overwriting 1st char of method name... */
8040 strcpy(cp
, mangled
+ (cp
- demangled
)); /* get it back */
8042 while (*cp
&& *cp
== '_')
8043 cp
++; /* skip any initial underbars in method name */
8046 *cp
= ':'; /* replace remaining '_' with ':' */
8047 *cp
++ = ']'; /* closing right brace */
8048 *cp
++ = 0; /* string terminator */
8052 return mangled
; /* not an objc mangled name */
8056 objc_printable_name (decl
, kind
)
8058 int kind ATTRIBUTE_UNUSED
;
8060 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl
)));
8063 /* Adds the tree codes specific to the ObjC/ObjC++ front end to the
8064 list of all tree codes. */
8067 add_objc_tree_codes ()
8069 int add
= (int) LAST_OBJC_TREE_CODE
- (int) LAST_BASE_TREE_CODE
;
8071 memcpy (tree_code_type
+ (int) LAST_BASE_TREE_CODE
,
8072 objc_tree_code_type
, add
);
8073 memcpy (tree_code_length
+ (int) LAST_BASE_TREE_CODE
,
8074 objc_tree_code_length
, add
* sizeof (int));
8075 memcpy (tree_code_name
+ (int) LAST_BASE_TREE_CODE
,
8076 objc_tree_code_name
, add
* sizeof (char *));
8082 gcc_obstack_init (&util_obstack
);
8083 util_firstobj
= (char *) obstack_finish (&util_obstack
);
8085 errbuf
= (char *)xmalloc (BUFSIZE
);
8087 synth_module_prologue ();
8093 struct imp_entry
*impent
;
8095 /* The internally generated initializers appear to have missing braces.
8096 Don't warn about this. */
8097 int save_warn_missing_braces
= warn_missing_braces
;
8098 warn_missing_braces
= 0;
8100 /* A missing @end may not be detected by the parser. */
8101 if (objc_implementation_context
)
8103 warning ("`@end' missing in implementation context");
8104 finish_class (objc_implementation_context
);
8105 objc_ivar_chain
= NULL_TREE
;
8106 objc_implementation_context
= NULL_TREE
;
8109 generate_forward_declaration_to_string_table ();
8111 #ifdef OBJC_PROLOGUE
8115 /* Process the static instances here because initialization of objc_symtab
8117 if (objc_static_instances
)
8118 generate_static_references ();
8120 if (imp_list
|| class_names_chain
8121 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8122 generate_objc_symtab_decl ();
8124 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8126 objc_implementation_context
= impent
->imp_context
;
8127 implementation_template
= impent
->imp_template
;
8129 UOBJC_CLASS_decl
= impent
->class_decl
;
8130 UOBJC_METACLASS_decl
= impent
->meta_decl
;
8132 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
8134 /* all of the following reference the string pool... */
8135 generate_ivar_lists ();
8136 generate_dispatch_tables ();
8137 generate_shared_structures ();
8141 generate_dispatch_tables ();
8142 generate_category (objc_implementation_context
);
8146 /* If we are using an array of selectors, we must always
8147 finish up the array decl even if no selectors were used. */
8148 if (! flag_next_runtime
|| sel_ref_chain
)
8149 build_selector_translation_table ();
8152 generate_protocols ();
8154 if (objc_implementation_context
|| class_names_chain
|| objc_static_instances
8155 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8157 /* Arrange for Objc data structures to be initialized at run time. */
8158 rtx init_sym
= build_module_descriptor ();
8159 if (init_sym
&& targetm
.have_ctors_dtors
)
8160 (* targetm
.asm_out
.constructor
) (init_sym
, DEFAULT_INIT_PRIORITY
);
8163 /* Dump the class references. This forces the appropriate classes
8164 to be linked into the executable image, preserving unix archive
8165 semantics. This can be removed when we move to a more dynamically
8166 linked environment. */
8168 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
8170 handle_class_ref (chain
);
8171 if (TREE_PURPOSE (chain
))
8172 generate_classref_translation_entry (chain
);
8175 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8176 handle_impent (impent
);
8178 /* Dump the string table last. */
8180 generate_strings ();
8182 if (flag_gen_declaration
)
8184 add_class (objc_implementation_context
);
8185 dump_interface (gen_declaration_file
, objc_implementation_context
);
8193 /* Run through the selector hash tables and print a warning for any
8194 selector which has multiple methods. */
8196 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8197 for (hsh
= cls_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8200 tree meth
= hsh
->key
;
8201 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8205 warning ("potential selector conflict for method `%s'",
8206 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8207 warn_with_method ("found", type
, meth
);
8208 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8209 warn_with_method ("found", type
, loop
->value
);
8212 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8213 for (hsh
= nst_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8216 tree meth
= hsh
->key
;
8217 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8221 warning ("potential selector conflict for method `%s'",
8222 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8223 warn_with_method ("found", type
, meth
);
8224 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8225 warn_with_method ("found", type
, loop
->value
);
8229 warn_missing_braces
= save_warn_missing_braces
;
8232 /* Subroutines of finish_objc. */
8235 generate_classref_translation_entry (chain
)
8238 tree expr
, name
, decl_specs
, decl
, sc_spec
;
8241 type
= TREE_TYPE (TREE_PURPOSE (chain
));
8243 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
8244 expr
= build_c_cast (type
, expr
); /* cast! */
8246 name
= DECL_NAME (TREE_PURPOSE (chain
));
8248 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
8250 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8251 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
8253 /* The decl that is returned from start_decl is the one that we
8254 forward declared in build_class_reference. */
8255 decl
= start_decl (name
, decl_specs
, 1, NULL_TREE
);
8256 DECL_CONTEXT (decl
) = NULL_TREE
;
8257 finish_decl (decl
, expr
, NULL_TREE
);
8262 handle_class_ref (chain
)
8265 const char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
8266 char *string
= (char *) alloca (strlen (name
) + 30);
8270 sprintf (string
, "%sobjc_class_name_%s",
8271 (flag_next_runtime
? "." : "__"), name
);
8273 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8274 if (flag_next_runtime
)
8276 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file
, string
);
8281 /* Make a decl for this name, so we can use its address in a tree. */
8282 decl
= build_decl (VAR_DECL
, get_identifier (string
), char_type_node
);
8283 DECL_EXTERNAL (decl
) = 1;
8284 TREE_PUBLIC (decl
) = 1;
8287 rest_of_decl_compilation (decl
, 0, 0, 0);
8289 /* Make a decl for the address. */
8290 sprintf (string
, "%sobjc_class_ref_%s",
8291 (flag_next_runtime
? "." : "__"), name
);
8292 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
8293 decl
= build_decl (VAR_DECL
, get_identifier (string
), string_type_node
);
8294 DECL_INITIAL (decl
) = exp
;
8295 TREE_STATIC (decl
) = 1;
8298 rest_of_decl_compilation (decl
, 0, 0, 0);
8302 handle_impent (impent
)
8303 struct imp_entry
*impent
;
8307 objc_implementation_context
= impent
->imp_context
;
8308 implementation_template
= impent
->imp_template
;
8310 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
8312 const char *const class_name
=
8313 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8315 string
= (char *) alloca (strlen (class_name
) + 30);
8317 sprintf (string
, "*%sobjc_class_name_%s",
8318 (flag_next_runtime
? "." : "__"), class_name
);
8320 else if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
8322 const char *const class_name
=
8323 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8324 const char *const class_super_name
=
8325 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
8327 string
= (char *) alloca (strlen (class_name
)
8328 + strlen (class_super_name
) + 30);
8330 /* Do the same for categories. Even though no references to
8331 these symbols are generated automatically by the compiler, it
8332 gives you a handle to pull them into an archive by hand. */
8333 sprintf (string
, "*%sobjc_category_name_%s_%s",
8334 (flag_next_runtime
? "." : "__"), class_name
, class_super_name
);
8339 #ifdef ASM_DECLARE_CLASS_REFERENCE
8340 if (flag_next_runtime
)
8342 ASM_DECLARE_CLASS_REFERENCE (asm_out_file
, string
);
8347 /* (Should this be a routine in varasm.c?) */
8348 readonly_data_section ();
8349 assemble_global (string
);
8350 assemble_align (UNITS_PER_WORD
);
8351 assemble_label (string
);
8352 assemble_zeros (UNITS_PER_WORD
);
8356 ggc_mark_imp_list (arg
)
8359 struct imp_entry
*impent
;
8361 for (impent
= *(struct imp_entry
**)arg
; impent
; impent
= impent
->next
)
8363 ggc_mark_tree (impent
->imp_context
);
8364 ggc_mark_tree (impent
->imp_template
);
8365 ggc_mark_tree (impent
->class_decl
);
8366 ggc_mark_tree (impent
->meta_decl
);
8371 ggc_mark_hash_table (arg
)
8374 hash
*hash_table
= *(hash
**)arg
;
8379 if (hash_table
== NULL
)
8381 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
8382 for (hst
= hash_table
[i
]; hst
; hst
= hst
->next
)
8384 ggc_mark_tree (hst
->key
);
8385 for (list
= hst
->list
; list
; list
= list
->next
)
8386 ggc_mark_tree (list
->value
);
8390 /* Add GC roots for variables local to this file. */
8392 objc_act_parse_init ()
8394 ggc_add_tree_root (objc_global_trees
, OCTI_MAX
);
8395 ggc_add_root (&imp_list
, 1, sizeof imp_list
, ggc_mark_imp_list
);
8396 ggc_add_root (&nst_method_hash_list
, 1, sizeof nst_method_hash_list
, ggc_mark_hash_table
);
8397 ggc_add_root (&cls_method_hash_list
, 1, sizeof cls_method_hash_list
, ggc_mark_hash_table
);
8400 /* Look up ID as an instance variable. */
8402 lookup_objc_ivar (id
)
8407 if (objc_receiver_context
&& !strcmp (IDENTIFIER_POINTER (id
), "super"))
8408 /* we have a message to super */
8409 return get_super_receiver ();
8410 else if (objc_method_context
&& (decl
= is_ivar (objc_ivar_chain
, id
)))
8412 if (is_private (decl
))
8413 return error_mark_node
;
8415 return build_ivar_reference (id
);