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':
61 #include "langhooks.h"
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));
158 static void objc_init
PARAMS ((void));
159 static void objc_init_options
PARAMS ((void));
160 static int objc_decode_option
PARAMS ((int, char **));
161 static void objc_post_options
PARAMS ((void));
163 /* Code generation. */
165 static void synth_module_prologue
PARAMS ((void));
166 static tree build_constructor
PARAMS ((tree
, tree
));
167 static rtx build_module_descriptor
PARAMS ((void));
168 static tree init_module_descriptor
PARAMS ((tree
));
169 static tree build_objc_method_call
PARAMS ((int, tree
, tree
,
171 static void generate_strings
PARAMS ((void));
172 static tree get_proto_encoding
PARAMS ((tree
));
173 static void build_selector_translation_table
PARAMS ((void));
174 static tree build_ivar_chain
PARAMS ((tree
, int));
176 static tree objc_add_static_instance
PARAMS ((tree
, tree
));
178 static tree build_ivar_template
PARAMS ((void));
179 static tree build_method_template
PARAMS ((void));
180 static tree build_private_template
PARAMS ((tree
));
181 static void build_class_template
PARAMS ((void));
182 static void build_selector_template
PARAMS ((void));
183 static void build_category_template
PARAMS ((void));
184 static tree build_super_template
PARAMS ((void));
185 static tree build_category_initializer
PARAMS ((tree
, tree
, tree
,
187 static tree build_protocol_initializer
PARAMS ((tree
, tree
, tree
,
190 static void synth_forward_declarations
PARAMS ((void));
191 static void generate_ivar_lists
PARAMS ((void));
192 static void generate_dispatch_tables
PARAMS ((void));
193 static void generate_shared_structures
PARAMS ((void));
194 static tree generate_protocol_list
PARAMS ((tree
));
195 static void generate_forward_declaration_to_string_table
PARAMS ((void));
196 static void build_protocol_reference
PARAMS ((tree
));
198 static tree build_keyword_selector
PARAMS ((tree
));
199 static tree synth_id_with_class_suffix
PARAMS ((const char *, tree
));
201 static void generate_static_references
PARAMS ((void));
202 static int check_methods_accessible
PARAMS ((tree
, tree
,
204 static void encode_aggregate_within
PARAMS ((tree
, int, int,
206 static const char *objc_demangle
PARAMS ((const char *));
207 static const char *objc_printable_name
PARAMS ((tree
, int));
208 static void objc_expand_function_end
PARAMS ((void));
210 /* Hash tables to manage the global pool of method prototypes. */
212 hash
*nst_method_hash_list
= 0;
213 hash
*cls_method_hash_list
= 0;
215 static void hash_init
PARAMS ((void));
216 static void hash_enter
PARAMS ((hash
*, tree
));
217 static hash hash_lookup
PARAMS ((hash
*, tree
));
218 static void hash_add_attr
PARAMS ((hash
, tree
));
219 static tree lookup_method
PARAMS ((tree
, tree
));
220 static tree lookup_instance_method_static
PARAMS ((tree
, tree
));
221 static tree lookup_class_method_static
PARAMS ((tree
, tree
));
222 static tree add_class
PARAMS ((tree
));
223 static void add_category
PARAMS ((tree
, tree
));
227 class_names
, /* class, category, protocol, module names */
228 meth_var_names
, /* method and variable names */
229 meth_var_types
/* method and variable type descriptors */
232 static tree add_objc_string
PARAMS ((tree
,
233 enum string_section
));
234 static tree get_objc_string_decl
PARAMS ((tree
,
235 enum string_section
));
236 static tree build_objc_string_decl
PARAMS ((enum string_section
));
237 static tree build_selector_reference_decl
PARAMS ((void));
239 /* Protocol additions. */
241 static tree add_protocol
PARAMS ((tree
));
242 static tree lookup_protocol
PARAMS ((tree
));
243 static void check_protocol_recursively
PARAMS ((tree
, tree
));
244 static tree lookup_and_install_protocols
PARAMS ((tree
));
248 static void encode_type_qualifiers
PARAMS ((tree
));
249 static void encode_pointer
PARAMS ((tree
, int, int));
250 static void encode_array
PARAMS ((tree
, int, int));
251 static void encode_aggregate
PARAMS ((tree
, int, int));
252 static void encode_bitfield
PARAMS ((int));
253 static void encode_type
PARAMS ((tree
, int, int));
254 static void encode_field_decl
PARAMS ((tree
, int, int));
256 static void really_start_method
PARAMS ((tree
, tree
));
257 static int comp_method_with_proto
PARAMS ((tree
, tree
));
258 static int comp_proto_with_proto
PARAMS ((tree
, tree
));
259 static tree get_arg_type_list
PARAMS ((tree
, int, int));
260 static tree expr_last
PARAMS ((tree
));
262 /* Utilities for debugging and error diagnostics. */
264 static void warn_with_method
PARAMS ((const char *, int, tree
));
265 static void error_with_ivar
PARAMS ((const char *, tree
, tree
));
266 static char *gen_method_decl
PARAMS ((tree
, char *));
267 static char *gen_declaration
PARAMS ((tree
, char *));
268 static void gen_declaration_1
PARAMS ((tree
, char *));
269 static char *gen_declarator
PARAMS ((tree
, char *,
271 static int is_complex_decl
PARAMS ((tree
));
272 static void adorn_decl
PARAMS ((tree
, char *));
273 static void dump_interface
PARAMS ((FILE *, tree
));
275 /* Everything else. */
277 static tree define_decl
PARAMS ((tree
, tree
));
278 static tree lookup_method_in_protocol_list
PARAMS ((tree
, tree
, int));
279 static tree lookup_protocol_in_reflist
PARAMS ((tree
, tree
));
280 static tree create_builtin_decl
PARAMS ((enum tree_code
,
281 tree
, const char *));
282 static void setup_string_decl
PARAMS ((void));
283 static tree my_build_string
PARAMS ((int, const char *));
284 static void build_objc_symtab_template
PARAMS ((void));
285 static tree init_def_list
PARAMS ((tree
));
286 static tree init_objc_symtab
PARAMS ((tree
));
287 static void forward_declare_categories
PARAMS ((void));
288 static void generate_objc_symtab_decl
PARAMS ((void));
289 static tree build_selector
PARAMS ((tree
));
290 static tree build_typed_selector_reference
PARAMS ((tree
, tree
));
291 static tree build_selector_reference
PARAMS ((tree
));
292 static tree build_class_reference_decl
PARAMS ((void));
293 static void add_class_reference
PARAMS ((tree
));
294 static tree objc_copy_list
PARAMS ((tree
, tree
*));
295 static tree build_protocol_template
PARAMS ((void));
296 static tree build_descriptor_table_initializer
PARAMS ((tree
, tree
));
297 static tree build_method_prototype_list_template
PARAMS ((tree
, int));
298 static tree build_method_prototype_template
PARAMS ((void));
299 static int forwarding_offset
PARAMS ((tree
));
300 static tree encode_method_prototype
PARAMS ((tree
, tree
));
301 static tree generate_descriptor_table
PARAMS ((tree
, const char *,
303 static void generate_method_descriptors
PARAMS ((tree
));
304 static tree build_tmp_function_decl
PARAMS ((void));
305 static void hack_method_prototype
PARAMS ((tree
, tree
));
306 static void generate_protocol_references
PARAMS ((tree
));
307 static void generate_protocols
PARAMS ((void));
308 static void check_ivars
PARAMS ((tree
, tree
));
309 static tree build_ivar_list_template
PARAMS ((tree
, int));
310 static tree build_method_list_template
PARAMS ((tree
, int));
311 static tree build_ivar_list_initializer
PARAMS ((tree
, tree
));
312 static tree generate_ivars_list
PARAMS ((tree
, const char *,
314 static tree build_dispatch_table_initializer
PARAMS ((tree
, tree
));
315 static tree generate_dispatch_table
PARAMS ((tree
, const char *,
317 static tree build_shared_structure_initializer
PARAMS ((tree
, tree
, tree
, tree
,
318 tree
, int, tree
, tree
,
320 static void generate_category
PARAMS ((tree
));
321 static int is_objc_type_qualifier
PARAMS ((tree
));
322 static tree adjust_type_for_id_default
PARAMS ((tree
));
323 static tree check_duplicates
PARAMS ((hash
));
324 static tree receiver_is_class_object
PARAMS ((tree
));
325 static int check_methods
PARAMS ((tree
, tree
, int));
326 static int conforms_to_protocol
PARAMS ((tree
, tree
));
327 static void check_protocol
PARAMS ((tree
, const char *,
329 static void check_protocols
PARAMS ((tree
, const char *,
331 static tree encode_method_def
PARAMS ((tree
));
332 static void gen_declspecs
PARAMS ((tree
, char *, int));
333 static void generate_classref_translation_entry
PARAMS ((tree
));
334 static void handle_class_ref
PARAMS ((tree
));
335 static void generate_struct_by_value_array
PARAMS ((void))
337 static void objc_act_parse_init
PARAMS ((void));
338 static void ggc_mark_imp_list
PARAMS ((void *));
339 static void ggc_mark_hash_table
PARAMS ((void *));
341 /*** Private Interface (data) ***/
343 /* Reserved tag definitions. */
346 #define TAG_OBJECT "objc_object"
347 #define TAG_CLASS "objc_class"
348 #define TAG_SUPER "objc_super"
349 #define TAG_SELECTOR "objc_selector"
351 #define UTAG_CLASS "_objc_class"
352 #define UTAG_IVAR "_objc_ivar"
353 #define UTAG_IVAR_LIST "_objc_ivar_list"
354 #define UTAG_METHOD "_objc_method"
355 #define UTAG_METHOD_LIST "_objc_method_list"
356 #define UTAG_CATEGORY "_objc_category"
357 #define UTAG_MODULE "_objc_module"
358 #define UTAG_STATICS "_objc_statics"
359 #define UTAG_SYMTAB "_objc_symtab"
360 #define UTAG_SUPER "_objc_super"
361 #define UTAG_SELECTOR "_objc_selector"
363 #define UTAG_PROTOCOL "_objc_protocol"
364 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
365 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
366 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
368 #ifdef NEXT_OBJC_RUNTIME
369 #define STRING_OBJECT_CLASS_NAME "NSConstantString"
371 #define STRING_OBJECT_CLASS_NAME "NXConstantString"
373 /* Note that the string object global name is only needed for the
375 #define STRING_OBJECT_GLOBAL_NAME "_NSConstantStringClassReference"
377 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
379 static const char *constant_string_class_name
= NULL
;
381 static const char *TAG_GETCLASS
;
382 static const char *TAG_GETMETACLASS
;
383 static const char *TAG_MSGSEND
;
384 static const char *TAG_MSGSENDSUPER
;
385 static const char *TAG_EXECCLASS
;
387 /* The OCTI_... enumeration itself in in objc/objc-act.h. */
388 tree objc_global_trees
[OCTI_MAX
];
390 int objc_receiver_context
;
392 static void handle_impent
PARAMS ((struct imp_entry
*));
394 struct imp_entry
*imp_list
= 0;
395 int imp_count
= 0; /* `@implementation' */
396 int cat_count
= 0; /* `@category' */
398 static int method_slot
= 0; /* Used by start_method_def, */
402 static char *errbuf
; /* Buffer for error diagnostics */
404 /* Data imported from tree.c. */
406 extern enum debug_info_type write_symbols
;
408 /* Data imported from toplev.c. */
410 extern const char *dump_base_name
;
412 /* Generate code for GNU or NeXT runtime environment. */
414 #ifdef NEXT_OBJC_RUNTIME
415 int flag_next_runtime
= 1;
417 int flag_next_runtime
= 0;
420 int flag_typed_selectors
;
422 /* Open and close the file for outputting class declarations, if requested. */
424 int flag_gen_declaration
= 0;
426 FILE *gen_declaration_file
;
428 /* Warn if multiple methods are seen for the same selector, but with
429 different argument types. */
431 int warn_selector
= 0;
433 /* Warn if methods required by a protocol are not implemented in the
434 class adopting it. When turned off, methods inherited to that
435 class are also considered implemented */
437 int flag_warn_protocol
= 1;
439 /* Tells "encode_pointer/encode_aggregate" whether we are generating
440 type descriptors for instance variables (as opposed to methods).
441 Type descriptors for instance variables contain more information
442 than methods (for static typing and embedded structures). This
443 was added to support features being planned for dbkit2. */
445 static int generating_instance_variables
= 0;
447 /* Tells the compiler that this is a special run. Do not perform
448 any compiling, instead we are to test some platform dependent
449 features and output a C header file with appropriate definitions. */
451 static int print_struct_values
= 0;
453 #undef LANG_HOOKS_INIT
454 #define LANG_HOOKS_INIT objc_init
455 #undef LANG_HOOKS_INIT_OPTIONS
456 #define LANG_HOOKS_INIT_OPTIONS objc_init_options
457 #undef LANG_HOOKS_DECODE_OPTION
458 #define LANG_HOOKS_DECODE_OPTION objc_decode_option
459 #undef LANG_HOOKS_POST_OPTIONS
460 #define LANG_HOOKS_POST_OPTIONS objc_post_options
462 /* Each front end provides its own. */
463 struct lang_hooks lang_hooks
= LANG_HOOKS_INITIALIZER
;
465 /* Post-switch processing. */
469 cpp_post_options (parse_in
);
472 /* Some platforms pass small structures through registers versus through
473 an invisible pointer. Determine at what size structure is the
474 transition point between the two possibilities. */
477 generate_struct_by_value_array ()
480 tree field_decl
, field_decl_chain
;
482 int aggregate_in_mem
[32];
485 /* Presumably no platform passes 32 byte structures in a register. */
486 for (i
= 1; i
< 32; i
++)
490 /* Create an unnamed struct that has `i' character components */
491 type
= start_struct (RECORD_TYPE
, NULL_TREE
);
493 strcpy (buffer
, "c1");
494 field_decl
= create_builtin_decl (FIELD_DECL
,
497 field_decl_chain
= field_decl
;
499 for (j
= 1; j
< i
; j
++)
501 sprintf (buffer
, "c%d", j
+ 1);
502 field_decl
= create_builtin_decl (FIELD_DECL
,
505 chainon (field_decl_chain
, field_decl
);
507 finish_struct (type
, field_decl_chain
, NULL_TREE
);
509 aggregate_in_mem
[i
] = aggregate_value_p (type
);
510 if (!aggregate_in_mem
[i
])
514 /* We found some structures that are returned in registers instead of memory
515 so output the necessary data. */
518 for (i
= 31; i
>= 0; i
--)
519 if (!aggregate_in_mem
[i
])
521 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i
);
523 /* The first member of the structure is always 0 because we don't handle
524 structures with 0 members */
525 printf ("static int struct_forward_array[] = {\n 0");
527 for (j
= 1; j
<= i
; j
++)
528 printf (", %d", aggregate_in_mem
[j
]);
538 /* Make identifier nodes long enough for the language-specific slots. */
539 set_identifier_size (sizeof (struct lang_identifier
));
541 parse_in
= cpp_create_reader (ident_hash
, CLK_OBJC
);
542 c_language
= clk_objective_c
;
548 /* Force the line number back to 0; check_newline will have
549 raised it to 1, which will make the builtin functions appear
550 not to be built in. */
553 c_common_lang_init ();
555 /* If gen_declaration desired, open the output file. */
556 if (flag_gen_declaration
)
558 register char * const dumpname
= concat (dump_base_name
, ".decl", NULL
);
559 gen_declaration_file
= fopen (dumpname
, "w");
560 if (gen_declaration_file
== 0)
561 fatal_io_error ("can't open %s", dumpname
);
565 if (flag_next_runtime
)
567 TAG_GETCLASS
= "objc_getClass";
568 TAG_GETMETACLASS
= "objc_getMetaClass";
569 TAG_MSGSEND
= "objc_msgSend";
570 TAG_MSGSENDSUPER
= "objc_msgSendSuper";
571 TAG_EXECCLASS
= "__objc_execClass";
575 TAG_GETCLASS
= "objc_get_class";
576 TAG_GETMETACLASS
= "objc_get_meta_class";
577 TAG_MSGSEND
= "objc_msg_lookup";
578 TAG_MSGSENDSUPER
= "objc_msg_lookup_super";
579 TAG_EXECCLASS
= "__objc_exec_class";
580 flag_typed_selectors
= 1;
583 objc_ellipsis_node
= make_node (ERROR_MARK
);
587 if (print_struct_values
)
588 generate_struct_by_value_array ();
590 objc_act_parse_init ();
597 finish_objc (); /* Objective-C finalization */
599 if (gen_declaration_file
)
600 fclose (gen_declaration_file
);
610 objc_decode_option (argc
, argv
)
614 const char *p
= argv
[0];
616 if (!strcmp (p
, "-gen-decls"))
617 flag_gen_declaration
= 1;
618 else if (!strcmp (p
, "-Wselector"))
620 else if (!strcmp (p
, "-Wno-selector"))
622 else if (!strcmp (p
, "-Wprotocol"))
623 flag_warn_protocol
= 1;
624 else if (!strcmp (p
, "-Wno-protocol"))
625 flag_warn_protocol
= 0;
626 else if (!strcmp (p
, "-fgnu-runtime"))
627 flag_next_runtime
= 0;
628 else if (!strcmp (p
, "-fno-next-runtime"))
629 flag_next_runtime
= 0;
630 else if (!strcmp (p
, "-fno-gnu-runtime"))
631 flag_next_runtime
= 1;
632 else if (!strcmp (p
, "-fnext-runtime"))
633 flag_next_runtime
= 1;
634 else if (!strcmp (p
, "-print-objc-runtime-info"))
635 print_struct_values
= 1;
636 #define CSTSTRCLASS "-fconstant-string-class="
637 else if (!strncmp (p
, CSTSTRCLASS
, sizeof(CSTSTRCLASS
) - 2)) {
638 if (strlen (argv
[0]) <= strlen (CSTSTRCLASS
))
639 error ("no class name specified as argument to -fconstant-string-class");
640 constant_string_class_name
= xstrdup(argv
[0] + sizeof(CSTSTRCLASS
) - 1);
644 return c_decode_option (argc
, argv
);
649 /* used by print-tree.c */
652 lang_print_xnode (file
, node
, indent
)
653 FILE *file ATTRIBUTE_UNUSED
;
654 tree node ATTRIBUTE_UNUSED
;
655 int indent ATTRIBUTE_UNUSED
;
661 define_decl (declarator
, declspecs
)
665 tree decl
= start_decl (declarator
, declspecs
, 0, NULL_TREE
);
666 finish_decl (decl
, NULL_TREE
, NULL_TREE
);
670 /* Return 1 if LHS and RHS are compatible types for assignment or
671 various other operations. Return 0 if they are incompatible, and
672 return -1 if we choose to not decide. When the operation is
673 REFLEXIVE, check for compatibility in either direction.
675 For statically typed objects, an assignment of the form `a' = `b'
679 `a' and `b' are the same class type, or
680 `a' and `b' are of class types A and B such that B is a descendant of A. */
683 maybe_objc_comptypes (lhs
, rhs
, reflexive
)
687 return objc_comptypes (lhs
, rhs
, reflexive
);
691 lookup_method_in_protocol_list (rproto_list
, sel_name
, class_meth
)
699 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
701 p
= TREE_VALUE (rproto
);
703 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
705 if ((fnd
= lookup_method (class_meth
706 ? PROTOCOL_CLS_METHODS (p
)
707 : PROTOCOL_NST_METHODS (p
), sel_name
)))
709 else if (PROTOCOL_LIST (p
))
710 fnd
= lookup_method_in_protocol_list (PROTOCOL_LIST (p
),
711 sel_name
, class_meth
);
715 ; /* An identifier...if we could not find a protocol. */
726 lookup_protocol_in_reflist (rproto_list
, lproto
)
732 /* Make sure the protocol is supported by the object on the rhs. */
733 if (TREE_CODE (lproto
) == PROTOCOL_INTERFACE_TYPE
)
736 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
738 p
= TREE_VALUE (rproto
);
740 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
745 else if (PROTOCOL_LIST (p
))
746 fnd
= lookup_protocol_in_reflist (PROTOCOL_LIST (p
), lproto
);
755 ; /* An identifier...if we could not find a protocol. */
761 /* Return 1 if LHS and RHS are compatible types for assignment
762 or various other operations. Return 0 if they are incompatible,
763 and return -1 if we choose to not decide. When the operation
764 is REFLEXIVE, check for compatibility in either direction. */
767 objc_comptypes (lhs
, rhs
, reflexive
)
772 /* New clause for protocols. */
774 if (TREE_CODE (lhs
) == POINTER_TYPE
775 && TREE_CODE (TREE_TYPE (lhs
)) == RECORD_TYPE
776 && TREE_CODE (rhs
) == POINTER_TYPE
777 && TREE_CODE (TREE_TYPE (rhs
)) == RECORD_TYPE
)
779 int lhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (lhs
);
780 int rhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (rhs
);
784 tree lproto
, lproto_list
= TYPE_PROTOCOL_LIST (lhs
);
785 tree rproto
, rproto_list
;
790 rproto_list
= TYPE_PROTOCOL_LIST (rhs
);
792 /* Make sure the protocol is supported by the object
794 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
796 p
= TREE_VALUE (lproto
);
797 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
800 warning ("object does not conform to the `%s' protocol",
801 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
804 else if (TYPED_OBJECT (TREE_TYPE (rhs
)))
806 tree rname
= TYPE_NAME (TREE_TYPE (rhs
));
809 /* Make sure the protocol is supported by the object
811 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
813 p
= TREE_VALUE (lproto
);
815 rinter
= lookup_interface (rname
);
817 while (rinter
&& !rproto
)
821 rproto_list
= CLASS_PROTOCOL_LIST (rinter
);
822 /* If the underlying ObjC class does not have
823 protocols attached to it, perhaps there are
824 "one-off" protocols attached to the rhs?
825 E.g., 'id<MyProt> foo;'. */
827 rproto_list
= TYPE_PROTOCOL_LIST (TREE_TYPE (rhs
));
828 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
830 /* Check for protocols adopted by categories. */
831 cat
= CLASS_CATEGORY_LIST (rinter
);
832 while (cat
&& !rproto
)
834 rproto_list
= CLASS_PROTOCOL_LIST (cat
);
835 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
837 cat
= CLASS_CATEGORY_LIST (cat
);
840 rinter
= lookup_interface (CLASS_SUPER_NAME (rinter
));
844 warning ("class `%s' does not implement the `%s' protocol",
845 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs
))),
846 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
850 /* May change...based on whether there was any mismatch */
853 else if (rhs_is_proto
)
854 /* Lhs is not a protocol...warn if it is statically typed */
855 return (TYPED_OBJECT (TREE_TYPE (lhs
)) != 0);
858 /* Defer to comptypes. */
862 else if (TREE_CODE (lhs
) == RECORD_TYPE
&& TREE_CODE (rhs
) == RECORD_TYPE
)
863 ; /* Fall thru. This is the case we have been handling all along */
865 /* Defer to comptypes. */
868 /* `id' = `<class> *', `<class> *' = `id' */
870 if ((TYPE_NAME (lhs
) == objc_object_id
&& TYPED_OBJECT (rhs
))
871 || (TYPE_NAME (rhs
) == objc_object_id
&& TYPED_OBJECT (lhs
)))
874 /* `id' = `Class', `Class' = `id' */
876 else if ((TYPE_NAME (lhs
) == objc_object_id
877 && TYPE_NAME (rhs
) == objc_class_id
)
878 || (TYPE_NAME (lhs
) == objc_class_id
879 && TYPE_NAME (rhs
) == objc_object_id
))
882 /* `<class> *' = `<class> *' */
884 else if (TYPED_OBJECT (lhs
) && TYPED_OBJECT (rhs
))
886 tree lname
= TYPE_NAME (lhs
);
887 tree rname
= TYPE_NAME (rhs
);
893 /* If the left hand side is a super class of the right hand side,
895 for (inter
= lookup_interface (rname
); inter
;
896 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
897 if (lname
== CLASS_SUPER_NAME (inter
))
900 /* Allow the reverse when reflexive. */
902 for (inter
= lookup_interface (lname
); inter
;
903 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
904 if (rname
== CLASS_SUPER_NAME (inter
))
910 /* Defer to comptypes. */
914 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
917 objc_check_decl (decl
)
920 tree type
= TREE_TYPE (decl
);
922 if (TREE_CODE (type
) == RECORD_TYPE
923 && TREE_STATIC_TEMPLATE (type
)
924 && type
!= constant_string_type
)
925 error_with_decl (decl
, "`%s' cannot be statically allocated");
929 maybe_objc_check_decl (decl
)
932 objc_check_decl (decl
);
935 /* Implement static typing. At this point, we know we have an interface. */
938 get_static_reference (interface
, protocols
)
942 tree type
= xref_tag (RECORD_TYPE
, interface
);
946 tree t
, m
= TYPE_MAIN_VARIANT (type
);
948 t
= copy_node (type
);
949 TYPE_BINFO (t
) = make_tree_vec (2);
951 /* Add this type to the chain of variants of TYPE. */
952 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
953 TYPE_NEXT_VARIANT (m
) = t
;
955 /* Look up protocols and install in lang specific list. Note
956 that the protocol list can have a different lifetime than T! */
957 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
959 /* This forces a new pointer type to be created later
960 (in build_pointer_type)...so that the new template
961 we just created will actually be used...what a hack! */
962 if (TYPE_POINTER_TO (t
))
963 TYPE_POINTER_TO (t
) = NULL_TREE
;
972 get_object_reference (protocols
)
975 tree type_decl
= lookup_name (objc_id_id
);
978 if (type_decl
&& TREE_CODE (type_decl
) == TYPE_DECL
)
980 type
= TREE_TYPE (type_decl
);
981 if (TYPE_MAIN_VARIANT (type
) != id_type
)
982 warning ("Unexpected type for `id' (%s)",
983 gen_declaration (type
, errbuf
));
987 error ("Undefined type `id', please import <objc/objc.h>");
988 return error_mark_node
;
991 /* This clause creates a new pointer type that is qualified with
992 the protocol specification...this info is used later to do more
993 elaborate type checking. */
997 tree t
, m
= TYPE_MAIN_VARIANT (type
);
999 t
= copy_node (type
);
1000 TYPE_BINFO (t
) = make_tree_vec (2);
1002 /* Add this type to the chain of variants of TYPE. */
1003 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
1004 TYPE_NEXT_VARIANT (m
) = t
;
1006 /* Look up protocols...and install in lang specific list */
1007 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
1009 /* This forces a new pointer type to be created later
1010 (in build_pointer_type)...so that the new template
1011 we just created will actually be used...what a hack! */
1012 if (TYPE_POINTER_TO (t
))
1013 TYPE_POINTER_TO (t
) = NULL_TREE
;
1020 /* Check for circular dependencies in protocols. The arguments are
1021 PROTO, the protocol to check, and LIST, a list of protocol it
1025 check_protocol_recursively (proto
, list
)
1031 for (p
= list
; p
; p
= TREE_CHAIN (p
))
1033 tree pp
= TREE_VALUE (p
);
1035 if (TREE_CODE (pp
) == IDENTIFIER_NODE
)
1036 pp
= lookup_protocol (pp
);
1039 fatal_error ("protocol `%s' has circular dependency",
1040 IDENTIFIER_POINTER (PROTOCOL_NAME (pp
)));
1042 check_protocol_recursively (proto
, PROTOCOL_LIST (pp
));
1047 lookup_and_install_protocols (protocols
)
1052 tree return_value
= protocols
;
1054 for (proto
= protocols
; proto
; proto
= TREE_CHAIN (proto
))
1056 tree ident
= TREE_VALUE (proto
);
1057 tree p
= lookup_protocol (ident
);
1061 error ("Cannot find protocol declaration for `%s'",
1062 IDENTIFIER_POINTER (ident
));
1064 TREE_CHAIN (prev
) = TREE_CHAIN (proto
);
1066 return_value
= TREE_CHAIN (proto
);
1070 /* Replace identifier with actual protocol node. */
1071 TREE_VALUE (proto
) = p
;
1076 return return_value
;
1079 /* Create and push a decl for a built-in external variable or field NAME.
1081 TYPE is its data type. */
1084 create_builtin_decl (code
, type
, name
)
1085 enum tree_code code
;
1089 tree decl
= build_decl (code
, get_identifier (name
), type
);
1091 if (code
== VAR_DECL
)
1093 TREE_STATIC (decl
) = 1;
1094 make_decl_rtl (decl
, 0);
1098 DECL_ARTIFICIAL (decl
) = 1;
1102 /* Find the decl for the constant string class. */
1105 setup_string_decl ()
1107 if (!string_class_decl
)
1109 if (!constant_string_global_id
)
1110 constant_string_global_id
= get_identifier (STRING_OBJECT_GLOBAL_NAME
);
1111 string_class_decl
= lookup_name (constant_string_global_id
);
1115 /* Purpose: "play" parser, creating/installing representations
1116 of the declarations that are required by Objective-C.
1120 type_spec--------->sc_spec
1121 (tree_list) (tree_list)
1124 identifier_node identifier_node */
1127 synth_module_prologue ()
1132 /* Defined in `objc.h' */
1133 objc_object_id
= get_identifier (TAG_OBJECT
);
1135 objc_object_reference
= xref_tag (RECORD_TYPE
, objc_object_id
);
1137 id_type
= build_pointer_type (objc_object_reference
);
1139 objc_id_id
= get_identifier (TYPE_ID
);
1140 objc_class_id
= get_identifier (TAG_CLASS
);
1142 objc_class_type
= build_pointer_type (xref_tag (RECORD_TYPE
, objc_class_id
));
1143 protocol_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
1144 get_identifier (PROTOCOL_OBJECT_CLASS_NAME
)));
1146 /* Declare type of selector-objects that represent an operation name. */
1148 /* `struct objc_selector *' */
1150 = build_pointer_type (xref_tag (RECORD_TYPE
,
1151 get_identifier (TAG_SELECTOR
)));
1153 /* Forward declare type, or else the prototype for msgSendSuper will
1156 super_p
= build_pointer_type (xref_tag (RECORD_TYPE
,
1157 get_identifier (TAG_SUPER
)));
1160 /* id objc_msgSend (id, SEL, ...); */
1163 = build_function_type (id_type
,
1164 tree_cons (NULL_TREE
, id_type
,
1165 tree_cons (NULL_TREE
, selector_type
,
1168 if (! flag_next_runtime
)
1170 umsg_decl
= build_decl (FUNCTION_DECL
,
1171 get_identifier (TAG_MSGSEND
), temp_type
);
1172 DECL_EXTERNAL (umsg_decl
) = 1;
1173 TREE_PUBLIC (umsg_decl
) = 1;
1174 DECL_INLINE (umsg_decl
) = 1;
1175 DECL_ARTIFICIAL (umsg_decl
) = 1;
1177 if (flag_traditional
&& TAG_MSGSEND
[0] != '_')
1178 DECL_BUILT_IN_NONANSI (umsg_decl
) = 1;
1180 make_decl_rtl (umsg_decl
, NULL
);
1181 pushdecl (umsg_decl
);
1184 umsg_decl
= builtin_function (TAG_MSGSEND
, temp_type
, 0, NOT_BUILT_IN
, 0);
1186 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1189 = build_function_type (id_type
,
1190 tree_cons (NULL_TREE
, super_p
,
1191 tree_cons (NULL_TREE
, selector_type
,
1194 umsg_super_decl
= builtin_function (TAG_MSGSENDSUPER
,
1195 temp_type
, 0, NOT_BUILT_IN
, 0);
1197 /* id objc_getClass (const char *); */
1199 temp_type
= build_function_type (id_type
,
1200 tree_cons (NULL_TREE
,
1201 const_string_type_node
,
1202 tree_cons (NULL_TREE
, void_type_node
,
1206 = builtin_function (TAG_GETCLASS
, temp_type
, 0, NOT_BUILT_IN
, 0);
1208 /* id objc_getMetaClass (const char *); */
1210 objc_get_meta_class_decl
1211 = builtin_function (TAG_GETMETACLASS
, temp_type
, 0, NOT_BUILT_IN
, 0);
1213 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1215 if (! flag_next_runtime
)
1217 if (flag_typed_selectors
)
1219 /* Suppress outputting debug symbols, because
1220 dbxout_init hasn'r been called yet. */
1221 enum debug_info_type save_write_symbols
= write_symbols
;
1222 struct gcc_debug_hooks
*save_hooks
= debug_hooks
;
1223 write_symbols
= NO_DEBUG
;
1224 debug_hooks
= &do_nothing_debug_hooks
;
1226 build_selector_template ();
1227 temp_type
= build_array_type (objc_selector_template
, NULL_TREE
);
1229 write_symbols
= save_write_symbols
;
1230 debug_hooks
= save_hooks
;
1233 temp_type
= build_array_type (selector_type
, NULL_TREE
);
1235 layout_type (temp_type
);
1236 UOBJC_SELECTOR_TABLE_decl
1237 = create_builtin_decl (VAR_DECL
, temp_type
,
1238 "_OBJC_SELECTOR_TABLE");
1240 /* Avoid warning when not sending messages. */
1241 TREE_USED (UOBJC_SELECTOR_TABLE_decl
) = 1;
1244 generate_forward_declaration_to_string_table ();
1246 /* Forward declare constant_string_id and constant_string_type. */
1247 if (!constant_string_class_name
)
1248 constant_string_class_name
= STRING_OBJECT_CLASS_NAME
;
1250 constant_string_id
= get_identifier (constant_string_class_name
);
1251 constant_string_type
= xref_tag (RECORD_TYPE
, constant_string_id
);
1254 /* Custom build_string which sets TREE_TYPE! */
1257 my_build_string (len
, str
)
1262 tree a_string
= build_string (len
, str
);
1264 /* Some code from combine_strings, which is local to c-parse.y. */
1265 if (TREE_TYPE (a_string
) == int_array_type_node
)
1268 TREE_TYPE (a_string
)
1269 = build_array_type (wide_flag
? integer_type_node
: char_type_node
,
1270 build_index_type (build_int_2 (len
- 1, 0)));
1272 TREE_CONSTANT (a_string
) = 1; /* Puts string in the readonly segment */
1273 TREE_STATIC (a_string
) = 1;
1278 /* Given a chain of STRING_CST's, build a static instance of
1279 NXConstantString which points at the concatenation of those strings.
1280 We place the string object in the __string_objects section of the
1281 __OBJC segment. The Objective-C runtime will initialize the isa
1282 pointers of the string objects to point at the NXConstantString
1286 build_objc_string_object (strings
)
1289 tree string
, initlist
, constructor
;
1292 if (lookup_interface (constant_string_id
) == NULL_TREE
)
1294 error ("Cannot find interface declaration for `%s'",
1295 IDENTIFIER_POINTER (constant_string_id
));
1296 return error_mark_node
;
1299 add_class_reference (constant_string_id
);
1301 string
= combine_strings (strings
);
1302 TREE_SET_CODE (string
, STRING_CST
);
1303 length
= TREE_STRING_LENGTH (string
) - 1;
1305 /* & ((NXConstantString) {0, string, length}) */
1307 if (flag_next_runtime
)
1309 /* For the NeXT runtime, we can generate a literal reference
1310 to the string class, don't need to run a constructor. */
1311 setup_string_decl ();
1312 if (string_class_decl
== NULL_TREE
)
1314 error ("Cannot find reference tag for class `%s'",
1315 IDENTIFIER_POINTER (constant_string_id
));
1316 return error_mark_node
;
1318 initlist
= build_tree_list
1320 copy_node (build_unary_op (ADDR_EXPR
, string_class_decl
, 0)));
1324 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1328 = tree_cons (NULL_TREE
, copy_node (build_unary_op (ADDR_EXPR
, string
, 1)),
1330 initlist
= tree_cons (NULL_TREE
, build_int_2 (length
, 0), initlist
);
1331 constructor
= build_constructor (constant_string_type
, nreverse (initlist
));
1333 if (!flag_next_runtime
)
1336 = objc_add_static_instance (constructor
, constant_string_type
);
1339 return (build_unary_op (ADDR_EXPR
, constructor
, 1));
1342 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1345 objc_add_static_instance (constructor
, class_decl
)
1346 tree constructor
, class_decl
;
1348 static int num_static_inst
;
1352 /* Find the list of static instances for the CLASS_DECL. Create one if
1354 for (chain
= &objc_static_instances
;
1355 *chain
&& TREE_VALUE (*chain
) != class_decl
;
1356 chain
= &TREE_CHAIN (*chain
));
1359 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
1360 add_objc_string (TYPE_NAME (class_decl
), class_names
);
1363 sprintf (buf
, "_OBJC_INSTANCE_%d", num_static_inst
++);
1364 decl
= build_decl (VAR_DECL
, get_identifier (buf
), class_decl
);
1365 DECL_COMMON (decl
) = 1;
1366 TREE_STATIC (decl
) = 1;
1367 DECL_ARTIFICIAL (decl
) = 1;
1368 DECL_INITIAL (decl
) = constructor
;
1370 /* We may be writing something else just now.
1371 Postpone till end of input. */
1372 DECL_DEFER_OUTPUT (decl
) = 1;
1373 pushdecl_top_level (decl
);
1374 rest_of_decl_compilation (decl
, 0, 1, 0);
1376 /* Add the DECL to the head of this CLASS' list. */
1377 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
1382 /* Build a static constant CONSTRUCTOR
1383 with type TYPE and elements ELTS. */
1386 build_constructor (type
, elts
)
1389 tree constructor
= build (CONSTRUCTOR
, type
, NULL_TREE
, elts
);
1391 TREE_CONSTANT (constructor
) = 1;
1392 TREE_STATIC (constructor
) = 1;
1393 TREE_READONLY (constructor
) = 1;
1398 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1400 /* Predefine the following data type:
1408 void *defs[cls_def_cnt + cat_def_cnt];
1412 build_objc_symtab_template ()
1414 tree field_decl
, field_decl_chain
, index
;
1416 objc_symtab_template
1417 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SYMTAB
));
1419 /* long sel_ref_cnt; */
1421 field_decl
= create_builtin_decl (FIELD_DECL
,
1422 long_integer_type_node
,
1424 field_decl_chain
= field_decl
;
1428 field_decl
= create_builtin_decl (FIELD_DECL
,
1429 build_pointer_type (selector_type
),
1431 chainon (field_decl_chain
, field_decl
);
1433 /* short cls_def_cnt; */
1435 field_decl
= create_builtin_decl (FIELD_DECL
,
1436 short_integer_type_node
,
1438 chainon (field_decl_chain
, field_decl
);
1440 /* short cat_def_cnt; */
1442 field_decl
= create_builtin_decl (FIELD_DECL
,
1443 short_integer_type_node
,
1445 chainon (field_decl_chain
, field_decl
);
1447 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1449 if (!flag_next_runtime
)
1450 index
= build_index_type (build_int_2 (imp_count
+ cat_count
, 0));
1452 index
= build_index_type (build_int_2 (imp_count
+ cat_count
- 1,
1453 imp_count
== 0 && cat_count
== 0
1455 field_decl
= create_builtin_decl (FIELD_DECL
,
1456 build_array_type (ptr_type_node
, index
),
1458 chainon (field_decl_chain
, field_decl
);
1460 finish_struct (objc_symtab_template
, field_decl_chain
, NULL_TREE
);
1463 /* Create the initial value for the `defs' field of _objc_symtab.
1464 This is a CONSTRUCTOR. */
1467 init_def_list (type
)
1470 tree expr
, initlist
= NULL_TREE
;
1471 struct imp_entry
*impent
;
1474 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1476 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
1478 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1479 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1484 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1486 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1488 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1489 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1493 if (!flag_next_runtime
)
1495 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1498 if (static_instances_decl
)
1499 expr
= build_unary_op (ADDR_EXPR
, static_instances_decl
, 0);
1501 expr
= build_int_2 (0, 0);
1503 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1506 return build_constructor (type
, nreverse (initlist
));
1509 /* Construct the initial value for all of _objc_symtab. */
1512 init_objc_symtab (type
)
1517 /* sel_ref_cnt = { ..., 5, ... } */
1519 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1521 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1523 if (flag_next_runtime
|| ! sel_ref_chain
)
1524 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1526 initlist
= tree_cons (NULL_TREE
,
1527 build_unary_op (ADDR_EXPR
,
1528 UOBJC_SELECTOR_TABLE_decl
, 1),
1531 /* cls_def_cnt = { ..., 5, ... } */
1533 initlist
= tree_cons (NULL_TREE
, build_int_2 (imp_count
, 0), initlist
);
1535 /* cat_def_cnt = { ..., 5, ... } */
1537 initlist
= tree_cons (NULL_TREE
, build_int_2 (cat_count
, 0), initlist
);
1539 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1541 if (imp_count
|| cat_count
|| static_instances_decl
)
1544 tree field
= TYPE_FIELDS (type
);
1545 field
= TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field
))));
1547 initlist
= tree_cons (NULL_TREE
, init_def_list (TREE_TYPE (field
)),
1551 return build_constructor (type
, nreverse (initlist
));
1554 /* Push forward-declarations of all the categories
1555 so that init_def_list can use them in a CONSTRUCTOR. */
1558 forward_declare_categories ()
1560 struct imp_entry
*impent
;
1561 tree sav
= objc_implementation_context
;
1563 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1565 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1567 /* Set an invisible arg to synth_id_with_class_suffix. */
1568 objc_implementation_context
= impent
->imp_context
;
1570 = create_builtin_decl (VAR_DECL
, objc_category_template
,
1571 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", objc_implementation_context
)));
1574 objc_implementation_context
= sav
;
1577 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1578 and initialized appropriately. */
1581 generate_objc_symtab_decl ()
1585 if (!objc_category_template
)
1586 build_category_template ();
1588 /* forward declare categories */
1590 forward_declare_categories ();
1592 if (!objc_symtab_template
)
1593 build_objc_symtab_template ();
1595 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
1597 UOBJC_SYMBOLS_decl
= start_decl (get_identifier ("_OBJC_SYMBOLS"),
1598 tree_cons (NULL_TREE
,
1599 objc_symtab_template
, sc_spec
),
1603 TREE_USED (UOBJC_SYMBOLS_decl
) = 1;
1604 DECL_IGNORED_P (UOBJC_SYMBOLS_decl
) = 1;
1605 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl
) = 1;
1606 finish_decl (UOBJC_SYMBOLS_decl
,
1607 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)),
1612 init_module_descriptor (type
)
1615 tree initlist
, expr
;
1617 /* version = { 1, ... } */
1619 expr
= build_int_2 (OBJC_VERSION
, 0);
1620 initlist
= build_tree_list (NULL_TREE
, expr
);
1622 /* size = { ..., sizeof (struct objc_module), ... } */
1624 expr
= size_in_bytes (objc_module_template
);
1625 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1627 /* name = { ..., "foo.m", ... } */
1629 expr
= add_objc_string (get_identifier (input_filename
), class_names
);
1630 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1632 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1634 if (UOBJC_SYMBOLS_decl
)
1635 expr
= build_unary_op (ADDR_EXPR
, UOBJC_SYMBOLS_decl
, 0);
1637 expr
= build_int_2 (0, 0);
1638 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1640 return build_constructor (type
, nreverse (initlist
));
1643 /* Write out the data structures to describe Objective C classes defined.
1644 If appropriate, compile and output a setup function to initialize them.
1645 Return a symbol_ref to the function to call to initialize the Objective C
1646 data structures for this file (and perhaps for other files also).
1648 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1651 build_module_descriptor ()
1653 tree decl_specs
, field_decl
, field_decl_chain
;
1655 objc_module_template
1656 = start_struct (RECORD_TYPE
, get_identifier (UTAG_MODULE
));
1660 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1661 field_decl
= get_identifier ("version");
1663 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1664 field_decl_chain
= field_decl
;
1668 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1669 field_decl
= get_identifier ("size");
1671 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1672 chainon (field_decl_chain
, field_decl
);
1676 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
1677 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
1679 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1680 chainon (field_decl_chain
, field_decl
);
1682 /* struct objc_symtab *symtab; */
1684 decl_specs
= get_identifier (UTAG_SYMTAB
);
1685 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
1686 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("symtab"));
1688 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1689 chainon (field_decl_chain
, field_decl
);
1691 finish_struct (objc_module_template
, field_decl_chain
, NULL_TREE
);
1693 /* Create an instance of "objc_module". */
1695 decl_specs
= tree_cons (NULL_TREE
, objc_module_template
,
1696 build_tree_list (NULL_TREE
,
1697 ridpointers
[(int) RID_STATIC
]));
1699 UOBJC_MODULES_decl
= start_decl (get_identifier ("_OBJC_MODULES"),
1700 decl_specs
, 1, NULL_TREE
);
1702 DECL_ARTIFICIAL (UOBJC_MODULES_decl
) = 1;
1703 DECL_IGNORED_P (UOBJC_MODULES_decl
) = 1;
1704 DECL_CONTEXT (UOBJC_MODULES_decl
) = NULL_TREE
;
1706 finish_decl (UOBJC_MODULES_decl
,
1707 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl
)),
1710 /* Mark the decl to avoid "defined but not used" warning. */
1711 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl
) = 1;
1713 /* Generate a constructor call for the module descriptor.
1714 This code was generated by reading the grammar rules
1715 of c-parse.in; Therefore, it may not be the most efficient
1716 way of generating the requisite code. */
1718 if (flag_next_runtime
)
1722 tree parms
, execclass_decl
, decelerator
, void_list_node_1
;
1723 tree init_function_name
, init_function_decl
;
1725 /* Declare void __objc_execClass (void *); */
1727 void_list_node_1
= build_tree_list (NULL_TREE
, void_type_node
);
1728 execclass_decl
= build_decl (FUNCTION_DECL
,
1729 get_identifier (TAG_EXECCLASS
),
1730 build_function_type (void_type_node
,
1731 tree_cons (NULL_TREE
, ptr_type_node
,
1732 void_list_node_1
)));
1733 DECL_EXTERNAL (execclass_decl
) = 1;
1734 DECL_ARTIFICIAL (execclass_decl
) = 1;
1735 TREE_PUBLIC (execclass_decl
) = 1;
1736 pushdecl (execclass_decl
);
1737 rest_of_decl_compilation (execclass_decl
, 0, 0, 0);
1738 assemble_external (execclass_decl
);
1740 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1742 init_function_name
= get_file_function_name ('I');
1743 start_function (void_list_node_1
,
1744 build_nt (CALL_EXPR
, init_function_name
,
1745 tree_cons (NULL_TREE
, NULL_TREE
,
1749 store_parm_decls ();
1751 init_function_decl
= current_function_decl
;
1752 TREE_PUBLIC (init_function_decl
) = ! targetm
.have_ctors_dtors
;
1753 TREE_USED (init_function_decl
) = 1;
1754 current_function_cannot_inline
1755 = "static constructors and destructors cannot be inlined";
1758 = build_tree_list (NULL_TREE
,
1759 build_unary_op (ADDR_EXPR
, UOBJC_MODULES_decl
, 0));
1760 decelerator
= build_function_call (execclass_decl
, parms
);
1762 c_expand_expr_stmt (decelerator
);
1764 finish_function (0);
1766 return XEXP (DECL_RTL (init_function_decl
), 0);
1770 /* extern const char _OBJC_STRINGS[]; */
1773 generate_forward_declaration_to_string_table ()
1775 tree sc_spec
, decl_specs
, expr_decl
;
1777 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_EXTERN
], NULL_TREE
);
1778 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1781 = build_nt (ARRAY_REF
, get_identifier ("_OBJC_STRINGS"), NULL_TREE
);
1783 UOBJC_STRINGS_decl
= define_decl (expr_decl
, decl_specs
);
1786 /* Return the DECL of the string IDENT in the SECTION. */
1789 get_objc_string_decl (ident
, section
)
1791 enum string_section section
;
1795 if (section
== class_names
)
1796 chain
= class_names_chain
;
1797 else if (section
== meth_var_names
)
1798 chain
= meth_var_names_chain
;
1799 else if (section
== meth_var_types
)
1800 chain
= meth_var_types_chain
;
1804 for (; chain
!= 0; chain
= TREE_VALUE (chain
))
1805 if (TREE_VALUE (chain
) == ident
)
1806 return (TREE_PURPOSE (chain
));
1812 /* Output references to all statically allocated objects. Return the DECL
1813 for the array built. */
1816 generate_static_references ()
1818 tree decls
= NULL_TREE
, ident
, decl_spec
, expr_decl
, expr
= NULL_TREE
;
1819 tree class_name
, class, decl
, initlist
;
1820 tree cl_chain
, in_chain
, type
;
1821 int num_inst
, num_class
;
1824 if (flag_next_runtime
)
1827 for (cl_chain
= objc_static_instances
, num_class
= 0;
1828 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
1830 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
1831 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
1833 sprintf (buf
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
1834 ident
= get_identifier (buf
);
1836 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1837 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1838 build_tree_list (NULL_TREE
,
1839 ridpointers
[(int) RID_STATIC
]));
1840 decl
= start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
);
1841 DECL_CONTEXT (decl
) = 0;
1842 DECL_ARTIFICIAL (decl
) = 1;
1844 /* Output {class_name, ...}. */
1845 class = TREE_VALUE (cl_chain
);
1846 class_name
= get_objc_string_decl (TYPE_NAME (class), class_names
);
1847 initlist
= build_tree_list (NULL_TREE
,
1848 build_unary_op (ADDR_EXPR
, class_name
, 1));
1850 /* Output {..., instance, ...}. */
1851 for (in_chain
= TREE_PURPOSE (cl_chain
);
1852 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
1854 expr
= build_unary_op (ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
1855 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1858 /* Output {..., NULL}. */
1859 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1861 expr
= build_constructor (TREE_TYPE (decl
), nreverse (initlist
));
1862 finish_decl (decl
, expr
, NULL_TREE
);
1863 TREE_USED (decl
) = 1;
1865 type
= build_array_type (build_pointer_type (void_type_node
), 0);
1866 decl
= build_decl (VAR_DECL
, ident
, type
);
1867 TREE_USED (decl
) = 1;
1868 TREE_STATIC (decl
) = 1;
1870 = tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, decl
, 1), decls
);
1873 decls
= tree_cons (NULL_TREE
, build_int_2 (0, 0), decls
);
1874 ident
= get_identifier ("_OBJC_STATIC_INSTANCES");
1875 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1876 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1877 build_tree_list (NULL_TREE
,
1878 ridpointers
[(int) RID_STATIC
]));
1879 static_instances_decl
1880 = start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
);
1881 TREE_USED (static_instances_decl
) = 1;
1882 DECL_CONTEXT (static_instances_decl
) = 0;
1883 DECL_ARTIFICIAL (static_instances_decl
) = 1;
1884 expr
= build_constructor (TREE_TYPE (static_instances_decl
),
1886 finish_decl (static_instances_decl
, expr
, NULL_TREE
);
1889 /* Output all strings. */
1894 tree sc_spec
, decl_specs
, expr_decl
;
1895 tree chain
, string_expr
;
1898 for (chain
= class_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1900 string
= TREE_VALUE (chain
);
1901 decl
= TREE_PURPOSE (chain
);
1903 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1904 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1905 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1906 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1907 DECL_CONTEXT (decl
) = NULL_TREE
;
1908 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1909 IDENTIFIER_POINTER (string
));
1910 finish_decl (decl
, string_expr
, NULL_TREE
);
1913 for (chain
= meth_var_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1915 string
= TREE_VALUE (chain
);
1916 decl
= TREE_PURPOSE (chain
);
1918 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1919 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1920 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1921 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1922 DECL_CONTEXT (decl
) = NULL_TREE
;
1923 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1924 IDENTIFIER_POINTER (string
));
1925 finish_decl (decl
, string_expr
, NULL_TREE
);
1928 for (chain
= meth_var_types_chain
; chain
; chain
= TREE_CHAIN (chain
))
1930 string
= TREE_VALUE (chain
);
1931 decl
= TREE_PURPOSE (chain
);
1933 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1934 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1935 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1936 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1937 DECL_CONTEXT (decl
) = NULL_TREE
;
1938 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1939 IDENTIFIER_POINTER (string
));
1940 finish_decl (decl
, string_expr
, NULL_TREE
);
1945 build_selector_reference_decl ()
1951 sprintf (buf
, "_OBJC_SELECTOR_REFERENCES_%d", idx
++);
1953 ident
= get_identifier (buf
);
1955 decl
= build_decl (VAR_DECL
, ident
, selector_type
);
1956 DECL_EXTERNAL (decl
) = 1;
1957 TREE_PUBLIC (decl
) = 1;
1958 TREE_USED (decl
) = 1;
1959 TREE_READONLY (decl
) = 1;
1960 DECL_ARTIFICIAL (decl
) = 1;
1961 DECL_CONTEXT (decl
) = 0;
1963 make_decl_rtl (decl
, 0);
1964 pushdecl_top_level (decl
);
1969 /* Just a handy wrapper for add_objc_string. */
1972 build_selector (ident
)
1975 tree expr
= add_objc_string (ident
, meth_var_names
);
1976 if (flag_typed_selectors
)
1979 return build_c_cast (selector_type
, expr
); /* cast! */
1983 build_selector_translation_table ()
1985 tree sc_spec
, decl_specs
;
1986 tree chain
, initlist
= NULL_TREE
;
1988 tree decl
= NULL_TREE
, var_decl
, name
;
1990 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
1994 expr
= build_selector (TREE_VALUE (chain
));
1996 if (flag_next_runtime
)
1998 name
= DECL_NAME (TREE_PURPOSE (chain
));
2000 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
2002 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2003 decl_specs
= tree_cons (NULL_TREE
, selector_type
, sc_spec
);
2007 /* The `decl' that is returned from start_decl is the one that we
2008 forward declared in `build_selector_reference' */
2009 decl
= start_decl (var_decl
, decl_specs
, 1, NULL_TREE
);
2012 /* add one for the '\0' character */
2013 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (chain
)) + 1;
2015 if (flag_next_runtime
)
2016 finish_decl (decl
, expr
, NULL_TREE
);
2019 if (flag_typed_selectors
)
2021 tree eltlist
= NULL_TREE
;
2022 tree encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
2023 eltlist
= tree_cons (NULL_TREE
, expr
, NULL_TREE
);
2024 eltlist
= tree_cons (NULL_TREE
, encoding
, eltlist
);
2025 expr
= build_constructor (objc_selector_template
,
2026 nreverse (eltlist
));
2028 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2033 if (! flag_next_runtime
)
2035 /* Cause the variable and its initial value to be actually output. */
2036 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl
) = 0;
2037 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl
) = 1;
2038 /* NULL terminate the list and fix the decl for output. */
2039 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
2040 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl
) = objc_ellipsis_node
;
2041 initlist
= build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
2042 nreverse (initlist
));
2043 finish_decl (UOBJC_SELECTOR_TABLE_decl
, initlist
, NULL_TREE
);
2044 current_function_decl
= NULL_TREE
;
2049 get_proto_encoding (proto
)
2057 if (! METHOD_ENCODING (proto
))
2059 tmp_decl
= build_tmp_function_decl ();
2060 hack_method_prototype (proto
, tmp_decl
);
2061 encoding
= encode_method_prototype (proto
, tmp_decl
);
2062 METHOD_ENCODING (proto
) = encoding
;
2065 encoding
= METHOD_ENCODING (proto
);
2067 return add_objc_string (encoding
, meth_var_types
);
2070 return build_int_2 (0, 0);
2073 /* sel_ref_chain is a list whose "value" fields will be instances of
2074 identifier_node that represent the selector. */
2077 build_typed_selector_reference (ident
, proto
)
2080 tree
*chain
= &sel_ref_chain
;
2086 if (TREE_PURPOSE (*chain
) == ident
&& TREE_VALUE (*chain
) == proto
)
2087 goto return_at_index
;
2090 chain
= &TREE_CHAIN (*chain
);
2093 *chain
= tree_cons (proto
, ident
, NULL_TREE
);
2096 expr
= build_unary_op (ADDR_EXPR
,
2097 build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2098 build_int_2 (index
, 0)),
2100 return build_c_cast (selector_type
, expr
);
2104 build_selector_reference (ident
)
2107 tree
*chain
= &sel_ref_chain
;
2113 if (TREE_VALUE (*chain
) == ident
)
2114 return (flag_next_runtime
2115 ? TREE_PURPOSE (*chain
)
2116 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2117 build_int_2 (index
, 0)));
2120 chain
= &TREE_CHAIN (*chain
);
2123 expr
= build_selector_reference_decl ();
2125 *chain
= tree_cons (expr
, ident
, NULL_TREE
);
2127 return (flag_next_runtime
2129 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2130 build_int_2 (index
, 0)));
2134 build_class_reference_decl ()
2140 sprintf (buf
, "_OBJC_CLASS_REFERENCES_%d", idx
++);
2142 ident
= get_identifier (buf
);
2144 decl
= build_decl (VAR_DECL
, ident
, objc_class_type
);
2145 DECL_EXTERNAL (decl
) = 1;
2146 TREE_PUBLIC (decl
) = 1;
2147 TREE_USED (decl
) = 1;
2148 TREE_READONLY (decl
) = 1;
2149 DECL_CONTEXT (decl
) = 0;
2150 DECL_ARTIFICIAL (decl
) = 1;
2152 make_decl_rtl (decl
, 0);
2153 pushdecl_top_level (decl
);
2158 /* Create a class reference, but don't create a variable to reference
2162 add_class_reference (ident
)
2167 if ((chain
= cls_ref_chain
))
2172 if (ident
== TREE_VALUE (chain
))
2176 chain
= TREE_CHAIN (chain
);
2180 /* Append to the end of the list */
2181 TREE_CHAIN (tail
) = tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2184 cls_ref_chain
= tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2187 /* Get a class reference, creating it if necessary. Also create the
2188 reference variable. */
2191 get_class_reference (ident
)
2194 if (flag_next_runtime
)
2199 for (chain
= &cls_ref_chain
; *chain
; chain
= &TREE_CHAIN (*chain
))
2200 if (TREE_VALUE (*chain
) == ident
)
2202 if (! TREE_PURPOSE (*chain
))
2203 TREE_PURPOSE (*chain
) = build_class_reference_decl ();
2205 return TREE_PURPOSE (*chain
);
2208 decl
= build_class_reference_decl ();
2209 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2216 add_class_reference (ident
);
2218 params
= build_tree_list (NULL_TREE
,
2219 my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
2220 IDENTIFIER_POINTER (ident
)));
2222 assemble_external (objc_get_class_decl
);
2223 return build_function_call (objc_get_class_decl
, params
);
2227 /* For each string section we have a chain which maps identifier nodes
2228 to decls for the strings. */
2231 add_objc_string (ident
, section
)
2233 enum string_section section
;
2237 if (section
== class_names
)
2238 chain
= &class_names_chain
;
2239 else if (section
== meth_var_names
)
2240 chain
= &meth_var_names_chain
;
2241 else if (section
== meth_var_types
)
2242 chain
= &meth_var_types_chain
;
2248 if (TREE_VALUE (*chain
) == ident
)
2249 return build_unary_op (ADDR_EXPR
, TREE_PURPOSE (*chain
), 1);
2251 chain
= &TREE_CHAIN (*chain
);
2254 decl
= build_objc_string_decl (section
);
2256 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2258 return build_unary_op (ADDR_EXPR
, decl
, 1);
2262 build_objc_string_decl (section
)
2263 enum string_section section
;
2267 static int class_names_idx
= 0;
2268 static int meth_var_names_idx
= 0;
2269 static int meth_var_types_idx
= 0;
2271 if (section
== class_names
)
2272 sprintf (buf
, "_OBJC_CLASS_NAME_%d", class_names_idx
++);
2273 else if (section
== meth_var_names
)
2274 sprintf (buf
, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx
++);
2275 else if (section
== meth_var_types
)
2276 sprintf (buf
, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx
++);
2278 ident
= get_identifier (buf
);
2280 decl
= build_decl (VAR_DECL
, ident
, build_array_type (char_type_node
, 0));
2281 DECL_EXTERNAL (decl
) = 1;
2282 TREE_PUBLIC (decl
) = 1;
2283 TREE_USED (decl
) = 1;
2284 TREE_READONLY (decl
) = 1;
2285 TREE_CONSTANT (decl
) = 1;
2286 DECL_CONTEXT (decl
) = 0;
2287 DECL_ARTIFICIAL (decl
) = 1;
2289 make_decl_rtl (decl
, 0);
2290 pushdecl_top_level (decl
);
2297 objc_declare_alias (alias_ident
, class_ident
)
2301 if (is_class_name (class_ident
) != class_ident
)
2302 warning ("Cannot find class `%s'", IDENTIFIER_POINTER (class_ident
));
2303 else if (is_class_name (alias_ident
))
2304 warning ("Class `%s' already exists", IDENTIFIER_POINTER (alias_ident
));
2306 alias_chain
= tree_cons (class_ident
, alias_ident
, alias_chain
);
2310 objc_declare_class (ident_list
)
2315 for (list
= ident_list
; list
; list
= TREE_CHAIN (list
))
2317 tree ident
= TREE_VALUE (list
);
2320 if ((decl
= lookup_name (ident
)))
2322 error ("`%s' redeclared as different kind of symbol",
2323 IDENTIFIER_POINTER (ident
));
2324 error_with_decl (decl
, "previous declaration of `%s'");
2327 if (! is_class_name (ident
))
2329 tree record
= xref_tag (RECORD_TYPE
, ident
);
2330 TREE_STATIC_TEMPLATE (record
) = 1;
2331 class_chain
= tree_cons (NULL_TREE
, ident
, class_chain
);
2337 is_class_name (ident
)
2342 if (lookup_interface (ident
))
2345 for (chain
= class_chain
; chain
; chain
= TREE_CHAIN (chain
))
2347 if (ident
== TREE_VALUE (chain
))
2351 for (chain
= alias_chain
; chain
; chain
= TREE_CHAIN (chain
))
2353 if (ident
== TREE_VALUE (chain
))
2354 return TREE_PURPOSE (chain
);
2361 lookup_interface (ident
)
2366 for (chain
= interface_chain
; chain
; chain
= TREE_CHAIN (chain
))
2368 if (ident
== CLASS_NAME (chain
))
2375 objc_copy_list (list
, head
)
2379 tree newlist
= NULL_TREE
, tail
= NULL_TREE
;
2383 tail
= copy_node (list
);
2385 /* The following statement fixes a bug when inheriting instance
2386 variables that are declared to be bitfields. finish_struct
2387 expects to find the width of the bitfield in DECL_INITIAL. */
2388 if (DECL_BIT_FIELD (tail
) && DECL_INITIAL (tail
) == 0)
2389 DECL_INITIAL (tail
) = DECL_SIZE (tail
);
2391 newlist
= chainon (newlist
, tail
);
2392 list
= TREE_CHAIN (list
);
2399 /* Used by: build_private_template, get_class_ivars, and
2400 continue_class. COPY is 1 when called from @defs. In this case
2401 copy all fields. Otherwise don't copy leaf ivars since we rely on
2402 them being side-effected exactly once by finish_struct. */
2405 build_ivar_chain (interface
, copy
)
2409 tree my_name
, super_name
, ivar_chain
;
2411 my_name
= CLASS_NAME (interface
);
2412 super_name
= CLASS_SUPER_NAME (interface
);
2414 /* Possibly copy leaf ivars. */
2416 objc_copy_list (CLASS_IVARS (interface
), &ivar_chain
);
2418 ivar_chain
= CLASS_IVARS (interface
);
2423 tree super_interface
= lookup_interface (super_name
);
2425 if (!super_interface
)
2427 /* fatal did not work with 2 args...should fix */
2428 error ("Cannot find interface declaration for `%s', superclass of `%s'",
2429 IDENTIFIER_POINTER (super_name
),
2430 IDENTIFIER_POINTER (my_name
));
2431 exit (FATAL_EXIT_CODE
);
2434 if (super_interface
== interface
)
2435 fatal_error ("Circular inheritance in interface declaration for `%s'",
2436 IDENTIFIER_POINTER (super_name
));
2438 interface
= super_interface
;
2439 my_name
= CLASS_NAME (interface
);
2440 super_name
= CLASS_SUPER_NAME (interface
);
2442 op1
= CLASS_IVARS (interface
);
2445 tree head
, tail
= objc_copy_list (op1
, &head
);
2447 /* Prepend super class ivars...make a copy of the list, we
2448 do not want to alter the original. */
2449 TREE_CHAIN (tail
) = ivar_chain
;
2456 /* struct <classname> {
2457 struct objc_class *isa;
2462 build_private_template (class)
2467 if (CLASS_STATIC_TEMPLATE (class))
2469 uprivate_record
= CLASS_STATIC_TEMPLATE (class);
2470 ivar_context
= TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2474 uprivate_record
= start_struct (RECORD_TYPE
, CLASS_NAME (class));
2476 ivar_context
= build_ivar_chain (class, 0);
2478 finish_struct (uprivate_record
, ivar_context
, NULL_TREE
);
2480 CLASS_STATIC_TEMPLATE (class) = uprivate_record
;
2482 /* mark this record as class template - for class type checking */
2483 TREE_STATIC_TEMPLATE (uprivate_record
) = 1;
2487 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
2489 build1 (INDIRECT_REF
, NULL_TREE
,
2492 return ivar_context
;
2495 /* Begin code generation for protocols... */
2497 /* struct objc_protocol {
2498 char *protocol_name;
2499 struct objc_protocol **protocol_list;
2500 struct objc_method_desc *instance_methods;
2501 struct objc_method_desc *class_methods;
2505 build_protocol_template ()
2507 tree decl_specs
, field_decl
, field_decl_chain
;
2510 template = start_struct (RECORD_TYPE
, get_identifier (UTAG_PROTOCOL
));
2512 /* struct objc_class *isa; */
2514 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2515 get_identifier (UTAG_CLASS
)));
2516 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
2518 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2519 field_decl_chain
= field_decl
;
2521 /* char *protocol_name; */
2523 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
2525 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_name"));
2527 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2528 chainon (field_decl_chain
, field_decl
);
2530 /* struct objc_protocol **protocol_list; */
2532 decl_specs
= build_tree_list (NULL_TREE
, template);
2534 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
2535 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
2537 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2538 chainon (field_decl_chain
, field_decl
);
2540 /* struct objc_method_list *instance_methods; */
2543 = build_tree_list (NULL_TREE
,
2544 xref_tag (RECORD_TYPE
,
2545 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2547 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
2549 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2550 chainon (field_decl_chain
, field_decl
);
2552 /* struct objc_method_list *class_methods; */
2555 = build_tree_list (NULL_TREE
,
2556 xref_tag (RECORD_TYPE
,
2557 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2559 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
2561 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2562 chainon (field_decl_chain
, field_decl
);
2564 return finish_struct (template, field_decl_chain
, NULL_TREE
);
2568 build_descriptor_table_initializer (type
, entries
)
2572 tree initlist
= NULL_TREE
;
2576 tree eltlist
= NULL_TREE
;
2579 = tree_cons (NULL_TREE
,
2580 build_selector (METHOD_SEL_NAME (entries
)), NULL_TREE
);
2582 = tree_cons (NULL_TREE
,
2583 add_objc_string (METHOD_ENCODING (entries
),
2588 = tree_cons (NULL_TREE
,
2589 build_constructor (type
, nreverse (eltlist
)), initlist
);
2591 entries
= TREE_CHAIN (entries
);
2595 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
2598 /* struct objc_method_prototype_list {
2600 struct objc_method_prototype {
2607 build_method_prototype_list_template (list_type
, size
)
2611 tree objc_ivar_list_record
;
2612 tree decl_specs
, field_decl
, field_decl_chain
;
2614 /* Generate an unnamed struct definition. */
2616 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
2618 /* int method_count; */
2620 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
2621 field_decl
= get_identifier ("method_count");
2624 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2625 field_decl_chain
= field_decl
;
2627 /* struct objc_method method_list[]; */
2629 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
2630 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
2631 build_int_2 (size
, 0));
2634 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2635 chainon (field_decl_chain
, field_decl
);
2637 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
2639 return objc_ivar_list_record
;
2643 build_method_prototype_template ()
2646 tree decl_specs
, field_decl
, field_decl_chain
;
2649 = start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD_PROTOTYPE
));
2651 /* struct objc_selector *_cmd; */
2652 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
2653 get_identifier (TAG_SELECTOR
)), NULL_TREE
);
2654 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
2657 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2658 field_decl_chain
= field_decl
;
2660 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
2662 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_types"));
2664 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2665 chainon (field_decl_chain
, field_decl
);
2667 finish_struct (proto_record
, field_decl_chain
, NULL_TREE
);
2669 return proto_record
;
2672 /* True if last call to forwarding_offset yielded a register offset. */
2673 static int offset_is_register
;
2676 forwarding_offset (parm
)
2679 int offset_in_bytes
;
2681 if (GET_CODE (DECL_INCOMING_RTL (parm
)) == MEM
)
2683 rtx addr
= XEXP (DECL_INCOMING_RTL (parm
), 0);
2685 /* ??? Here we assume that the parm address is indexed
2686 off the frame pointer or arg pointer.
2687 If that is not true, we produce meaningless results,
2688 but do not crash. */
2689 if (GET_CODE (addr
) == PLUS
2690 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
2691 offset_in_bytes
= INTVAL (XEXP (addr
, 1));
2693 offset_in_bytes
= 0;
2695 offset_in_bytes
+= OBJC_FORWARDING_STACK_OFFSET
;
2696 offset_is_register
= 0;
2698 else if (GET_CODE (DECL_INCOMING_RTL (parm
)) == REG
)
2700 int regno
= REGNO (DECL_INCOMING_RTL (parm
));
2701 offset_in_bytes
= apply_args_register_offset (regno
);
2702 offset_is_register
= 1;
2707 /* This is the case where the parm is passed as an int or double
2708 and it is converted to a char, short or float and stored back
2709 in the parmlist. In this case, describe the parm
2710 with the variable's declared type, and adjust the address
2711 if the least significant bytes (which we are using) are not
2713 if (BYTES_BIG_ENDIAN
&& TREE_TYPE (parm
) != DECL_ARG_TYPE (parm
))
2714 offset_in_bytes
+= (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm
)))
2715 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm
))));
2717 return offset_in_bytes
;
2721 encode_method_prototype (method_decl
, func_decl
)
2728 HOST_WIDE_INT max_parm_end
= 0;
2732 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2733 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl
)));
2736 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
2737 obstack_object_size (&util_obstack
),
2738 OBJC_ENCODE_INLINE_DEFS
);
2741 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
2742 parms
= TREE_CHAIN (parms
))
2744 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
2745 + int_size_in_bytes (TREE_TYPE (parms
)));
2747 if (!offset_is_register
&& max_parm_end
< parm_end
)
2748 max_parm_end
= parm_end
;
2751 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
2753 sprintf (buf
, "%d", stack_size
);
2754 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2756 user_args
= METHOD_SEL_ARGS (method_decl
);
2758 /* Argument types. */
2759 for (parms
= DECL_ARGUMENTS (func_decl
), i
= 0; parms
;
2760 parms
= TREE_CHAIN (parms
), i
++)
2762 /* Process argument qualifiers for user supplied arguments. */
2765 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args
)));
2766 user_args
= TREE_CHAIN (user_args
);
2770 encode_type (TREE_TYPE (parms
),
2771 obstack_object_size (&util_obstack
),
2772 OBJC_ENCODE_INLINE_DEFS
);
2774 /* Compute offset. */
2775 sprintf (buf
, "%d", forwarding_offset (parms
));
2777 /* Indicate register. */
2778 if (offset_is_register
)
2779 obstack_1grow (&util_obstack
, '+');
2781 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2784 obstack_1grow (&util_obstack
, '\0');
2785 result
= get_identifier (obstack_finish (&util_obstack
));
2786 obstack_free (&util_obstack
, util_firstobj
);
2791 generate_descriptor_table (type
, name
, size
, list
, proto
)
2798 tree sc_spec
, decl_specs
, decl
, initlist
;
2800 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2801 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
2803 decl
= start_decl (synth_id_with_class_suffix (name
, proto
),
2804 decl_specs
, 1, NULL_TREE
);
2805 DECL_CONTEXT (decl
) = NULL_TREE
;
2807 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
2808 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
2810 finish_decl (decl
, build_constructor (type
, nreverse (initlist
)),
2817 generate_method_descriptors (protocol
) /* generate_dispatch_tables */
2820 tree initlist
, chain
, method_list_template
;
2821 tree cast
, variable_length_type
;
2824 if (!objc_method_prototype_template
)
2826 objc_method_prototype_template
= build_method_prototype_template ();
2829 cast
= build_tree_list (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2830 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
))),
2832 variable_length_type
= groktypename (cast
);
2834 chain
= PROTOCOL_CLS_METHODS (protocol
);
2837 size
= list_length (chain
);
2839 method_list_template
2840 = build_method_prototype_list_template (objc_method_prototype_template
,
2844 = build_descriptor_table_initializer (objc_method_prototype_template
,
2847 UOBJC_CLASS_METHODS_decl
2848 = generate_descriptor_table (method_list_template
,
2849 "_OBJC_PROTOCOL_CLASS_METHODS",
2850 size
, initlist
, protocol
);
2851 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
2854 UOBJC_CLASS_METHODS_decl
= 0;
2856 chain
= PROTOCOL_NST_METHODS (protocol
);
2859 size
= list_length (chain
);
2861 method_list_template
2862 = build_method_prototype_list_template (objc_method_prototype_template
,
2865 = build_descriptor_table_initializer (objc_method_prototype_template
,
2868 UOBJC_INSTANCE_METHODS_decl
2869 = generate_descriptor_table (method_list_template
,
2870 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2871 size
, initlist
, protocol
);
2872 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
2875 UOBJC_INSTANCE_METHODS_decl
= 0;
2878 /* Generate a temporary FUNCTION_DECL node to be used in
2879 hack_method_prototype below. */
2882 build_tmp_function_decl ()
2884 tree decl_specs
, expr_decl
, parms
;
2888 /* struct objc_object *objc_xxx (id, SEL, ...); */
2890 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
2891 push_parm_decl (build_tree_list
2892 (build_tree_list (decl_specs
,
2893 build1 (INDIRECT_REF
, NULL_TREE
,
2897 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2898 get_identifier (TAG_SELECTOR
)));
2899 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
);
2901 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, expr_decl
),
2903 parms
= get_parm_info (0);
2906 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
2907 sprintf (buffer
, "__objc_tmp_%x", xxx
++);
2908 expr_decl
= build_nt (CALL_EXPR
, get_identifier (buffer
), parms
, NULL_TREE
);
2909 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
2911 return define_decl (expr_decl
, decl_specs
);
2914 /* Generate the prototypes for protocol methods. This is used to
2915 generate method encodings for these.
2917 NST_METHODS is the method to generate a _DECL node for TMP_DECL is
2918 a decl node to be used. This is also where the return value is
2922 hack_method_prototype (nst_methods
, tmp_decl
)
2929 /* Hack to avoid problem with static typing of self arg. */
2930 TREE_SET_CODE (nst_methods
, CLASS_METHOD_DECL
);
2931 start_method_def (nst_methods
);
2932 TREE_SET_CODE (nst_methods
, INSTANCE_METHOD_DECL
);
2934 if (METHOD_ADD_ARGS (nst_methods
) == objc_ellipsis_node
)
2935 parms
= get_parm_info (0); /* we have a `, ...' */
2937 parms
= get_parm_info (1); /* place a `void_at_end' */
2939 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2941 /* Usually called from store_parm_decls -> init_function_start. */
2943 DECL_ARGUMENTS (tmp_decl
) = TREE_PURPOSE (parms
);
2944 current_function_decl
= tmp_decl
;
2947 /* Code taken from start_function. */
2948 tree restype
= TREE_TYPE (TREE_TYPE (tmp_decl
));
2949 /* Promote the value to int before returning it. */
2950 if (TREE_CODE (restype
) == INTEGER_TYPE
2951 && TYPE_PRECISION (restype
) < TYPE_PRECISION (integer_type_node
))
2952 restype
= integer_type_node
;
2953 DECL_RESULT (tmp_decl
) = build_decl (RESULT_DECL
, 0, restype
);
2956 for (parm
= DECL_ARGUMENTS (tmp_decl
); parm
; parm
= TREE_CHAIN (parm
))
2957 DECL_CONTEXT (parm
) = tmp_decl
;
2959 init_function_start (tmp_decl
, "objc-act", 0);
2961 /* Typically called from expand_function_start for function definitions. */
2962 assign_parms (tmp_decl
);
2964 /* install return type */
2965 TREE_TYPE (TREE_TYPE (tmp_decl
)) = groktypename (TREE_TYPE (nst_methods
));
2970 generate_protocol_references (plist
)
2975 /* Forward declare protocols referenced. */
2976 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
2978 tree proto
= TREE_VALUE (lproto
);
2980 if (TREE_CODE (proto
) == PROTOCOL_INTERFACE_TYPE
2981 && PROTOCOL_NAME (proto
))
2983 if (! PROTOCOL_FORWARD_DECL (proto
))
2984 build_protocol_reference (proto
);
2986 if (PROTOCOL_LIST (proto
))
2987 generate_protocol_references (PROTOCOL_LIST (proto
));
2993 generate_protocols ()
2995 tree p
, tmp_decl
, encoding
;
2996 tree sc_spec
, decl_specs
, decl
;
2997 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
3000 tmp_decl
= build_tmp_function_decl ();
3002 if (! objc_protocol_template
)
3003 objc_protocol_template
= build_protocol_template ();
3005 /* If a protocol was directly referenced, pull in indirect references. */
3006 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3007 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
3008 generate_protocol_references (PROTOCOL_LIST (p
));
3010 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3012 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
3013 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
3015 /* If protocol wasn't referenced, don't generate any code. */
3016 if (! PROTOCOL_FORWARD_DECL (p
))
3019 /* Make sure we link in the Protocol class. */
3020 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
3024 if (! METHOD_ENCODING (nst_methods
))
3026 hack_method_prototype (nst_methods
, tmp_decl
);
3027 encoding
= encode_method_prototype (nst_methods
, tmp_decl
);
3028 METHOD_ENCODING (nst_methods
) = encoding
;
3030 nst_methods
= TREE_CHAIN (nst_methods
);
3035 if (! METHOD_ENCODING (cls_methods
))
3037 hack_method_prototype (cls_methods
, tmp_decl
);
3038 encoding
= encode_method_prototype (cls_methods
, tmp_decl
);
3039 METHOD_ENCODING (cls_methods
) = encoding
;
3042 cls_methods
= TREE_CHAIN (cls_methods
);
3044 generate_method_descriptors (p
);
3046 if (PROTOCOL_LIST (p
))
3047 refs_decl
= generate_protocol_list (p
);
3051 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3053 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
],
3055 decl_specs
= tree_cons (NULL_TREE
, objc_protocol_template
, sc_spec
);
3057 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
),
3058 decl_specs
, 1, NULL_TREE
);
3060 DECL_CONTEXT (decl
) = NULL_TREE
;
3062 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
3068 (build_tree_list (build_tree_list (NULL_TREE
,
3069 objc_protocol_template
),
3070 build1 (INDIRECT_REF
, NULL_TREE
,
3071 build1 (INDIRECT_REF
, NULL_TREE
,
3074 refs_expr
= build_unary_op (ADDR_EXPR
, refs_decl
, 0);
3075 TREE_TYPE (refs_expr
) = cast_type2
;
3078 refs_expr
= build_int_2 (0, 0);
3080 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3081 by generate_method_descriptors, which is called above. */
3082 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
3083 protocol_name_expr
, refs_expr
,
3084 UOBJC_INSTANCE_METHODS_decl
,
3085 UOBJC_CLASS_METHODS_decl
);
3086 finish_decl (decl
, initlist
, NULL_TREE
);
3088 /* Mark the decl as used to avoid "defined but not used" warning. */
3089 TREE_USED (decl
) = 1;
3094 build_protocol_initializer (type
, protocol_name
, protocol_list
,
3095 instance_methods
, class_methods
)
3099 tree instance_methods
;
3102 tree initlist
= NULL_TREE
, expr
;
3105 cast_type
= groktypename
3107 (build_tree_list (NULL_TREE
,
3108 xref_tag (RECORD_TYPE
,
3109 get_identifier (UTAG_CLASS
))),
3110 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
3112 /* Filling the "isa" in with one allows the runtime system to
3113 detect that the version change...should remove before final release. */
3115 expr
= build_int_2 (PROTOCOL_VERSION
, 0);
3116 TREE_TYPE (expr
) = cast_type
;
3117 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3118 initlist
= tree_cons (NULL_TREE
, protocol_name
, initlist
);
3119 initlist
= tree_cons (NULL_TREE
, protocol_list
, initlist
);
3121 if (!instance_methods
)
3122 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3125 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
3126 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3130 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3133 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
3134 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3137 return build_constructor (type
, nreverse (initlist
));
3140 /* struct objc_category {
3141 char *category_name;
3143 struct objc_method_list *instance_methods;
3144 struct objc_method_list *class_methods;
3145 struct objc_protocol_list *protocols;
3149 build_category_template ()
3151 tree decl_specs
, field_decl
, field_decl_chain
;
3153 objc_category_template
= start_struct (RECORD_TYPE
,
3154 get_identifier (UTAG_CATEGORY
));
3155 /* char *category_name; */
3157 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3159 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("category_name"));
3161 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3162 field_decl_chain
= field_decl
;
3164 /* char *class_name; */
3166 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3167 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_name"));
3169 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3170 chainon (field_decl_chain
, field_decl
);
3172 /* struct objc_method_list *instance_methods; */
3174 decl_specs
= build_tree_list (NULL_TREE
,
3175 xref_tag (RECORD_TYPE
,
3176 get_identifier (UTAG_METHOD_LIST
)));
3178 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
3180 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3181 chainon (field_decl_chain
, field_decl
);
3183 /* struct objc_method_list *class_methods; */
3185 decl_specs
= build_tree_list (NULL_TREE
,
3186 xref_tag (RECORD_TYPE
,
3187 get_identifier (UTAG_METHOD_LIST
)));
3189 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
3191 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3192 chainon (field_decl_chain
, field_decl
);
3194 /* struct objc_protocol **protocol_list; */
3196 decl_specs
= build_tree_list (NULL_TREE
,
3197 xref_tag (RECORD_TYPE
,
3198 get_identifier (UTAG_PROTOCOL
)));
3200 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3201 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3203 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3204 chainon (field_decl_chain
, field_decl
);
3206 finish_struct (objc_category_template
, field_decl_chain
, NULL_TREE
);
3209 /* struct objc_selector {
3215 build_selector_template ()
3218 tree decl_specs
, field_decl
, field_decl_chain
;
3220 objc_selector_template
3221 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SELECTOR
));
3225 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3226 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3228 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3229 field_decl_chain
= field_decl
;
3231 /* char *sel_type; */
3233 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3234 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_type"));
3236 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3237 chainon (field_decl_chain
, field_decl
);
3239 finish_struct (objc_selector_template
, field_decl_chain
, NULL_TREE
);
3242 /* struct objc_class {
3243 struct objc_class *isa;
3244 struct objc_class *super_class;
3249 struct objc_ivar_list *ivars;
3250 struct objc_method_list *methods;
3251 if (flag_next_runtime)
3252 struct objc_cache *cache;
3254 struct sarray *dtable;
3255 struct objc_class *subclass_list;
3256 struct objc_class *sibling_class;
3258 struct objc_protocol_list *protocols;
3259 void *gc_object_type;
3263 build_class_template ()
3265 tree decl_specs
, field_decl
, field_decl_chain
;
3268 = start_struct (RECORD_TYPE
, get_identifier (UTAG_CLASS
));
3270 /* struct objc_class *isa; */
3272 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3273 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
3275 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3276 field_decl_chain
= field_decl
;
3278 /* struct objc_class *super_class; */
3280 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3282 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("super_class"));
3284 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3285 chainon (field_decl_chain
, field_decl
);
3289 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3290 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
3292 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3293 chainon (field_decl_chain
, field_decl
);
3297 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3298 field_decl
= get_identifier ("version");
3300 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3301 chainon (field_decl_chain
, field_decl
);
3305 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3306 field_decl
= get_identifier ("info");
3308 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3309 chainon (field_decl_chain
, field_decl
);
3311 /* long instance_size; */
3313 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3314 field_decl
= get_identifier ("instance_size");
3316 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3317 chainon (field_decl_chain
, field_decl
);
3319 /* struct objc_ivar_list *ivars; */
3321 decl_specs
= build_tree_list (NULL_TREE
,
3322 xref_tag (RECORD_TYPE
,
3323 get_identifier (UTAG_IVAR_LIST
)));
3324 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivars"));
3326 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3327 chainon (field_decl_chain
, field_decl
);
3329 /* struct objc_method_list *methods; */
3331 decl_specs
= build_tree_list (NULL_TREE
,
3332 xref_tag (RECORD_TYPE
,
3333 get_identifier (UTAG_METHOD_LIST
)));
3334 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("methods"));
3336 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3337 chainon (field_decl_chain
, field_decl
);
3339 if (flag_next_runtime
)
3341 /* struct objc_cache *cache; */
3343 decl_specs
= build_tree_list (NULL_TREE
,
3344 xref_tag (RECORD_TYPE
,
3345 get_identifier ("objc_cache")));
3346 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("cache"));
3347 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3348 decl_specs
, NULL_TREE
);
3349 chainon (field_decl_chain
, field_decl
);
3353 /* struct sarray *dtable; */
3355 decl_specs
= build_tree_list (NULL_TREE
,
3356 xref_tag (RECORD_TYPE
,
3357 get_identifier ("sarray")));
3358 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("dtable"));
3359 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3360 decl_specs
, NULL_TREE
);
3361 chainon (field_decl_chain
, field_decl
);
3363 /* struct objc_class *subclass_list; */
3365 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3367 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("subclass_list"));
3368 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3369 decl_specs
, NULL_TREE
);
3370 chainon (field_decl_chain
, field_decl
);
3372 /* struct objc_class *sibling_class; */
3374 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3376 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sibling_class"));
3377 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3378 decl_specs
, NULL_TREE
);
3379 chainon (field_decl_chain
, field_decl
);
3382 /* struct objc_protocol **protocol_list; */
3384 decl_specs
= build_tree_list (NULL_TREE
,
3385 xref_tag (RECORD_TYPE
,
3386 get_identifier (UTAG_PROTOCOL
)));
3388 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3390 = build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3391 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3392 decl_specs
, NULL_TREE
);
3393 chainon (field_decl_chain
, field_decl
);
3397 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3398 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3400 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3401 chainon (field_decl_chain
, field_decl
);
3403 /* void *gc_object_type; */
3405 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3406 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("gc_object_type"));
3408 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3409 chainon (field_decl_chain
, field_decl
);
3411 finish_struct (objc_class_template
, field_decl_chain
, NULL_TREE
);
3414 /* Generate appropriate forward declarations for an implementation. */
3417 synth_forward_declarations ()
3419 tree sc_spec
, decl_specs
, an_id
;
3421 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3423 an_id
= synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context
);
3425 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
3426 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
3427 UOBJC_CLASS_decl
= define_decl (an_id
, decl_specs
);
3428 TREE_USED (UOBJC_CLASS_decl
) = 1;
3429 DECL_ARTIFICIAL (UOBJC_CLASS_decl
) = 1;
3431 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3433 an_id
= synth_id_with_class_suffix ("_OBJC_METACLASS",
3434 objc_implementation_context
);
3436 UOBJC_METACLASS_decl
= define_decl (an_id
, decl_specs
);
3437 TREE_USED (UOBJC_METACLASS_decl
) = 1;
3438 DECL_ARTIFICIAL(UOBJC_METACLASS_decl
) = 1;
3440 /* Pre-build the following entities - for speed/convenience. */
3442 an_id
= get_identifier ("super_class");
3443 ucls_super_ref
= build_component_ref (UOBJC_CLASS_decl
, an_id
);
3444 uucls_super_ref
= build_component_ref (UOBJC_METACLASS_decl
, an_id
);
3448 error_with_ivar (message
, decl
, rawdecl
)
3449 const char *message
;
3455 report_error_function (DECL_SOURCE_FILE (decl
));
3457 error_with_file_and_line (DECL_SOURCE_FILE (decl
),
3458 DECL_SOURCE_LINE (decl
),
3460 message
, gen_declaration (rawdecl
, errbuf
));
3464 #define USERTYPE(t) \
3465 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3466 || TREE_CODE (t) == ENUMERAL_TYPE)
3469 check_ivars (inter
, imp
)
3473 tree intdecls
= CLASS_IVARS (inter
);
3474 tree impdecls
= CLASS_IVARS (imp
);
3475 tree rawintdecls
= CLASS_RAW_IVARS (inter
);
3476 tree rawimpdecls
= CLASS_RAW_IVARS (imp
);
3482 if (intdecls
== 0 && impdecls
== 0)
3484 if (intdecls
== 0 || impdecls
== 0)
3486 error ("inconsistent instance variable specification");
3490 t1
= TREE_TYPE (intdecls
); t2
= TREE_TYPE (impdecls
);
3492 if (!comptypes (t1
, t2
))
3494 if (DECL_NAME (intdecls
) == DECL_NAME (impdecls
))
3496 error_with_ivar ("conflicting instance variable type",
3497 impdecls
, rawimpdecls
);
3498 error_with_ivar ("previous declaration of",
3499 intdecls
, rawintdecls
);
3501 else /* both the type and the name don't match */
3503 error ("inconsistent instance variable specification");
3508 else if (DECL_NAME (intdecls
) != DECL_NAME (impdecls
))
3510 error_with_ivar ("conflicting instance variable name",
3511 impdecls
, rawimpdecls
);
3512 error_with_ivar ("previous declaration of",
3513 intdecls
, rawintdecls
);
3516 intdecls
= TREE_CHAIN (intdecls
);
3517 impdecls
= TREE_CHAIN (impdecls
);
3518 rawintdecls
= TREE_CHAIN (rawintdecls
);
3519 rawimpdecls
= TREE_CHAIN (rawimpdecls
);
3523 /* Set super_type to the data type node for struct objc_super *,
3524 first defining struct objc_super itself.
3525 This needs to be done just once per compilation. */
3528 build_super_template ()
3530 tree record
, decl_specs
, field_decl
, field_decl_chain
;
3532 record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_SUPER
));
3534 /* struct objc_object *self; */
3536 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3537 field_decl
= get_identifier ("self");
3538 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3539 field_decl
= grokfield (input_filename
, lineno
,
3540 field_decl
, decl_specs
, NULL_TREE
);
3541 field_decl_chain
= field_decl
;
3543 /* struct objc_class *class; */
3545 decl_specs
= get_identifier (UTAG_CLASS
);
3546 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
3547 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class"));
3549 field_decl
= grokfield (input_filename
, lineno
,
3550 field_decl
, decl_specs
, NULL_TREE
);
3551 chainon (field_decl_chain
, field_decl
);
3553 finish_struct (record
, field_decl_chain
, NULL_TREE
);
3555 /* `struct objc_super *' */
3556 super_type
= groktypename (build_tree_list (build_tree_list (NULL_TREE
,
3558 build1 (INDIRECT_REF
,
3559 NULL_TREE
, NULL_TREE
)));
3563 /* struct objc_ivar {
3570 build_ivar_template ()
3572 tree objc_ivar_id
, objc_ivar_record
;
3573 tree decl_specs
, field_decl
, field_decl_chain
;
3575 objc_ivar_id
= get_identifier (UTAG_IVAR
);
3576 objc_ivar_record
= start_struct (RECORD_TYPE
, objc_ivar_id
);
3578 /* char *ivar_name; */
3580 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3581 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_name"));
3583 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3584 decl_specs
, NULL_TREE
);
3585 field_decl_chain
= field_decl
;
3587 /* char *ivar_type; */
3589 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3590 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_type"));
3592 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3593 decl_specs
, NULL_TREE
);
3594 chainon (field_decl_chain
, field_decl
);
3596 /* int ivar_offset; */
3598 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3599 field_decl
= get_identifier ("ivar_offset");
3601 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3602 decl_specs
, NULL_TREE
);
3603 chainon (field_decl_chain
, field_decl
);
3605 finish_struct (objc_ivar_record
, field_decl_chain
, NULL_TREE
);
3607 return objc_ivar_record
;
3612 struct objc_ivar ivar_list[ivar_count];
3616 build_ivar_list_template (list_type
, size
)
3620 tree objc_ivar_list_record
;
3621 tree decl_specs
, field_decl
, field_decl_chain
;
3623 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3625 /* int ivar_count; */
3627 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3628 field_decl
= get_identifier ("ivar_count");
3630 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3631 decl_specs
, NULL_TREE
);
3632 field_decl_chain
= field_decl
;
3634 /* struct objc_ivar ivar_list[]; */
3636 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3637 field_decl
= build_nt (ARRAY_REF
, get_identifier ("ivar_list"),
3638 build_int_2 (size
, 0));
3640 field_decl
= grokfield (input_filename
, lineno
,
3641 field_decl
, decl_specs
, NULL_TREE
);
3642 chainon (field_decl_chain
, field_decl
);
3644 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3646 return objc_ivar_list_record
;
3652 struct objc_method method_list[method_count];
3656 build_method_list_template (list_type
, size
)
3660 tree objc_ivar_list_record
;
3661 tree decl_specs
, field_decl
, field_decl_chain
;
3663 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3665 /* int method_next; */
3670 xref_tag (RECORD_TYPE
,
3671 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
3673 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_next"));
3674 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3675 decl_specs
, NULL_TREE
);
3676 field_decl_chain
= field_decl
;
3678 /* int method_count; */
3680 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3681 field_decl
= get_identifier ("method_count");
3683 field_decl
= grokfield (input_filename
, lineno
,
3684 field_decl
, decl_specs
, NULL_TREE
);
3685 chainon (field_decl_chain
, field_decl
);
3687 /* struct objc_method method_list[]; */
3689 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3690 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
3691 build_int_2 (size
, 0));
3693 field_decl
= grokfield (input_filename
, lineno
,
3694 field_decl
, decl_specs
, NULL_TREE
);
3695 chainon (field_decl_chain
, field_decl
);
3697 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3699 return objc_ivar_list_record
;
3703 build_ivar_list_initializer (type
, field_decl
)
3707 tree initlist
= NULL_TREE
;
3711 tree ivar
= NULL_TREE
;
3714 if (DECL_NAME (field_decl
))
3715 ivar
= tree_cons (NULL_TREE
,
3716 add_objc_string (DECL_NAME (field_decl
),
3720 /* Unnamed bit-field ivar (yuck). */
3721 ivar
= tree_cons (NULL_TREE
, build_int_2 (0, 0), ivar
);
3724 encode_field_decl (field_decl
,
3725 obstack_object_size (&util_obstack
),
3726 OBJC_ENCODE_DONT_INLINE_DEFS
);
3728 /* Null terminate string. */
3729 obstack_1grow (&util_obstack
, 0);
3733 add_objc_string (get_identifier (obstack_finish (&util_obstack
)),
3736 obstack_free (&util_obstack
, util_firstobj
);
3739 ivar
= tree_cons (NULL_TREE
, byte_position (field_decl
), ivar
);
3740 initlist
= tree_cons (NULL_TREE
,
3741 build_constructor (type
, nreverse (ivar
)),
3744 field_decl
= TREE_CHAIN (field_decl
);
3748 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3752 generate_ivars_list (type
, name
, size
, list
)
3758 tree sc_spec
, decl_specs
, decl
, initlist
;
3760 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3761 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
3763 decl
= start_decl (synth_id_with_class_suffix (name
, objc_implementation_context
),
3764 decl_specs
, 1, NULL_TREE
);
3766 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
3767 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3770 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3777 generate_ivar_lists ()
3779 tree initlist
, ivar_list_template
, chain
;
3780 tree cast
, variable_length_type
;
3783 generating_instance_variables
= 1;
3785 if (!objc_ivar_template
)
3786 objc_ivar_template
= build_ivar_template ();
3790 (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3791 get_identifier (UTAG_IVAR_LIST
))),
3793 variable_length_type
= groktypename (cast
);
3795 /* Only generate class variables for the root of the inheritance
3796 hierarchy since these will be the same for every class. */
3798 if (CLASS_SUPER_NAME (implementation_template
) == NULL_TREE
3799 && (chain
= TYPE_FIELDS (objc_class_template
)))
3801 size
= list_length (chain
);
3803 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3804 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3806 UOBJC_CLASS_VARIABLES_decl
3807 = generate_ivars_list (ivar_list_template
, "_OBJC_CLASS_VARIABLES",
3809 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl
) = variable_length_type
;
3812 UOBJC_CLASS_VARIABLES_decl
= 0;
3814 chain
= CLASS_IVARS (implementation_template
);
3817 size
= list_length (chain
);
3818 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3819 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3821 UOBJC_INSTANCE_VARIABLES_decl
3822 = generate_ivars_list (ivar_list_template
, "_OBJC_INSTANCE_VARIABLES",
3824 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl
) = variable_length_type
;
3827 UOBJC_INSTANCE_VARIABLES_decl
= 0;
3829 generating_instance_variables
= 0;
3833 build_dispatch_table_initializer (type
, entries
)
3837 tree initlist
= NULL_TREE
;
3841 tree elemlist
= NULL_TREE
;
3843 elemlist
= tree_cons (NULL_TREE
,
3844 build_selector (METHOD_SEL_NAME (entries
)),
3847 elemlist
= tree_cons (NULL_TREE
,
3848 add_objc_string (METHOD_ENCODING (entries
),
3852 elemlist
= tree_cons (NULL_TREE
,
3853 build_unary_op (ADDR_EXPR
,
3854 METHOD_DEFINITION (entries
), 1),
3857 initlist
= tree_cons (NULL_TREE
,
3858 build_constructor (type
, nreverse (elemlist
)),
3861 entries
= TREE_CHAIN (entries
);
3865 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3868 /* To accomplish method prototyping without generating all kinds of
3869 inane warnings, the definition of the dispatch table entries were
3872 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3874 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3877 build_method_template ()
3880 tree decl_specs
, field_decl
, field_decl_chain
;
3882 _SLT_record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD
));
3884 /* struct objc_selector *_cmd; */
3885 decl_specs
= tree_cons (NULL_TREE
,
3886 xref_tag (RECORD_TYPE
,
3887 get_identifier (TAG_SELECTOR
)),
3889 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
3891 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3892 decl_specs
, NULL_TREE
);
3893 field_decl_chain
= field_decl
;
3895 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
3896 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
,
3897 get_identifier ("method_types"));
3898 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3899 decl_specs
, NULL_TREE
);
3900 chainon (field_decl_chain
, field_decl
);
3904 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_VOID
], NULL_TREE
);
3905 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_imp"));
3906 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3907 decl_specs
, NULL_TREE
);
3908 chainon (field_decl_chain
, field_decl
);
3910 finish_struct (_SLT_record
, field_decl_chain
, NULL_TREE
);
3917 generate_dispatch_table (type
, name
, size
, list
)
3923 tree sc_spec
, decl_specs
, decl
, initlist
;
3925 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3926 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
3928 decl
= start_decl (synth_id_with_class_suffix (name
, objc_implementation_context
),
3929 decl_specs
, 1, NULL_TREE
);
3931 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
3932 initlist
= tree_cons (NULL_TREE
, build_int_2 (size
, 0), initlist
);
3933 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3936 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3943 generate_dispatch_tables ()
3945 tree initlist
, chain
, method_list_template
;
3946 tree cast
, variable_length_type
;
3949 if (!objc_method_template
)
3950 objc_method_template
= build_method_template ();
3954 (build_tree_list (NULL_TREE
,
3955 xref_tag (RECORD_TYPE
,
3956 get_identifier (UTAG_METHOD_LIST
))),
3959 variable_length_type
= groktypename (cast
);
3961 chain
= CLASS_CLS_METHODS (objc_implementation_context
);
3964 size
= list_length (chain
);
3966 method_list_template
3967 = build_method_list_template (objc_method_template
, size
);
3969 = build_dispatch_table_initializer (objc_method_template
, chain
);
3971 UOBJC_CLASS_METHODS_decl
3972 = generate_dispatch_table (method_list_template
,
3973 ((TREE_CODE (objc_implementation_context
)
3974 == CLASS_IMPLEMENTATION_TYPE
)
3975 ? "_OBJC_CLASS_METHODS"
3976 : "_OBJC_CATEGORY_CLASS_METHODS"),
3978 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
3981 UOBJC_CLASS_METHODS_decl
= 0;
3983 chain
= CLASS_NST_METHODS (objc_implementation_context
);
3986 size
= list_length (chain
);
3988 method_list_template
3989 = build_method_list_template (objc_method_template
, size
);
3991 = build_dispatch_table_initializer (objc_method_template
, chain
);
3993 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
3994 UOBJC_INSTANCE_METHODS_decl
3995 = generate_dispatch_table (method_list_template
,
3996 "_OBJC_INSTANCE_METHODS",
3999 /* We have a category. */
4000 UOBJC_INSTANCE_METHODS_decl
4001 = generate_dispatch_table (method_list_template
,
4002 "_OBJC_CATEGORY_INSTANCE_METHODS",
4004 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
4007 UOBJC_INSTANCE_METHODS_decl
= 0;
4011 generate_protocol_list (i_or_p
)
4014 tree initlist
, decl_specs
, sc_spec
;
4015 tree refs_decl
, expr_decl
, lproto
, e
, plist
;
4019 if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
4020 || TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4021 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
4022 else if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4023 plist
= PROTOCOL_LIST (i_or_p
);
4027 cast_type
= groktypename
4029 (build_tree_list (NULL_TREE
,
4030 xref_tag (RECORD_TYPE
,
4031 get_identifier (UTAG_PROTOCOL
))),
4032 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
4035 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4036 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
4037 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
4040 /* Build initializer. */
4041 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), NULL_TREE
);
4043 e
= build_int_2 (size
, 0);
4044 TREE_TYPE (e
) = cast_type
;
4045 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4047 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4049 tree pval
= TREE_VALUE (lproto
);
4051 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
4052 && PROTOCOL_FORWARD_DECL (pval
))
4054 e
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (pval
), 0);
4055 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4059 /* static struct objc_protocol *refs[n]; */
4061 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4062 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
4063 get_identifier (UTAG_PROTOCOL
)),
4066 if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4067 expr_decl
= build_nt (ARRAY_REF
,
4068 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4070 build_int_2 (size
+ 2, 0));
4071 else if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
)
4072 expr_decl
= build_nt (ARRAY_REF
,
4073 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4075 build_int_2 (size
+ 2, 0));
4076 else if (TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4078 = build_nt (ARRAY_REF
,
4079 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4081 build_int_2 (size
+ 2, 0));
4085 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
4087 refs_decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
4088 DECL_CONTEXT (refs_decl
) = NULL_TREE
;
4090 finish_decl (refs_decl
, build_constructor (TREE_TYPE (refs_decl
),
4091 nreverse (initlist
)),
4098 build_category_initializer (type
, cat_name
, class_name
,
4099 instance_methods
, class_methods
, protocol_list
)
4103 tree instance_methods
;
4107 tree initlist
= NULL_TREE
, expr
;
4109 initlist
= tree_cons (NULL_TREE
, cat_name
, initlist
);
4110 initlist
= tree_cons (NULL_TREE
, class_name
, initlist
);
4112 if (!instance_methods
)
4113 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4116 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
4117 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4120 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4123 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
4124 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4127 /* protocol_list = */
4129 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4132 tree cast_type2
= groktypename
4134 (build_tree_list (NULL_TREE
,
4135 xref_tag (RECORD_TYPE
,
4136 get_identifier (UTAG_PROTOCOL
))),
4137 build1 (INDIRECT_REF
, NULL_TREE
,
4138 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4140 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4141 TREE_TYPE (expr
) = cast_type2
;
4142 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4145 return build_constructor (type
, nreverse (initlist
));
4148 /* struct objc_class {
4149 struct objc_class *isa;
4150 struct objc_class *super_class;
4155 struct objc_ivar_list *ivars;
4156 struct objc_method_list *methods;
4157 if (flag_next_runtime)
4158 struct objc_cache *cache;
4160 struct sarray *dtable;
4161 struct objc_class *subclass_list;
4162 struct objc_class *sibling_class;
4164 struct objc_protocol_list *protocols;
4165 void *gc_object_type;
4169 build_shared_structure_initializer (type
, isa
, super
, name
, size
, status
,
4170 dispatch_table
, ivar_list
, protocol_list
)
4177 tree dispatch_table
;
4181 tree initlist
= NULL_TREE
, expr
;
4184 initlist
= tree_cons (NULL_TREE
, isa
, initlist
);
4187 initlist
= tree_cons (NULL_TREE
, super
, initlist
);
4190 initlist
= tree_cons (NULL_TREE
, default_conversion (name
), initlist
);
4193 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4196 initlist
= tree_cons (NULL_TREE
, build_int_2 (status
, 0), initlist
);
4198 /* instance_size = */
4199 initlist
= tree_cons (NULL_TREE
, size
, initlist
);
4201 /* objc_ivar_list = */
4203 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4206 expr
= build_unary_op (ADDR_EXPR
, ivar_list
, 0);
4207 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4210 /* objc_method_list = */
4211 if (!dispatch_table
)
4212 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4215 expr
= build_unary_op (ADDR_EXPR
, dispatch_table
, 0);
4216 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4219 if (flag_next_runtime
)
4220 /* method_cache = */
4221 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4225 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4227 /* subclass_list = */
4228 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4230 /* sibling_class = */
4231 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4234 /* protocol_list = */
4235 if (! protocol_list
)
4236 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4242 (build_tree_list (NULL_TREE
,
4243 xref_tag (RECORD_TYPE
,
4244 get_identifier (UTAG_PROTOCOL
))),
4245 build1 (INDIRECT_REF
, NULL_TREE
,
4246 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4248 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4249 TREE_TYPE (expr
) = cast_type2
;
4250 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4253 /* gc_object_type = NULL */
4254 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4256 return build_constructor (type
, nreverse (initlist
));
4259 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4262 generate_category (cat
)
4265 tree sc_spec
, decl_specs
, decl
;
4266 tree initlist
, cat_name_expr
, class_name_expr
;
4267 tree protocol_decl
, category
;
4269 add_class_reference (CLASS_NAME (cat
));
4270 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
4272 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
4274 category
= CLASS_CATEGORY_LIST (implementation_template
);
4276 /* find the category interface from the class it is associated with */
4279 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
4281 category
= CLASS_CATEGORY_LIST (category
);
4284 if (category
&& CLASS_PROTOCOL_LIST (category
))
4286 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
4287 protocol_decl
= generate_protocol_list (category
);
4292 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4293 decl_specs
= tree_cons (NULL_TREE
, objc_category_template
, sc_spec
);
4295 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4296 objc_implementation_context
),
4297 decl_specs
, 1, NULL_TREE
);
4299 initlist
= build_category_initializer (TREE_TYPE (decl
),
4300 cat_name_expr
, class_name_expr
,
4301 UOBJC_INSTANCE_METHODS_decl
,
4302 UOBJC_CLASS_METHODS_decl
,
4305 TREE_USED (decl
) = 1;
4306 finish_decl (decl
, initlist
, NULL_TREE
);
4309 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4310 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4313 generate_shared_structures ()
4315 tree sc_spec
, decl_specs
, decl
;
4316 tree name_expr
, super_expr
, root_expr
;
4317 tree my_root_id
= NULL_TREE
, my_super_id
= NULL_TREE
;
4318 tree cast_type
, initlist
, protocol_decl
;
4320 my_super_id
= CLASS_SUPER_NAME (implementation_template
);
4323 add_class_reference (my_super_id
);
4325 /* Compute "my_root_id" - this is required for code generation.
4326 the "isa" for all meta class structures points to the root of
4327 the inheritance hierarchy (e.g. "__Object")... */
4328 my_root_id
= my_super_id
;
4331 tree my_root_int
= lookup_interface (my_root_id
);
4333 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
4334 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
4341 /* No super class. */
4342 my_root_id
= CLASS_NAME (implementation_template
);
4345 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
4346 objc_class_template
),
4347 build1 (INDIRECT_REF
,
4348 NULL_TREE
, NULL_TREE
)));
4350 name_expr
= add_objc_string (CLASS_NAME (implementation_template
),
4353 /* Install class `isa' and `super' pointers at runtime. */
4356 super_expr
= add_objc_string (my_super_id
, class_names
);
4357 super_expr
= build_c_cast (cast_type
, super_expr
); /* cast! */
4360 super_expr
= build_int_2 (0, 0);
4362 root_expr
= add_objc_string (my_root_id
, class_names
);
4363 root_expr
= build_c_cast (cast_type
, root_expr
); /* cast! */
4365 if (CLASS_PROTOCOL_LIST (implementation_template
))
4367 generate_protocol_references
4368 (CLASS_PROTOCOL_LIST (implementation_template
));
4369 protocol_decl
= generate_protocol_list (implementation_template
);
4374 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4376 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
4377 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
4379 decl
= start_decl (DECL_NAME (UOBJC_METACLASS_decl
), decl_specs
, 1,
4383 = build_shared_structure_initializer
4385 root_expr
, super_expr
, name_expr
,
4386 convert (integer_type_node
, TYPE_SIZE_UNIT (objc_class_template
)),
4388 UOBJC_CLASS_METHODS_decl
,
4389 UOBJC_CLASS_VARIABLES_decl
,
4392 finish_decl (decl
, initlist
, NULL_TREE
);
4394 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4396 decl
= start_decl (DECL_NAME (UOBJC_CLASS_decl
), decl_specs
, 1,
4400 = build_shared_structure_initializer
4402 build_unary_op (ADDR_EXPR
, UOBJC_METACLASS_decl
, 0),
4403 super_expr
, name_expr
,
4404 convert (integer_type_node
,
4405 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4406 (implementation_template
))),
4408 UOBJC_INSTANCE_METHODS_decl
,
4409 UOBJC_INSTANCE_VARIABLES_decl
,
4412 finish_decl (decl
, initlist
, NULL_TREE
);
4416 synth_id_with_class_suffix (preamble
, ctxt
)
4417 const char *preamble
;
4421 if (TREE_CODE (ctxt
) == CLASS_IMPLEMENTATION_TYPE
4422 || TREE_CODE (ctxt
) == CLASS_INTERFACE_TYPE
)
4424 const char *const class_name
4425 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
4426 string
= (char *) alloca (strlen (preamble
) + strlen (class_name
) + 3);
4427 sprintf (string
, "%s_%s", preamble
,
4428 IDENTIFIER_POINTER (CLASS_NAME (ctxt
)));
4430 else if (TREE_CODE (ctxt
) == CATEGORY_IMPLEMENTATION_TYPE
4431 || TREE_CODE (ctxt
) == CATEGORY_INTERFACE_TYPE
)
4433 /* We have a category. */
4434 const char *const class_name
4435 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
4436 const char *const class_super_name
4437 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
));
4438 string
= (char *) alloca (strlen (preamble
)
4439 + strlen (class_name
)
4440 + strlen (class_super_name
)
4442 sprintf (string
, "%s_%s_%s", preamble
, class_name
, class_super_name
);
4444 else if (TREE_CODE (ctxt
) == PROTOCOL_INTERFACE_TYPE
)
4446 const char *protocol_name
= IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt
));
4448 = (char *) alloca (strlen (preamble
) + strlen (protocol_name
) + 3);
4449 sprintf (string
, "%s_%s", preamble
, protocol_name
);
4454 return get_identifier (string
);
4458 is_objc_type_qualifier (node
)
4461 return (TREE_CODE (node
) == IDENTIFIER_NODE
4462 && (node
== ridpointers
[(int) RID_CONST
]
4463 || node
== ridpointers
[(int) RID_VOLATILE
]
4464 || node
== ridpointers
[(int) RID_IN
]
4465 || node
== ridpointers
[(int) RID_OUT
]
4466 || node
== ridpointers
[(int) RID_INOUT
]
4467 || node
== ridpointers
[(int) RID_BYCOPY
]
4468 || node
== ridpointers
[(int) RID_BYREF
]
4469 || node
== ridpointers
[(int) RID_ONEWAY
]));
4472 /* If type is empty or only type qualifiers are present, add default
4473 type of id (otherwise grokdeclarator will default to int). */
4476 adjust_type_for_id_default (type
)
4479 tree declspecs
, chain
;
4482 return build_tree_list (build_tree_list (NULL_TREE
, objc_object_reference
),
4483 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4485 declspecs
= TREE_PURPOSE (type
);
4487 /* Determine if a typespec is present. */
4488 for (chain
= declspecs
;
4490 chain
= TREE_CHAIN (chain
))
4492 if (!is_objc_type_qualifier (TREE_VALUE (chain
)))
4496 return build_tree_list (tree_cons (NULL_TREE
, objc_object_reference
,
4498 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4503 selector ':' '(' typename ')' identifier
4506 Transform an Objective-C keyword argument into
4507 the C equivalent parameter declarator.
4509 In: key_name, an "identifier_node" (optional).
4510 arg_type, a "tree_list" (optional).
4511 arg_name, an "identifier_node".
4513 Note: It would be really nice to strongly type the preceding
4514 arguments in the function prototype; however, then I
4515 could not use the "accessor" macros defined in "tree.h".
4517 Out: an instance of "keyword_decl". */
4520 build_keyword_decl (key_name
, arg_type
, arg_name
)
4527 /* If no type is specified, default to "id". */
4528 arg_type
= adjust_type_for_id_default (arg_type
);
4530 keyword_decl
= make_node (KEYWORD_DECL
);
4532 TREE_TYPE (keyword_decl
) = arg_type
;
4533 KEYWORD_ARG_NAME (keyword_decl
) = arg_name
;
4534 KEYWORD_KEY_NAME (keyword_decl
) = key_name
;
4536 return keyword_decl
;
4539 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4542 build_keyword_selector (selector
)
4546 tree key_chain
, key_name
;
4549 /* Scan the selector to see how much space we'll need. */
4550 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4552 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4553 key_name
= KEYWORD_KEY_NAME (key_chain
);
4554 else if (TREE_CODE (selector
) == TREE_LIST
)
4555 key_name
= TREE_PURPOSE (key_chain
);
4560 len
+= IDENTIFIER_LENGTH (key_name
) + 1;
4562 /* Just a ':' arg. */
4566 buf
= (char *) alloca (len
+ 1);
4567 /* Start the buffer out as an empty string. */
4570 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4572 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4573 key_name
= KEYWORD_KEY_NAME (key_chain
);
4574 else if (TREE_CODE (selector
) == TREE_LIST
)
4575 key_name
= TREE_PURPOSE (key_chain
);
4580 strcat (buf
, IDENTIFIER_POINTER (key_name
));
4584 return get_identifier (buf
);
4587 /* Used for declarations and definitions. */
4590 build_method_decl (code
, ret_type
, selector
, add_args
)
4591 enum tree_code code
;
4598 /* If no type is specified, default to "id". */
4599 ret_type
= adjust_type_for_id_default (ret_type
);
4601 method_decl
= make_node (code
);
4602 TREE_TYPE (method_decl
) = ret_type
;
4604 /* If we have a keyword selector, create an identifier_node that
4605 represents the full selector name (`:' included)... */
4606 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4608 METHOD_SEL_NAME (method_decl
) = build_keyword_selector (selector
);
4609 METHOD_SEL_ARGS (method_decl
) = selector
;
4610 METHOD_ADD_ARGS (method_decl
) = add_args
;
4614 METHOD_SEL_NAME (method_decl
) = selector
;
4615 METHOD_SEL_ARGS (method_decl
) = NULL_TREE
;
4616 METHOD_ADD_ARGS (method_decl
) = NULL_TREE
;
4622 #define METHOD_DEF 0
4623 #define METHOD_REF 1
4625 /* Used by `build_objc_method_call' and `comp_method_types'. Return
4626 an argument list for method METH. CONTEXT is either METHOD_DEF or
4627 METHOD_REF, saying whether we are trying to define a method or call
4628 one. SUPERFLAG says this is for a send to super; this makes a
4629 difference for the NeXT calling sequence in which the lookup and
4630 the method call are done together. */
4633 get_arg_type_list (meth
, context
, superflag
)
4640 /* Receiver type. */
4641 if (flag_next_runtime
&& superflag
)
4642 arglist
= build_tree_list (NULL_TREE
, super_type
);
4643 else if (context
== METHOD_DEF
)
4644 arglist
= build_tree_list (NULL_TREE
, TREE_TYPE (self_decl
));
4646 arglist
= build_tree_list (NULL_TREE
, id_type
);
4648 /* Selector type - will eventually change to `int'. */
4649 chainon (arglist
, build_tree_list (NULL_TREE
, selector_type
));
4651 /* Build a list of argument types. */
4652 for (akey
= METHOD_SEL_ARGS (meth
); akey
; akey
= TREE_CHAIN (akey
))
4654 tree arg_decl
= groktypename_in_parm_context (TREE_TYPE (akey
));
4655 chainon (arglist
, build_tree_list (NULL_TREE
, TREE_TYPE (arg_decl
)));
4658 if (METHOD_ADD_ARGS (meth
) == objc_ellipsis_node
)
4659 /* We have a `, ...' immediately following the selector,
4660 finalize the arglist...simulate get_parm_info (0). */
4662 else if (METHOD_ADD_ARGS (meth
))
4664 /* we have a variable length selector */
4665 tree add_arg_list
= TREE_CHAIN (METHOD_ADD_ARGS (meth
));
4666 chainon (arglist
, add_arg_list
);
4669 /* finalize the arglist...simulate get_parm_info (1) */
4670 chainon (arglist
, build_tree_list (NULL_TREE
, void_type_node
));
4676 check_duplicates (hsh
)
4679 tree meth
= NULL_TREE
;
4687 /* We have two methods with the same name and different types. */
4689 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
) ? '-' : '+';
4691 warning ("multiple declarations for method `%s'",
4692 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
4694 warn_with_method ("using", type
, meth
);
4695 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
4696 warn_with_method ("also found", type
, loop
->value
);
4702 /* If RECEIVER is a class reference, return the identifier node for
4703 the referenced class. RECEIVER is created by get_class_reference,
4704 so we check the exact form created depending on which runtimes are
4708 receiver_is_class_object (receiver
)
4711 tree chain
, exp
, arg
;
4713 if (flag_next_runtime
)
4715 /* The receiver is 'self' in the context of a class method. */
4716 if (objc_method_context
4717 && receiver
== self_decl
4718 && TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
4719 return CLASS_NAME (objc_implementation_context
);
4721 /* The receiver is a variable created by
4722 build_class_reference_decl. */
4723 if (TREE_CODE (receiver
) == VAR_DECL
4724 && TREE_TYPE (receiver
) == objc_class_type
)
4725 /* Look up the identifier. */
4726 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
4727 if (TREE_PURPOSE (chain
) == receiver
)
4728 return TREE_VALUE (chain
);
4732 /* The receiver is a function call that returns an id. Check if
4733 it is a call to objc_getClass, if so, pick up the class name. */
4734 if ((exp
= TREE_OPERAND (receiver
, 0))
4735 && TREE_CODE (exp
) == ADDR_EXPR
4736 && (exp
= TREE_OPERAND (exp
, 0))
4737 && TREE_CODE (exp
) == FUNCTION_DECL
4738 && exp
== objc_get_class_decl
4739 /* We have a call to objc_getClass! */
4740 && (arg
= TREE_OPERAND (receiver
, 1))
4741 && TREE_CODE (arg
) == TREE_LIST
4742 && (arg
= TREE_VALUE (arg
)))
4745 if (TREE_CODE (arg
) == ADDR_EXPR
4746 && (arg
= TREE_OPERAND (arg
, 0))
4747 && TREE_CODE (arg
) == STRING_CST
)
4748 /* Finally, we have the class name. */
4749 return get_identifier (TREE_STRING_POINTER (arg
));
4755 /* If we are currently building a message expr, this holds
4756 the identifier of the selector of the message. This is
4757 used when printing warnings about argument mismatches. */
4759 static tree building_objc_message_expr
= 0;
4762 maybe_building_objc_message_expr ()
4764 return building_objc_message_expr
;
4767 /* Construct an expression for sending a message.
4768 MESS has the object to send to in TREE_PURPOSE
4769 and the argument list (including selector) in TREE_VALUE.
4771 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4772 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4775 build_message_expr (mess
)
4778 tree receiver
= TREE_PURPOSE (mess
);
4780 tree args
= TREE_VALUE (mess
);
4781 tree method_params
= NULL_TREE
;
4783 if (TREE_CODE (receiver
) == ERROR_MARK
)
4784 return error_mark_node
;
4786 /* Obtain the full selector name. */
4787 if (TREE_CODE (args
) == IDENTIFIER_NODE
)
4788 /* A unary selector. */
4790 else if (TREE_CODE (args
) == TREE_LIST
)
4791 sel_name
= build_keyword_selector (args
);
4795 /* Build the parameter list to give to the method. */
4796 if (TREE_CODE (args
) == TREE_LIST
)
4798 tree chain
= args
, prev
= NULL_TREE
;
4800 /* We have a keyword selector--check for comma expressions. */
4803 tree element
= TREE_VALUE (chain
);
4805 /* We have a comma expression, must collapse... */
4806 if (TREE_CODE (element
) == TREE_LIST
)
4809 TREE_CHAIN (prev
) = element
;
4814 chain
= TREE_CHAIN (chain
);
4816 method_params
= args
;
4819 return finish_message_expr (receiver
, sel_name
, method_params
);
4822 /* The 'finish_message_expr' routine is called from within
4823 'build_message_expr' for non-template functions. In the case of
4824 C++ template functions, it is called from 'build_expr_from_tree'
4825 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
4828 finish_message_expr (receiver
, sel_name
, method_params
)
4829 tree receiver
, sel_name
, method_params
;
4831 tree method_prototype
= NULL_TREE
, class_ident
= NULL_TREE
;
4832 tree selector
, self_object
, retval
;
4833 int statically_typed
= 0, statically_allocated
= 0;
4835 /* Determine receiver type. */
4836 tree rtype
= TREE_TYPE (receiver
);
4837 int super
= IS_SUPER (rtype
);
4841 if (TREE_STATIC_TEMPLATE (rtype
))
4842 statically_allocated
= 1;
4843 else if (TREE_CODE (rtype
) == POINTER_TYPE
4844 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype
)))
4845 statically_typed
= 1;
4846 else if ((flag_next_runtime
4847 || (TREE_CODE (receiver
) == CALL_EXPR
&& IS_ID (rtype
)))
4848 && (class_ident
= receiver_is_class_object (receiver
)))
4850 else if (! IS_ID (rtype
)
4851 /* Allow any type that matches objc_class_type. */
4852 && ! comptypes (rtype
, objc_class_type
))
4854 warning ("invalid receiver type `%s'",
4855 gen_declaration (rtype
, errbuf
));
4857 if (statically_allocated
)
4858 receiver
= build_unary_op (ADDR_EXPR
, receiver
, 0);
4860 /* Don't evaluate the receiver twice. */
4861 receiver
= save_expr (receiver
);
4862 self_object
= receiver
;
4865 /* If sending to `super', use current self as the object. */
4866 self_object
= self_decl
;
4868 /* Determine operation return type. */
4874 if (CLASS_SUPER_NAME (implementation_template
))
4877 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
4879 if (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
)
4880 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4882 method_prototype
= lookup_class_method_static (iface
, sel_name
);
4884 if (iface
&& !method_prototype
)
4885 warning ("`%s' does not respond to `%s'",
4886 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template
)),
4887 IDENTIFIER_POINTER (sel_name
));
4891 error ("no super class declared in interface for `%s'",
4892 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
4893 return error_mark_node
;
4897 else if (statically_allocated
)
4899 tree ctype
= TREE_TYPE (rtype
);
4900 tree iface
= lookup_interface (TYPE_NAME (rtype
));
4903 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4905 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
4907 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
4910 if (!method_prototype
)
4911 warning ("`%s' does not respond to `%s'",
4912 IDENTIFIER_POINTER (TYPE_NAME (rtype
)),
4913 IDENTIFIER_POINTER (sel_name
));
4915 else if (statically_typed
)
4917 tree ctype
= TREE_TYPE (rtype
);
4919 /* `self' is now statically_typed. All methods should be visible
4920 within the context of the implementation. */
4921 if (objc_implementation_context
4922 && CLASS_NAME (objc_implementation_context
) == TYPE_NAME (ctype
))
4925 = lookup_instance_method_static (implementation_template
,
4928 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
4930 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
4933 if (! method_prototype
4934 && implementation_template
!= objc_implementation_context
)
4935 /* The method is not published in the interface. Check
4938 = lookup_method (CLASS_NST_METHODS (objc_implementation_context
),
4945 if ((iface
= lookup_interface (TYPE_NAME (ctype
))))
4946 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4948 if (! method_prototype
)
4950 tree protocol_list
= TYPE_PROTOCOL_LIST (ctype
);
4953 = lookup_method_in_protocol_list (protocol_list
,
4958 if (!method_prototype
)
4959 warning ("`%s' does not respond to `%s'",
4960 IDENTIFIER_POINTER (TYPE_NAME (ctype
)),
4961 IDENTIFIER_POINTER (sel_name
));
4963 else if (class_ident
)
4965 if (objc_implementation_context
4966 && CLASS_NAME (objc_implementation_context
) == class_ident
)
4969 = lookup_class_method_static (implementation_template
, sel_name
);
4971 if (!method_prototype
4972 && implementation_template
!= objc_implementation_context
)
4973 /* The method is not published in the interface. Check
4976 = lookup_method (CLASS_CLS_METHODS (objc_implementation_context
),
4983 if ((iface
= lookup_interface (class_ident
)))
4984 method_prototype
= lookup_class_method_static (iface
, sel_name
);
4987 if (!method_prototype
)
4989 warning ("cannot find class (factory) method.");
4990 warning ("return type for `%s' defaults to id",
4991 IDENTIFIER_POINTER (sel_name
));
4994 else if (IS_PROTOCOL_QUALIFIED_ID (rtype
))
4996 /* An anonymous object that has been qualified with a protocol. */
4998 tree protocol_list
= TYPE_PROTOCOL_LIST (rtype
);
5000 method_prototype
= lookup_method_in_protocol_list (protocol_list
,
5003 if (!method_prototype
)
5007 warning ("method `%s' not implemented by protocol.",
5008 IDENTIFIER_POINTER (sel_name
));
5010 /* Try and find the method signature in the global pools. */
5012 if (!(hsh
= hash_lookup (nst_method_hash_list
, sel_name
)))
5013 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5015 if (!(method_prototype
= check_duplicates (hsh
)))
5016 warning ("return type defaults to id");
5023 /* We think we have an instance...loophole: extern id Object; */
5024 hsh
= hash_lookup (nst_method_hash_list
, sel_name
);
5026 /* For various loopholes, like sending messages to self in a
5028 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5030 method_prototype
= check_duplicates (hsh
);
5031 if (!method_prototype
)
5033 warning ("cannot find method.");
5034 warning ("return type for `%s' defaults to id",
5035 IDENTIFIER_POINTER (sel_name
));
5039 /* Save the selector name for printing error messages. */
5040 building_objc_message_expr
= sel_name
;
5042 /* Build the parameters list for looking up the method.
5043 These are the object itself and the selector. */
5045 if (flag_typed_selectors
)
5046 selector
= build_typed_selector_reference (sel_name
, method_prototype
);
5048 selector
= build_selector_reference (sel_name
);
5050 retval
= build_objc_method_call (super
, method_prototype
,
5051 receiver
, self_object
,
5052 selector
, method_params
);
5054 building_objc_message_expr
= 0;
5059 /* Build a tree expression to send OBJECT the operation SELECTOR,
5060 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5061 assuming the method has prototype METHOD_PROTOTYPE.
5062 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5063 Use METHOD_PARAMS as list of args to pass to the method.
5064 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5067 build_objc_method_call (super_flag
, method_prototype
, lookup_object
, object
,
5068 selector
, method_params
)
5070 tree method_prototype
, lookup_object
, object
, selector
, method_params
;
5072 tree sender
= (super_flag
? umsg_super_decl
: umsg_decl
);
5073 tree rcv_p
= (super_flag
5074 ? build_pointer_type (xref_tag (RECORD_TYPE
,
5075 get_identifier (TAG_SUPER
)))
5078 if (flag_next_runtime
)
5080 if (! method_prototype
)
5082 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5083 tree_cons (NULL_TREE
, selector
,
5085 assemble_external (sender
);
5086 return build_function_call (sender
, method_params
);
5090 /* This is a real kludge, but it is used only for the Next.
5091 Clobber the data type of SENDER temporarily to accept
5092 all the arguments for this operation, and to return
5093 whatever this operation returns. */
5094 tree arglist
= NULL_TREE
, retval
, savarg
, savret
;
5095 tree ret_type
= groktypename (TREE_TYPE (method_prototype
));
5097 /* Save the proper contents of SENDER's data type. */
5098 savarg
= TYPE_ARG_TYPES (TREE_TYPE (sender
));
5099 savret
= TREE_TYPE (TREE_TYPE (sender
));
5101 /* Install this method's argument types. */
5102 arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5104 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = arglist
;
5106 /* Install this method's return type. */
5107 TREE_TYPE (TREE_TYPE (sender
)) = ret_type
;
5109 /* Call SENDER with all the parameters. This will do type
5110 checking using the arg types for this method. */
5111 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5112 tree_cons (NULL_TREE
, selector
,
5114 assemble_external (sender
);
5115 retval
= build_function_call (sender
, method_params
);
5117 /* Restore SENDER's return/argument types. */
5118 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = savarg
;
5119 TREE_TYPE (TREE_TYPE (sender
)) = savret
;
5125 /* This is the portable way.
5126 First call the lookup function to get a pointer to the method,
5127 then cast the pointer, then call it with the method arguments. */
5130 /* Avoid trouble since we may evaluate each of these twice. */
5131 object
= save_expr (object
);
5132 selector
= save_expr (selector
);
5134 lookup_object
= build_c_cast (rcv_p
, lookup_object
);
5136 assemble_external (sender
);
5138 = build_function_call (sender
,
5139 tree_cons (NULL_TREE
, lookup_object
,
5140 tree_cons (NULL_TREE
, selector
,
5143 /* If we have a method prototype, construct the data type this
5144 method needs, and cast what we got from SENDER into a pointer
5146 if (method_prototype
)
5148 tree arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5150 tree valtype
= groktypename (TREE_TYPE (method_prototype
));
5151 tree fake_function_type
= build_function_type (valtype
, arglist
);
5152 TREE_TYPE (method
) = build_pointer_type (fake_function_type
);
5156 = build_pointer_type (build_function_type (ptr_type_node
, NULL_TREE
));
5158 /* Pass the object to the method. */
5159 assemble_external (method
);
5160 return build_function_call (method
,
5161 tree_cons (NULL_TREE
, object
,
5162 tree_cons (NULL_TREE
, selector
,
5168 build_protocol_reference (p
)
5171 tree decl
, ident
, ptype
;
5173 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5175 ident
= synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
);
5177 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
5178 objc_protocol_template
),
5181 if (IDENTIFIER_GLOBAL_VALUE (ident
))
5182 decl
= IDENTIFIER_GLOBAL_VALUE (ident
); /* Set by pushdecl. */
5185 decl
= build_decl (VAR_DECL
, ident
, ptype
);
5186 DECL_EXTERNAL (decl
) = 1;
5187 TREE_PUBLIC (decl
) = 1;
5188 TREE_USED (decl
) = 1;
5189 DECL_ARTIFICIAL (decl
) = 1;
5191 make_decl_rtl (decl
, 0);
5192 pushdecl_top_level (decl
);
5195 PROTOCOL_FORWARD_DECL (p
) = decl
;
5199 build_protocol_expr (protoname
)
5203 tree p
= lookup_protocol (protoname
);
5207 error ("Cannot find protocol declaration for `%s'",
5208 IDENTIFIER_POINTER (protoname
));
5209 return error_mark_node
;
5212 if (!PROTOCOL_FORWARD_DECL (p
))
5213 build_protocol_reference (p
);
5215 expr
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
5217 TREE_TYPE (expr
) = protocol_type
;
5223 build_selector_expr (selnamelist
)
5228 /* Obtain the full selector name. */
5229 if (TREE_CODE (selnamelist
) == IDENTIFIER_NODE
)
5230 /* A unary selector. */
5231 selname
= selnamelist
;
5232 else if (TREE_CODE (selnamelist
) == TREE_LIST
)
5233 selname
= build_keyword_selector (selnamelist
);
5237 if (flag_typed_selectors
)
5238 return build_typed_selector_reference (selname
, 0);
5240 return build_selector_reference (selname
);
5244 build_encode_expr (type
)
5250 encode_type (type
, obstack_object_size (&util_obstack
),
5251 OBJC_ENCODE_INLINE_DEFS
);
5252 obstack_1grow (&util_obstack
, 0); /* null terminate string */
5253 string
= obstack_finish (&util_obstack
);
5255 /* Synthesize a string that represents the encoded struct/union. */
5256 result
= my_build_string (strlen (string
) + 1, string
);
5257 obstack_free (&util_obstack
, util_firstobj
);
5262 build_ivar_reference (id
)
5265 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
5267 /* Historically, a class method that produced objects (factory
5268 method) would assign `self' to the instance that it
5269 allocated. This would effectively turn the class method into
5270 an instance method. Following this assignment, the instance
5271 variables could be accessed. That practice, while safe,
5272 violates the simple rule that a class method should not refer
5273 to an instance variable. It's better to catch the cases
5274 where this is done unknowingly than to support the above
5276 warning ("instance variable `%s' accessed in class method",
5277 IDENTIFIER_POINTER (id
));
5278 TREE_TYPE (self_decl
) = instance_type
; /* cast */
5281 return build_component_ref (build_indirect_ref (self_decl
, "->"), id
);
5283 \f/* Make the hash value positive. */
5284 #define HASHFUNCTION(key) ((size_t) key & 0x7fffffff)
5289 nst_method_hash_list
= (hash
*) xcalloc (SIZEHASHTABLE
, sizeof (hash
));
5290 cls_method_hash_list
= (hash
*) xcalloc (SIZEHASHTABLE
, sizeof (hash
));
5293 /* WARNING!!!! hash_enter is called with a method, and will peek
5294 inside to find its selector! But hash_lookup is given a selector
5295 directly, and looks for the selector that's inside the found
5296 entry's key (method) for comparison. */
5299 hash_enter (hashlist
, method
)
5303 static hash hash_alloc_list
= 0;
5304 static int hash_alloc_index
= 0;
5306 int slot
= HASHFUNCTION (METHOD_SEL_NAME (method
)) % SIZEHASHTABLE
;
5308 if (! hash_alloc_list
|| hash_alloc_index
>= HASH_ALLOC_LIST_SIZE
)
5310 hash_alloc_index
= 0;
5311 hash_alloc_list
= (hash
) xmalloc (sizeof (struct hashed_entry
)
5312 * HASH_ALLOC_LIST_SIZE
);
5314 obj
= &hash_alloc_list
[hash_alloc_index
++];
5316 obj
->next
= hashlist
[slot
];
5319 hashlist
[slot
] = obj
; /* append to front */
5323 hash_lookup (hashlist
, sel_name
)
5329 target
= hashlist
[HASHFUNCTION (sel_name
) % SIZEHASHTABLE
];
5333 if (sel_name
== METHOD_SEL_NAME (target
->key
))
5336 target
= target
->next
;
5342 hash_add_attr (entry
, value
)
5346 static attr attr_alloc_list
= 0;
5347 static int attr_alloc_index
= 0;
5350 if (! attr_alloc_list
|| attr_alloc_index
>= ATTR_ALLOC_LIST_SIZE
)
5352 attr_alloc_index
= 0;
5353 attr_alloc_list
= (attr
) xmalloc (sizeof (struct hashed_attribute
)
5354 * ATTR_ALLOC_LIST_SIZE
);
5356 obj
= &attr_alloc_list
[attr_alloc_index
++];
5357 obj
->next
= entry
->list
;
5360 entry
->list
= obj
; /* append to front */
5364 lookup_method (mchain
, method
)
5370 if (TREE_CODE (method
) == IDENTIFIER_NODE
)
5373 key
= METHOD_SEL_NAME (method
);
5377 if (METHOD_SEL_NAME (mchain
) == key
)
5379 mchain
= TREE_CHAIN (mchain
);
5385 lookup_instance_method_static (interface
, ident
)
5389 tree inter
= interface
;
5390 tree chain
= CLASS_NST_METHODS (inter
);
5391 tree meth
= NULL_TREE
;
5395 if ((meth
= lookup_method (chain
, ident
)))
5398 if (CLASS_CATEGORY_LIST (inter
))
5400 tree category
= CLASS_CATEGORY_LIST (inter
);
5401 chain
= CLASS_NST_METHODS (category
);
5405 if ((meth
= lookup_method (chain
, ident
)))
5408 /* Check for instance methods in protocols in categories. */
5409 if (CLASS_PROTOCOL_LIST (category
))
5411 if ((meth
= (lookup_method_in_protocol_list
5412 (CLASS_PROTOCOL_LIST (category
), ident
, 0))))
5416 if ((category
= CLASS_CATEGORY_LIST (category
)))
5417 chain
= CLASS_NST_METHODS (category
);
5422 if (CLASS_PROTOCOL_LIST (inter
))
5424 if ((meth
= (lookup_method_in_protocol_list
5425 (CLASS_PROTOCOL_LIST (inter
), ident
, 0))))
5429 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5430 chain
= CLASS_NST_METHODS (inter
);
5438 lookup_class_method_static (interface
, ident
)
5442 tree inter
= interface
;
5443 tree chain
= CLASS_CLS_METHODS (inter
);
5444 tree meth
= NULL_TREE
;
5445 tree root_inter
= NULL_TREE
;
5449 if ((meth
= lookup_method (chain
, ident
)))
5452 if (CLASS_CATEGORY_LIST (inter
))
5454 tree category
= CLASS_CATEGORY_LIST (inter
);
5455 chain
= CLASS_CLS_METHODS (category
);
5459 if ((meth
= lookup_method (chain
, ident
)))
5462 /* Check for class methods in protocols in categories. */
5463 if (CLASS_PROTOCOL_LIST (category
))
5465 if ((meth
= (lookup_method_in_protocol_list
5466 (CLASS_PROTOCOL_LIST (category
), ident
, 1))))
5470 if ((category
= CLASS_CATEGORY_LIST (category
)))
5471 chain
= CLASS_CLS_METHODS (category
);
5476 /* Check for class methods in protocols. */
5477 if (CLASS_PROTOCOL_LIST (inter
))
5479 if ((meth
= (lookup_method_in_protocol_list
5480 (CLASS_PROTOCOL_LIST (inter
), ident
, 1))))
5485 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5486 chain
= CLASS_CLS_METHODS (inter
);
5490 /* If no class (factory) method was found, check if an _instance_
5491 method of the same name exists in the root class. This is what
5492 the Objective-C runtime will do. */
5493 return lookup_instance_method_static (root_inter
, ident
);
5497 add_class_method (class, method
)
5504 if (!(mth
= lookup_method (CLASS_CLS_METHODS (class), method
)))
5506 /* put method on list in reverse order */
5507 TREE_CHAIN (method
) = CLASS_CLS_METHODS (class);
5508 CLASS_CLS_METHODS (class) = method
;
5512 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5513 error ("duplicate definition of class method `%s'.",
5514 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5517 /* Check types; if different, complain. */
5518 if (!comp_proto_with_proto (method
, mth
))
5519 error ("duplicate declaration of class method `%s'.",
5520 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5524 if (!(hsh
= hash_lookup (cls_method_hash_list
, METHOD_SEL_NAME (method
))))
5526 /* Install on a global chain. */
5527 hash_enter (cls_method_hash_list
, method
);
5531 /* Check types; if different, add to a list. */
5532 if (!comp_proto_with_proto (method
, hsh
->key
))
5533 hash_add_attr (hsh
, method
);
5539 add_instance_method (class, method
)
5546 if (!(mth
= lookup_method (CLASS_NST_METHODS (class), method
)))
5548 /* Put method on list in reverse order. */
5549 TREE_CHAIN (method
) = CLASS_NST_METHODS (class);
5550 CLASS_NST_METHODS (class) = method
;
5554 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5555 error ("duplicate definition of instance method `%s'.",
5556 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5559 /* Check types; if different, complain. */
5560 if (!comp_proto_with_proto (method
, mth
))
5561 error ("duplicate declaration of instance method `%s'.",
5562 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5566 if (!(hsh
= hash_lookup (nst_method_hash_list
, METHOD_SEL_NAME (method
))))
5568 /* Install on a global chain. */
5569 hash_enter (nst_method_hash_list
, method
);
5573 /* Check types; if different, add to a list. */
5574 if (!comp_proto_with_proto (method
, hsh
->key
))
5575 hash_add_attr (hsh
, method
);
5584 /* Put interfaces on list in reverse order. */
5585 TREE_CHAIN (class) = interface_chain
;
5586 interface_chain
= class;
5587 return interface_chain
;
5591 add_category (class, category
)
5595 /* Put categories on list in reverse order. */
5596 tree cat
= CLASS_CATEGORY_LIST (class);
5600 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
5601 warning ("duplicate interface declaration for category `%s(%s)'",
5602 IDENTIFIER_POINTER (CLASS_NAME (class)),
5603 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category
)));
5604 cat
= CLASS_CATEGORY_LIST (cat
);
5607 CLASS_CATEGORY_LIST (category
) = CLASS_CATEGORY_LIST (class);
5608 CLASS_CATEGORY_LIST (class) = category
;
5611 /* Called after parsing each instance variable declaration. Necessary to
5612 preserve typedefs and implement public/private...
5614 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5617 add_instance_variable (class, public, declarator
, declspecs
, width
)
5624 tree field_decl
, raw_decl
;
5626 raw_decl
= build_tree_list (declspecs
, declarator
);
5628 if (CLASS_RAW_IVARS (class))
5629 chainon (CLASS_RAW_IVARS (class), raw_decl
);
5631 CLASS_RAW_IVARS (class) = raw_decl
;
5633 field_decl
= grokfield (input_filename
, lineno
,
5634 declarator
, declspecs
, width
);
5636 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5640 TREE_PUBLIC (field_decl
) = 0;
5641 TREE_PRIVATE (field_decl
) = 0;
5642 TREE_PROTECTED (field_decl
) = 1;
5646 TREE_PUBLIC (field_decl
) = 1;
5647 TREE_PRIVATE (field_decl
) = 0;
5648 TREE_PROTECTED (field_decl
) = 0;
5652 TREE_PUBLIC (field_decl
) = 0;
5653 TREE_PRIVATE (field_decl
) = 1;
5654 TREE_PROTECTED (field_decl
) = 0;
5659 if (CLASS_IVARS (class))
5660 chainon (CLASS_IVARS (class), field_decl
);
5662 CLASS_IVARS (class) = field_decl
;
5668 is_ivar (decl_chain
, ident
)
5672 for ( ; decl_chain
; decl_chain
= TREE_CHAIN (decl_chain
))
5673 if (DECL_NAME (decl_chain
) == ident
)
5678 /* True if the ivar is private and we are not in its implementation. */
5684 if (TREE_PRIVATE (decl
)
5685 && ! is_ivar (CLASS_IVARS (implementation_template
), DECL_NAME (decl
)))
5687 error ("instance variable `%s' is declared private",
5688 IDENTIFIER_POINTER (DECL_NAME (decl
)));
5695 /* We have an instance variable reference;, check to see if it is public. */
5698 is_public (expr
, identifier
)
5702 tree basetype
= TREE_TYPE (expr
);
5703 enum tree_code code
= TREE_CODE (basetype
);
5706 if (code
== RECORD_TYPE
)
5708 if (TREE_STATIC_TEMPLATE (basetype
))
5710 if (!lookup_interface (TYPE_NAME (basetype
)))
5712 error ("Cannot find interface declaration for `%s'",
5713 IDENTIFIER_POINTER (TYPE_NAME (basetype
)));
5717 if ((decl
= is_ivar (TYPE_FIELDS (basetype
), identifier
)))
5719 if (TREE_PUBLIC (decl
))
5722 /* Important difference between the Stepstone translator:
5723 all instance variables should be public within the context
5724 of the implementation. */
5725 if (objc_implementation_context
5726 && (((TREE_CODE (objc_implementation_context
)
5727 == CLASS_IMPLEMENTATION_TYPE
)
5728 || (TREE_CODE (objc_implementation_context
)
5729 == CATEGORY_IMPLEMENTATION_TYPE
))
5730 && (CLASS_NAME (objc_implementation_context
)
5731 == TYPE_NAME (basetype
))))
5732 return ! is_private (decl
);
5734 error ("instance variable `%s' is declared %s",
5735 IDENTIFIER_POINTER (identifier
),
5736 TREE_PRIVATE (decl
) ? "private" : "protected");
5741 else if (objc_implementation_context
&& (basetype
== objc_object_reference
))
5743 TREE_TYPE (expr
) = uprivate_record
;
5744 warning ("static access to object of type `id'");
5751 /* Implement @defs (<classname>) within struct bodies. */
5754 get_class_ivars (interface
)
5757 /* Make sure we copy the leaf ivars in case @defs is used in a local
5758 context. Otherwise finish_struct will overwrite the layout info
5759 using temporary storage. */
5760 return build_ivar_chain (interface
, 1);
5763 /* Make sure all entries in CHAIN are also in LIST. */
5766 check_methods (chain
, list
, mtype
)
5775 if (!lookup_method (list
, chain
))
5779 if (TREE_CODE (objc_implementation_context
)
5780 == CLASS_IMPLEMENTATION_TYPE
)
5781 warning ("incomplete implementation of class `%s'",
5782 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
)));
5783 else if (TREE_CODE (objc_implementation_context
)
5784 == CATEGORY_IMPLEMENTATION_TYPE
)
5785 warning ("incomplete implementation of category `%s'",
5786 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
5790 warning ("method definition for `%c%s' not found",
5791 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
5794 chain
= TREE_CHAIN (chain
);
5800 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
5803 conforms_to_protocol (class, protocol
)
5807 if (TREE_CODE (protocol
) == PROTOCOL_INTERFACE_TYPE
)
5809 tree p
= CLASS_PROTOCOL_LIST (class);
5810 while (p
&& TREE_VALUE (p
) != protocol
)
5815 tree super
= (CLASS_SUPER_NAME (class)
5816 ? lookup_interface (CLASS_SUPER_NAME (class))
5818 int tmp
= super
? conforms_to_protocol (super
, protocol
) : 0;
5827 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5828 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5831 check_methods_accessible (chain
, context
, mtype
)
5838 tree base_context
= context
;
5842 context
= base_context
;
5846 list
= CLASS_CLS_METHODS (context
);
5848 list
= CLASS_NST_METHODS (context
);
5850 if (lookup_method (list
, chain
))
5853 else if (TREE_CODE (context
) == CLASS_IMPLEMENTATION_TYPE
5854 || TREE_CODE (context
) == CLASS_INTERFACE_TYPE
)
5855 context
= (CLASS_SUPER_NAME (context
)
5856 ? lookup_interface (CLASS_SUPER_NAME (context
))
5859 else if (TREE_CODE (context
) == CATEGORY_IMPLEMENTATION_TYPE
5860 || TREE_CODE (context
) == CATEGORY_INTERFACE_TYPE
)
5861 context
= (CLASS_NAME (context
)
5862 ? lookup_interface (CLASS_NAME (context
))
5868 if (context
== NULL_TREE
)
5872 if (TREE_CODE (objc_implementation_context
)
5873 == CLASS_IMPLEMENTATION_TYPE
)
5874 warning ("incomplete implementation of class `%s'",
5876 (CLASS_NAME (objc_implementation_context
)));
5877 else if (TREE_CODE (objc_implementation_context
)
5878 == CATEGORY_IMPLEMENTATION_TYPE
)
5879 warning ("incomplete implementation of category `%s'",
5881 (CLASS_SUPER_NAME (objc_implementation_context
)));
5884 warning ("method definition for `%c%s' not found",
5885 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
5888 chain
= TREE_CHAIN (chain
); /* next method... */
5893 /* Check whether the current interface (accessible via
5894 'objc_implementation_context') actually implements protocol P, along
5895 with any protocols that P inherits. */
5898 check_protocol (p
, type
, name
)
5903 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
5907 /* Ensure that all protocols have bodies! */
5908 if (flag_warn_protocol
)
5910 f1
= check_methods (PROTOCOL_CLS_METHODS (p
),
5911 CLASS_CLS_METHODS (objc_implementation_context
),
5913 f2
= check_methods (PROTOCOL_NST_METHODS (p
),
5914 CLASS_NST_METHODS (objc_implementation_context
),
5919 f1
= check_methods_accessible (PROTOCOL_CLS_METHODS (p
),
5920 objc_implementation_context
,
5922 f2
= check_methods_accessible (PROTOCOL_NST_METHODS (p
),
5923 objc_implementation_context
,
5928 warning ("%s `%s' does not fully implement the `%s' protocol",
5929 type
, name
, IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
5932 /* Check protocols recursively. */
5933 if (PROTOCOL_LIST (p
))
5935 tree subs
= PROTOCOL_LIST (p
);
5937 lookup_interface (CLASS_SUPER_NAME (implementation_template
));
5940 tree sub
= TREE_VALUE (subs
);
5942 /* If the superclass does not conform to the protocols
5943 inherited by P, then we must! */
5944 if (!super_class
|| !conforms_to_protocol (super_class
, sub
))
5945 check_protocol (sub
, type
, name
);
5946 subs
= TREE_CHAIN (subs
);
5951 /* Check whether the current interface (accessible via
5952 'objc_implementation_context') actually implements the protocols listed
5956 check_protocols (proto_list
, type
, name
)
5961 for ( ; proto_list
; proto_list
= TREE_CHAIN (proto_list
))
5963 tree p
= TREE_VALUE (proto_list
);
5965 check_protocol (p
, type
, name
);
5969 /* Make sure that the class CLASS_NAME is defined
5970 CODE says which kind of thing CLASS_NAME ought to be.
5971 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
5972 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
5975 start_class (code
, class_name
, super_name
, protocol_list
)
5976 enum tree_code code
;
5983 if (objc_implementation_context
)
5985 warning ("`@end' missing in implementation context");
5986 finish_class (objc_implementation_context
);
5987 objc_ivar_chain
= NULL_TREE
;
5988 objc_implementation_context
= NULL_TREE
;
5991 class = make_node (code
);
5992 TYPE_BINFO (class) = make_tree_vec (5);
5994 CLASS_NAME (class) = class_name
;
5995 CLASS_SUPER_NAME (class) = super_name
;
5996 CLASS_CLS_METHODS (class) = NULL_TREE
;
5998 if (! is_class_name (class_name
) && (decl
= lookup_name (class_name
)))
6000 error ("`%s' redeclared as different kind of symbol",
6001 IDENTIFIER_POINTER (class_name
));
6002 error_with_decl (decl
, "previous declaration of `%s'");
6005 if (code
== CLASS_IMPLEMENTATION_TYPE
)
6010 for (chain
= implemented_classes
; chain
; chain
= TREE_CHAIN (chain
))
6011 if (TREE_VALUE (chain
) == class_name
)
6013 error ("reimplementation of class `%s'",
6014 IDENTIFIER_POINTER (class_name
));
6015 return error_mark_node
;
6017 implemented_classes
= tree_cons (NULL_TREE
, class_name
,
6018 implemented_classes
);
6021 /* Pre-build the following entities - for speed/convenience. */
6023 self_id
= get_identifier ("self");
6025 ucmd_id
= get_identifier ("_cmd");
6028 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6029 if (!objc_super_template
)
6030 objc_super_template
= build_super_template ();
6032 /* Reset for multiple classes per file. */
6035 objc_implementation_context
= class;
6037 /* Lookup the interface for this implementation. */
6039 if (!(implementation_template
= lookup_interface (class_name
)))
6041 warning ("Cannot find interface declaration for `%s'",
6042 IDENTIFIER_POINTER (class_name
));
6043 add_class (implementation_template
= objc_implementation_context
);
6046 /* If a super class has been specified in the implementation,
6047 insure it conforms to the one specified in the interface. */
6050 && (super_name
!= CLASS_SUPER_NAME (implementation_template
)))
6052 tree previous_name
= CLASS_SUPER_NAME (implementation_template
);
6053 const char *const name
=
6054 previous_name
? IDENTIFIER_POINTER (previous_name
) : "";
6055 error ("conflicting super class name `%s'",
6056 IDENTIFIER_POINTER (super_name
));
6057 error ("previous declaration of `%s'", name
);
6060 else if (! super_name
)
6062 CLASS_SUPER_NAME (objc_implementation_context
)
6063 = CLASS_SUPER_NAME (implementation_template
);
6067 else if (code
== CLASS_INTERFACE_TYPE
)
6069 if (lookup_interface (class_name
))
6070 warning ("duplicate interface declaration for class `%s'",
6071 IDENTIFIER_POINTER (class_name
));
6076 CLASS_PROTOCOL_LIST (class)
6077 = lookup_and_install_protocols (protocol_list
);
6080 else if (code
== CATEGORY_INTERFACE_TYPE
)
6082 tree class_category_is_assoc_with
;
6084 /* For a category, class_name is really the name of the class that
6085 the following set of methods will be associated with. We must
6086 find the interface so that can derive the objects template. */
6088 if (!(class_category_is_assoc_with
= lookup_interface (class_name
)))
6090 error ("Cannot find interface declaration for `%s'",
6091 IDENTIFIER_POINTER (class_name
));
6092 exit (FATAL_EXIT_CODE
);
6095 add_category (class_category_is_assoc_with
, class);
6098 CLASS_PROTOCOL_LIST (class)
6099 = lookup_and_install_protocols (protocol_list
);
6102 else if (code
== CATEGORY_IMPLEMENTATION_TYPE
)
6104 /* Pre-build the following entities for speed/convenience. */
6106 self_id
= get_identifier ("self");
6108 ucmd_id
= get_identifier ("_cmd");
6111 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6112 if (!objc_super_template
)
6113 objc_super_template
= build_super_template ();
6115 /* Reset for multiple classes per file. */
6118 objc_implementation_context
= class;
6120 /* For a category, class_name is really the name of the class that
6121 the following set of methods will be associated with. We must
6122 find the interface so that can derive the objects template. */
6124 if (!(implementation_template
= lookup_interface (class_name
)))
6126 error ("Cannot find interface declaration for `%s'",
6127 IDENTIFIER_POINTER (class_name
));
6128 exit (FATAL_EXIT_CODE
);
6135 continue_class (class)
6138 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6139 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6141 struct imp_entry
*imp_entry
;
6144 /* Check consistency of the instance variables. */
6146 if (CLASS_IVARS (class))
6147 check_ivars (implementation_template
, class);
6149 /* code generation */
6151 ivar_context
= build_private_template (implementation_template
);
6153 if (!objc_class_template
)
6154 build_class_template ();
6156 imp_entry
= (struct imp_entry
*) xmalloc (sizeof (struct imp_entry
));
6158 imp_entry
->next
= imp_list
;
6159 imp_entry
->imp_context
= class;
6160 imp_entry
->imp_template
= implementation_template
;
6162 synth_forward_declarations ();
6163 imp_entry
->class_decl
= UOBJC_CLASS_decl
;
6164 imp_entry
->meta_decl
= UOBJC_METACLASS_decl
;
6166 /* Append to front and increment count. */
6167 imp_list
= imp_entry
;
6168 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6173 return ivar_context
;
6176 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6178 tree record
= xref_tag (RECORD_TYPE
, CLASS_NAME (class));
6180 if (!TYPE_FIELDS (record
))
6182 finish_struct (record
, build_ivar_chain (class, 0), NULL_TREE
);
6183 CLASS_STATIC_TEMPLATE (class) = record
;
6185 /* Mark this record as a class template for static typing. */
6186 TREE_STATIC_TEMPLATE (record
) = 1;
6193 return error_mark_node
;
6196 /* This is called once we see the "@end" in an interface/implementation. */
6199 finish_class (class)
6202 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6204 /* All code generation is done in finish_objc. */
6206 if (implementation_template
!= objc_implementation_context
)
6208 /* Ensure that all method listed in the interface contain bodies. */
6209 check_methods (CLASS_CLS_METHODS (implementation_template
),
6210 CLASS_CLS_METHODS (objc_implementation_context
), '+');
6211 check_methods (CLASS_NST_METHODS (implementation_template
),
6212 CLASS_NST_METHODS (objc_implementation_context
), '-');
6214 if (CLASS_PROTOCOL_LIST (implementation_template
))
6215 check_protocols (CLASS_PROTOCOL_LIST (implementation_template
),
6217 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
)));
6221 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6223 tree category
= CLASS_CATEGORY_LIST (implementation_template
);
6225 /* Find the category interface from the class it is associated with. */
6228 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category
))
6230 category
= CLASS_CATEGORY_LIST (category
);
6235 /* Ensure all method listed in the interface contain bodies. */
6236 check_methods (CLASS_CLS_METHODS (category
),
6237 CLASS_CLS_METHODS (objc_implementation_context
), '+');
6238 check_methods (CLASS_NST_METHODS (category
),
6239 CLASS_NST_METHODS (objc_implementation_context
), '-');
6241 if (CLASS_PROTOCOL_LIST (category
))
6242 check_protocols (CLASS_PROTOCOL_LIST (category
),
6244 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
6248 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6251 const char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (class));
6252 char *string
= (char *) alloca (strlen (class_name
) + 3);
6254 /* extern struct objc_object *_<my_name>; */
6256 sprintf (string
, "_%s", class_name
);
6258 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
6259 decl_specs
= tree_cons (NULL_TREE
, objc_object_reference
, decl_specs
);
6260 define_decl (build1 (INDIRECT_REF
, NULL_TREE
, get_identifier (string
)),
6266 add_protocol (protocol
)
6269 /* Put protocol on list in reverse order. */
6270 TREE_CHAIN (protocol
) = protocol_chain
;
6271 protocol_chain
= protocol
;
6272 return protocol_chain
;
6276 lookup_protocol (ident
)
6281 for (chain
= protocol_chain
; chain
; chain
= TREE_CHAIN (chain
))
6283 if (ident
== PROTOCOL_NAME (chain
))
6290 /* This function forward declares the protocols named by NAMES. If
6291 they are already declared or defined, the function has no effect. */
6294 objc_declare_protocols (names
)
6299 for (list
= names
; list
; list
= TREE_CHAIN (list
))
6301 tree name
= TREE_VALUE (list
);
6303 if (lookup_protocol (name
) == NULL_TREE
)
6305 tree protocol
= make_node (PROTOCOL_INTERFACE_TYPE
);
6307 TYPE_BINFO (protocol
) = make_tree_vec (2);
6308 PROTOCOL_NAME (protocol
) = name
;
6309 PROTOCOL_LIST (protocol
) = NULL_TREE
;
6310 add_protocol (protocol
);
6311 PROTOCOL_DEFINED (protocol
) = 0;
6312 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6318 start_protocol (code
, name
, list
)
6319 enum tree_code code
;
6325 /* This is as good a place as any. Need to invoke
6326 push_tag_toplevel. */
6327 if (!objc_protocol_template
)
6328 objc_protocol_template
= build_protocol_template ();
6330 protocol
= lookup_protocol (name
);
6334 protocol
= make_node (code
);
6335 TYPE_BINFO (protocol
) = make_tree_vec (2);
6337 PROTOCOL_NAME (protocol
) = name
;
6338 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
6339 add_protocol (protocol
);
6340 PROTOCOL_DEFINED (protocol
) = 1;
6341 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6343 check_protocol_recursively (protocol
, list
);
6345 else if (! PROTOCOL_DEFINED (protocol
))
6347 PROTOCOL_DEFINED (protocol
) = 1;
6348 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
6350 check_protocol_recursively (protocol
, list
);
6354 warning ("duplicate declaration for protocol `%s'",
6355 IDENTIFIER_POINTER (name
));
6361 finish_protocol (protocol
)
6362 tree protocol ATTRIBUTE_UNUSED
;
6367 /* "Encode" a data type into a string, which grows in util_obstack.
6368 ??? What is the FORMAT? Someone please document this! */
6371 encode_type_qualifiers (declspecs
)
6376 for (spec
= declspecs
; spec
; spec
= TREE_CHAIN (spec
))
6378 if (ridpointers
[(int) RID_CONST
] == TREE_VALUE (spec
))
6379 obstack_1grow (&util_obstack
, 'r');
6380 else if (ridpointers
[(int) RID_IN
] == TREE_VALUE (spec
))
6381 obstack_1grow (&util_obstack
, 'n');
6382 else if (ridpointers
[(int) RID_INOUT
] == TREE_VALUE (spec
))
6383 obstack_1grow (&util_obstack
, 'N');
6384 else if (ridpointers
[(int) RID_OUT
] == TREE_VALUE (spec
))
6385 obstack_1grow (&util_obstack
, 'o');
6386 else if (ridpointers
[(int) RID_BYCOPY
] == TREE_VALUE (spec
))
6387 obstack_1grow (&util_obstack
, 'O');
6388 else if (ridpointers
[(int) RID_BYREF
] == TREE_VALUE (spec
))
6389 obstack_1grow (&util_obstack
, 'R');
6390 else if (ridpointers
[(int) RID_ONEWAY
] == TREE_VALUE (spec
))
6391 obstack_1grow (&util_obstack
, 'V');
6395 /* Encode a pointer type. */
6398 encode_pointer (type
, curtype
, format
)
6403 tree pointer_to
= TREE_TYPE (type
);
6405 if (TREE_CODE (pointer_to
) == RECORD_TYPE
)
6407 if (TYPE_NAME (pointer_to
)
6408 && TREE_CODE (TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
)
6410 const char *name
= IDENTIFIER_POINTER (TYPE_NAME (pointer_to
));
6412 if (strcmp (name
, TAG_OBJECT
) == 0) /* '@' */
6414 obstack_1grow (&util_obstack
, '@');
6417 else if (TREE_STATIC_TEMPLATE (pointer_to
))
6419 if (generating_instance_variables
)
6421 obstack_1grow (&util_obstack
, '@');
6422 obstack_1grow (&util_obstack
, '"');
6423 obstack_grow (&util_obstack
, name
, strlen (name
));
6424 obstack_1grow (&util_obstack
, '"');
6429 obstack_1grow (&util_obstack
, '@');
6433 else if (strcmp (name
, TAG_CLASS
) == 0) /* '#' */
6435 obstack_1grow (&util_obstack
, '#');
6438 else if (strcmp (name
, TAG_SELECTOR
) == 0) /* ':' */
6440 obstack_1grow (&util_obstack
, ':');
6445 else if (TREE_CODE (pointer_to
) == INTEGER_TYPE
6446 && TYPE_MODE (pointer_to
) == QImode
)
6448 obstack_1grow (&util_obstack
, '*');
6452 /* We have a type that does not get special treatment. */
6454 /* NeXT extension */
6455 obstack_1grow (&util_obstack
, '^');
6456 encode_type (pointer_to
, curtype
, format
);
6460 encode_array (type
, curtype
, format
)
6465 tree an_int_cst
= TYPE_SIZE (type
);
6466 tree array_of
= TREE_TYPE (type
);
6469 /* An incomplete array is treated like a pointer. */
6470 if (an_int_cst
== NULL
)
6472 encode_pointer (type
, curtype
, format
);
6476 sprintf (buffer
, "[%ld",
6477 (long) (TREE_INT_CST_LOW (an_int_cst
)
6478 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
6480 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6481 encode_type (array_of
, curtype
, format
);
6482 obstack_1grow (&util_obstack
, ']');
6487 encode_aggregate_within (type
, curtype
, format
, left
, right
)
6494 /* The RECORD_TYPE may in fact be a typedef! For purposes
6495 of encoding, we need the real underlying enchilada. */
6496 if (TYPE_MAIN_VARIANT (type
))
6497 type
= TYPE_MAIN_VARIANT (type
);
6499 if (obstack_object_size (&util_obstack
) > 0
6500 && *(obstack_next_free (&util_obstack
) - 1) == '^')
6502 tree name
= TYPE_NAME (type
);
6504 /* we have a reference; this is a NeXT extension. */
6506 if (obstack_object_size (&util_obstack
) - curtype
== 1
6507 && format
== OBJC_ENCODE_INLINE_DEFS
)
6509 /* Output format of struct for first level only. */
6510 tree fields
= TYPE_FIELDS (type
);
6512 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6514 obstack_1grow (&util_obstack
, left
);
6515 obstack_grow (&util_obstack
,
6516 IDENTIFIER_POINTER (name
),
6517 strlen (IDENTIFIER_POINTER (name
)));
6518 obstack_1grow (&util_obstack
, '=');
6522 obstack_1grow (&util_obstack
, left
);
6523 obstack_grow (&util_obstack
, "?=", 2);
6526 for ( ; fields
; fields
= TREE_CHAIN (fields
))
6527 encode_field_decl (fields
, curtype
, format
);
6529 obstack_1grow (&util_obstack
, right
);
6532 else 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
, right
);
6543 /* We have an untagged structure or a typedef. */
6544 obstack_1grow (&util_obstack
, left
);
6545 obstack_1grow (&util_obstack
, '?');
6546 obstack_1grow (&util_obstack
, right
);
6552 tree name
= TYPE_NAME (type
);
6553 tree fields
= TYPE_FIELDS (type
);
6555 if (format
== OBJC_ENCODE_INLINE_DEFS
6556 || generating_instance_variables
)
6558 obstack_1grow (&util_obstack
, left
);
6559 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6560 obstack_grow (&util_obstack
,
6561 IDENTIFIER_POINTER (name
),
6562 strlen (IDENTIFIER_POINTER (name
)));
6564 obstack_1grow (&util_obstack
, '?');
6566 obstack_1grow (&util_obstack
, '=');
6568 for (; fields
; fields
= TREE_CHAIN (fields
))
6570 if (generating_instance_variables
)
6572 tree fname
= DECL_NAME (fields
);
6574 obstack_1grow (&util_obstack
, '"');
6575 if (fname
&& TREE_CODE (fname
) == IDENTIFIER_NODE
)
6577 obstack_grow (&util_obstack
,
6578 IDENTIFIER_POINTER (fname
),
6579 strlen (IDENTIFIER_POINTER (fname
)));
6582 obstack_1grow (&util_obstack
, '"');
6585 encode_field_decl (fields
, curtype
, format
);
6588 obstack_1grow (&util_obstack
, right
);
6593 obstack_1grow (&util_obstack
, left
);
6594 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6595 obstack_grow (&util_obstack
,
6596 IDENTIFIER_POINTER (name
),
6597 strlen (IDENTIFIER_POINTER (name
)));
6599 /* We have an untagged structure or a typedef. */
6600 obstack_1grow (&util_obstack
, '?');
6602 obstack_1grow (&util_obstack
, right
);
6608 encode_aggregate (type
, curtype
, format
)
6613 enum tree_code code
= TREE_CODE (type
);
6619 encode_aggregate_within(type
, curtype
, format
, '{', '}');
6624 encode_aggregate_within(type
, curtype
, format
, '(', ')');
6629 obstack_1grow (&util_obstack
, 'i');
6637 /* Support bitfields. The current version of Objective-C does not support
6638 them. The string will consist of one or more "b:n"'s where n is an
6639 integer describing the width of the bitfield. Currently, classes in
6640 the kit implement a method "-(char *)describeBitfieldStruct:" that
6641 simulates this. If they do not implement this method, the archiver
6642 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6643 according to the GNU compiler. After looking at the "kit", it appears
6644 that all classes currently rely on this default behavior, rather than
6645 hand generating this string (which is tedious). */
6648 encode_bitfield (width
)
6652 sprintf (buffer
, "b%d", width
);
6653 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6656 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6659 encode_type (type
, curtype
, format
)
6664 enum tree_code code
= TREE_CODE (type
);
6666 if (code
== INTEGER_TYPE
)
6668 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6670 /* Unsigned integer types. */
6672 if (TYPE_MODE (type
) == QImode
)
6673 obstack_1grow (&util_obstack
, 'C');
6674 else if (TYPE_MODE (type
) == HImode
)
6675 obstack_1grow (&util_obstack
, 'S');
6676 else if (TYPE_MODE (type
) == SImode
)
6678 if (type
== long_unsigned_type_node
)
6679 obstack_1grow (&util_obstack
, 'L');
6681 obstack_1grow (&util_obstack
, 'I');
6683 else if (TYPE_MODE (type
) == DImode
)
6684 obstack_1grow (&util_obstack
, 'Q');
6688 /* Signed integer types. */
6690 if (TYPE_MODE (type
) == QImode
)
6691 obstack_1grow (&util_obstack
, 'c');
6692 else if (TYPE_MODE (type
) == HImode
)
6693 obstack_1grow (&util_obstack
, 's');
6694 else if (TYPE_MODE (type
) == SImode
)
6696 if (type
== long_integer_type_node
)
6697 obstack_1grow (&util_obstack
, 'l');
6699 obstack_1grow (&util_obstack
, 'i');
6702 else if (TYPE_MODE (type
) == DImode
)
6703 obstack_1grow (&util_obstack
, 'q');
6707 else if (code
== REAL_TYPE
)
6709 /* Floating point types. */
6711 if (TYPE_MODE (type
) == SFmode
)
6712 obstack_1grow (&util_obstack
, 'f');
6713 else if (TYPE_MODE (type
) == DFmode
6714 || TYPE_MODE (type
) == TFmode
)
6715 obstack_1grow (&util_obstack
, 'd');
6718 else if (code
== VOID_TYPE
)
6719 obstack_1grow (&util_obstack
, 'v');
6721 else if (code
== ARRAY_TYPE
)
6722 encode_array (type
, curtype
, format
);
6724 else if (code
== POINTER_TYPE
)
6725 encode_pointer (type
, curtype
, format
);
6727 else if (code
== RECORD_TYPE
|| code
== UNION_TYPE
|| code
== ENUMERAL_TYPE
)
6728 encode_aggregate (type
, curtype
, format
);
6730 else if (code
== FUNCTION_TYPE
) /* '?' */
6731 obstack_1grow (&util_obstack
, '?');
6735 encode_complete_bitfield (int position
, tree type
, int size
)
6737 enum tree_code code
= TREE_CODE (type
);
6739 char charType
= '?';
6741 if (code
== INTEGER_TYPE
)
6743 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6745 /* Unsigned integer types. */
6747 if (TYPE_MODE (type
) == QImode
)
6749 else if (TYPE_MODE (type
) == HImode
)
6751 else if (TYPE_MODE (type
) == SImode
)
6753 if (type
== long_unsigned_type_node
)
6758 else if (TYPE_MODE (type
) == DImode
)
6763 /* Signed integer types. */
6765 if (TYPE_MODE (type
) == QImode
)
6767 else if (TYPE_MODE (type
) == HImode
)
6769 else if (TYPE_MODE (type
) == SImode
)
6771 if (type
== long_integer_type_node
)
6777 else if (TYPE_MODE (type
) == DImode
)
6785 sprintf (buffer
, "b%d%c%d", position
, charType
, size
);
6786 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6790 encode_field_decl (field_decl
, curtype
, format
)
6797 type
= TREE_TYPE (field_decl
);
6799 /* If this field is obviously a bitfield, or is a bitfield that has been
6800 clobbered to look like a ordinary integer mode, go ahead and generate
6801 the bitfield typing information. */
6802 if (flag_next_runtime
)
6804 if (DECL_BIT_FIELD (field_decl
))
6805 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl
), 1));
6807 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6811 if (DECL_BIT_FIELD (field_decl
))
6812 encode_complete_bitfield (int_bit_position (field_decl
),
6813 DECL_BIT_FIELD_TYPE (field_decl
),
6814 tree_low_cst (DECL_SIZE (field_decl
), 1));
6816 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6821 expr_last (complex_expr
)
6827 while ((next
= TREE_OPERAND (complex_expr
, 0)))
6828 complex_expr
= next
;
6830 return complex_expr
;
6833 /* Transform a method definition into a function definition as follows:
6834 - synthesize the first two arguments, "self" and "_cmd". */
6837 start_method_def (method
)
6842 /* Required to implement _msgSuper. */
6843 objc_method_context
= method
;
6844 UOBJC_SUPER_decl
= NULL_TREE
;
6846 /* Must be called BEFORE start_function. */
6849 /* Generate prototype declarations for arguments..."new-style". */
6851 if (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
)
6852 decl_specs
= build_tree_list (NULL_TREE
, uprivate_record
);
6854 /* Really a `struct objc_class *'. However, we allow people to
6855 assign to self, which changes its type midstream. */
6856 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
6858 push_parm_decl (build_tree_list
6859 (build_tree_list (decl_specs
,
6860 build1 (INDIRECT_REF
, NULL_TREE
, self_id
)),
6863 decl_specs
= build_tree_list (NULL_TREE
,
6864 xref_tag (RECORD_TYPE
,
6865 get_identifier (TAG_SELECTOR
)));
6866 push_parm_decl (build_tree_list
6867 (build_tree_list (decl_specs
,
6868 build1 (INDIRECT_REF
, NULL_TREE
, ucmd_id
)),
6871 /* Generate argument declarations if a keyword_decl. */
6872 if (METHOD_SEL_ARGS (method
))
6874 tree arglist
= METHOD_SEL_ARGS (method
);
6877 tree arg_spec
= TREE_PURPOSE (TREE_TYPE (arglist
));
6878 tree arg_decl
= TREE_VALUE (TREE_TYPE (arglist
));
6882 tree last_expr
= expr_last (arg_decl
);
6884 /* Unite the abstract decl with its name. */
6885 TREE_OPERAND (last_expr
, 0) = KEYWORD_ARG_NAME (arglist
);
6886 push_parm_decl (build_tree_list
6887 (build_tree_list (arg_spec
, arg_decl
),
6890 /* Unhook: restore the abstract declarator. */
6891 TREE_OPERAND (last_expr
, 0) = NULL_TREE
;
6895 push_parm_decl (build_tree_list
6896 (build_tree_list (arg_spec
,
6897 KEYWORD_ARG_NAME (arglist
)),
6900 arglist
= TREE_CHAIN (arglist
);
6905 if (METHOD_ADD_ARGS (method
) != NULL_TREE
6906 && METHOD_ADD_ARGS (method
) != objc_ellipsis_node
)
6908 /* We have a variable length selector - in "prototype" format. */
6909 tree akey
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
6912 /* This must be done prior to calling pushdecl. pushdecl is
6913 going to change our chain on us. */
6914 tree nextkey
= TREE_CHAIN (akey
);
6922 warn_with_method (message
, mtype
, method
)
6923 const char *message
;
6927 if (count_error (1) == 0)
6930 report_error_function (DECL_SOURCE_FILE (method
));
6932 /* Add a readable method name to the warning. */
6933 warning_with_file_and_line (DECL_SOURCE_FILE (method
),
6934 DECL_SOURCE_LINE (method
),
6937 gen_method_decl (method
, errbuf
));
6940 /* Return 1 if METHOD is consistent with PROTO. */
6943 comp_method_with_proto (method
, proto
)
6946 /* Create a function template node at most once. */
6947 if (!function1_template
)
6948 function1_template
= make_node (FUNCTION_TYPE
);
6950 /* Install argument types - normally set by build_function_type. */
6951 TYPE_ARG_TYPES (function1_template
) = get_arg_type_list (proto
, METHOD_DEF
, 0);
6953 /* install return type */
6954 TREE_TYPE (function1_template
) = groktypename (TREE_TYPE (proto
));
6956 return comptypes (TREE_TYPE (METHOD_DEFINITION (method
)), function1_template
);
6959 /* Return 1 if PROTO1 is consistent with PROTO2. */
6962 comp_proto_with_proto (proto0
, proto1
)
6963 tree proto0
, proto1
;
6965 /* Create a couple of function_template nodes at most once. */
6966 if (!function1_template
)
6967 function1_template
= make_node (FUNCTION_TYPE
);
6968 if (!function2_template
)
6969 function2_template
= make_node (FUNCTION_TYPE
);
6971 /* Install argument types; normally set by build_function_type. */
6972 TYPE_ARG_TYPES (function1_template
) = get_arg_type_list (proto0
, METHOD_REF
, 0);
6973 TYPE_ARG_TYPES (function2_template
) = get_arg_type_list (proto1
, METHOD_REF
, 0);
6975 /* Install return type. */
6976 TREE_TYPE (function1_template
) = groktypename (TREE_TYPE (proto0
));
6977 TREE_TYPE (function2_template
) = groktypename (TREE_TYPE (proto1
));
6979 return comptypes (function1_template
, function2_template
);
6982 /* - Generate an identifier for the function. the format is "_n_cls",
6983 where 1 <= n <= nMethods, and cls is the name the implementation we
6985 - Install the return type from the method declaration.
6986 - If we have a prototype, check for type consistency. */
6989 really_start_method (method
, parmlist
)
6990 tree method
, parmlist
;
6992 tree sc_spec
, ret_spec
, ret_decl
, decl_specs
;
6993 tree method_decl
, method_id
;
6994 const char *sel_name
, *class_name
, *cat_name
;
6997 /* Synth the storage class & assemble the return type. */
6998 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
6999 ret_spec
= TREE_PURPOSE (TREE_TYPE (method
));
7000 decl_specs
= chainon (sc_spec
, ret_spec
);
7002 sel_name
= IDENTIFIER_POINTER (METHOD_SEL_NAME (method
));
7003 class_name
= IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
7004 cat_name
= ((TREE_CODE (objc_implementation_context
)
7005 == CLASS_IMPLEMENTATION_TYPE
)
7007 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
7010 /* Make sure this is big enough for any plausible method label. */
7011 buf
= (char *) alloca (50 + strlen (sel_name
) + strlen (class_name
)
7012 + (cat_name
? strlen (cat_name
) : 0));
7014 OBJC_GEN_METHOD_LABEL (buf
, TREE_CODE (method
) == INSTANCE_METHOD_DECL
,
7015 class_name
, cat_name
, sel_name
, method_slot
);
7017 method_id
= get_identifier (buf
);
7019 method_decl
= build_nt (CALL_EXPR
, method_id
, parmlist
, NULL_TREE
);
7021 /* Check the declarator portion of the return type for the method. */
7022 if ((ret_decl
= TREE_VALUE (TREE_TYPE (method
))))
7024 /* Unite the complex decl (specified in the abstract decl) with the
7025 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7026 tree save_expr
= expr_last (ret_decl
);
7028 TREE_OPERAND (save_expr
, 0) = method_decl
;
7029 method_decl
= ret_decl
;
7031 /* Fool the parser into thinking it is starting a function. */
7032 start_function (decl_specs
, method_decl
, NULL_TREE
);
7034 /* Unhook: this has the effect of restoring the abstract declarator. */
7035 TREE_OPERAND (save_expr
, 0) = NULL_TREE
;
7040 TREE_VALUE (TREE_TYPE (method
)) = method_decl
;
7042 /* Fool the parser into thinking it is starting a function. */
7043 start_function (decl_specs
, method_decl
, NULL_TREE
);
7045 /* Unhook: this has the effect of restoring the abstract declarator. */
7046 TREE_VALUE (TREE_TYPE (method
)) = NULL_TREE
;
7049 METHOD_DEFINITION (method
) = current_function_decl
;
7051 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7053 if (implementation_template
!= objc_implementation_context
)
7057 if (TREE_CODE (method
) == INSTANCE_METHOD_DECL
)
7058 proto
= lookup_instance_method_static (implementation_template
,
7059 METHOD_SEL_NAME (method
));
7061 proto
= lookup_class_method_static (implementation_template
,
7062 METHOD_SEL_NAME (method
));
7064 if (proto
&& ! comp_method_with_proto (method
, proto
))
7066 char type
= (TREE_CODE (method
) == INSTANCE_METHOD_DECL
? '-' : '+');
7068 warn_with_method ("conflicting types for", type
, method
);
7069 warn_with_method ("previous declaration of", type
, proto
);
7074 /* The following routine is always called...this "architecture" is to
7075 accommodate "old-style" variable length selectors.
7077 - a:a b:b // prototype ; id c; id d; // old-style. */
7080 continue_method_def ()
7084 if (METHOD_ADD_ARGS (objc_method_context
) == objc_ellipsis_node
)
7085 /* We have a `, ...' immediately following the selector. */
7086 parmlist
= get_parm_info (0);
7088 parmlist
= get_parm_info (1); /* place a `void_at_end' */
7090 /* Set self_decl from the first argument...this global is used by
7091 build_ivar_reference calling build_indirect_ref. */
7092 self_decl
= TREE_PURPOSE (parmlist
);
7095 really_start_method (objc_method_context
, parmlist
);
7096 store_parm_decls ();
7099 /* Called by the parser, from the `pushlevel' production. */
7104 if (!UOBJC_SUPER_decl
)
7106 UOBJC_SUPER_decl
= start_decl (get_identifier (UTAG_SUPER
),
7107 build_tree_list (NULL_TREE
,
7108 objc_super_template
),
7111 finish_decl (UOBJC_SUPER_decl
, NULL_TREE
, NULL_TREE
);
7113 /* This prevents `unused variable' warnings when compiling with -Wall. */
7114 TREE_USED (UOBJC_SUPER_decl
) = 1;
7115 DECL_ARTIFICIAL (UOBJC_SUPER_decl
) = 1;
7119 /* _n_Method (id self, SEL sel, ...)
7121 struct objc_super _S;
7122 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7126 get_super_receiver ()
7128 if (objc_method_context
)
7130 tree super_expr
, super_expr_list
;
7132 /* Set receiver to self. */
7133 super_expr
= build_component_ref (UOBJC_SUPER_decl
, self_id
);
7134 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, self_decl
);
7135 super_expr_list
= build_tree_list (NULL_TREE
, super_expr
);
7137 /* Set class to begin searching. */
7138 super_expr
= build_component_ref (UOBJC_SUPER_decl
,
7139 get_identifier ("class"));
7141 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
7143 /* [_cls, __cls]Super are "pre-built" in
7144 synth_forward_declarations. */
7146 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
,
7147 ((TREE_CODE (objc_method_context
)
7148 == INSTANCE_METHOD_DECL
)
7150 : uucls_super_ref
));
7154 /* We have a category. */
7156 tree super_name
= CLASS_SUPER_NAME (implementation_template
);
7159 /* Barf if super used in a category of Object. */
7162 error ("no super class declared in interface for `%s'",
7163 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
7164 return error_mark_node
;
7167 if (flag_next_runtime
)
7169 super_class
= get_class_reference (super_name
);
7170 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
7172 = build_component_ref (build_indirect_ref (super_class
, "->"),
7173 get_identifier ("isa"));
7177 add_class_reference (super_name
);
7178 super_class
= (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
7179 ? objc_get_class_decl
: objc_get_meta_class_decl
);
7180 assemble_external (super_class
);
7182 = build_function_call
7186 my_build_string (IDENTIFIER_LENGTH (super_name
) + 1,
7187 IDENTIFIER_POINTER (super_name
))));
7190 TREE_TYPE (super_class
) = TREE_TYPE (ucls_super_ref
);
7191 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, super_class
);
7194 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7196 super_expr
= build_unary_op (ADDR_EXPR
, UOBJC_SUPER_decl
, 0);
7197 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7199 return build_compound_expr (super_expr_list
);
7203 error ("[super ...] must appear in a method context");
7204 return error_mark_node
;
7209 encode_method_def (func_decl
)
7214 HOST_WIDE_INT max_parm_end
= 0;
7219 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
7220 obstack_object_size (&util_obstack
),
7221 OBJC_ENCODE_INLINE_DEFS
);
7224 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7225 parms
= TREE_CHAIN (parms
))
7227 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
7228 + int_size_in_bytes (TREE_TYPE (parms
)));
7230 if (! offset_is_register
&& parm_end
> max_parm_end
)
7231 max_parm_end
= parm_end
;
7234 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
7236 sprintf (buffer
, "%d", stack_size
);
7237 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7239 /* Argument types. */
7240 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7241 parms
= TREE_CHAIN (parms
))
7244 encode_type (TREE_TYPE (parms
),
7245 obstack_object_size (&util_obstack
),
7246 OBJC_ENCODE_INLINE_DEFS
);
7248 /* Compute offset. */
7249 sprintf (buffer
, "%d", forwarding_offset (parms
));
7251 /* Indicate register. */
7252 if (offset_is_register
)
7253 obstack_1grow (&util_obstack
, '+');
7255 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7258 /* Null terminate string. */
7259 obstack_1grow (&util_obstack
, 0);
7260 result
= get_identifier (obstack_finish (&util_obstack
));
7261 obstack_free (&util_obstack
, util_firstobj
);
7266 objc_expand_function_end ()
7268 METHOD_ENCODING (objc_method_context
) = encode_method_def (current_function_decl
);
7272 finish_method_def ()
7274 lang_expand_function_end
= objc_expand_function_end
;
7275 finish_function (0);
7276 lang_expand_function_end
= NULL
;
7278 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7279 since the optimizer may find "may be used before set" errors. */
7280 objc_method_context
= NULL_TREE
;
7285 lang_report_error_function (decl
)
7288 if (objc_method_context
)
7290 fprintf (stderr
, "In method `%s'\n",
7291 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context
)));
7301 is_complex_decl (type
)
7304 return (TREE_CODE (type
) == ARRAY_TYPE
7305 || TREE_CODE (type
) == FUNCTION_TYPE
7306 || (TREE_CODE (type
) == POINTER_TYPE
&& ! IS_ID (type
)));
7310 /* Code to convert a decl node into text for a declaration in C. */
7312 static char tmpbuf
[256];
7315 adorn_decl (decl
, str
)
7319 enum tree_code code
= TREE_CODE (decl
);
7321 if (code
== ARRAY_REF
)
7323 tree an_int_cst
= TREE_OPERAND (decl
, 1);
7325 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_CST
)
7326 sprintf (str
+ strlen (str
), "[%ld]",
7327 (long) TREE_INT_CST_LOW (an_int_cst
));
7332 else if (code
== ARRAY_TYPE
)
7334 tree an_int_cst
= TYPE_SIZE (decl
);
7335 tree array_of
= TREE_TYPE (decl
);
7337 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_TYPE
)
7338 sprintf (str
+ strlen (str
), "[%ld]",
7339 (long) (TREE_INT_CST_LOW (an_int_cst
)
7340 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
7345 else if (code
== CALL_EXPR
)
7347 tree chain
= TREE_PURPOSE (TREE_OPERAND (decl
, 1));
7352 gen_declaration_1 (chain
, str
);
7353 chain
= TREE_CHAIN (chain
);
7360 else if (code
== FUNCTION_TYPE
)
7362 tree chain
= TYPE_ARG_TYPES (decl
);
7365 while (chain
&& TREE_VALUE (chain
) != void_type_node
)
7367 gen_declaration_1 (TREE_VALUE (chain
), str
);
7368 chain
= TREE_CHAIN (chain
);
7369 if (chain
&& TREE_VALUE (chain
) != void_type_node
)
7375 else if (code
== INDIRECT_REF
)
7377 strcpy (tmpbuf
, "*");
7378 if (TREE_TYPE (decl
) && TREE_CODE (TREE_TYPE (decl
)) == TREE_LIST
)
7382 for (chain
= nreverse (copy_list (TREE_TYPE (decl
)));
7384 chain
= TREE_CHAIN (chain
))
7386 if (TREE_CODE (TREE_VALUE (chain
)) == IDENTIFIER_NODE
)
7388 strcat (tmpbuf
, " ");
7389 strcat (tmpbuf
, IDENTIFIER_POINTER (TREE_VALUE (chain
)));
7393 strcat (tmpbuf
, " ");
7395 strcat (tmpbuf
, str
);
7396 strcpy (str
, tmpbuf
);
7399 else if (code
== POINTER_TYPE
)
7401 strcpy (tmpbuf
, "*");
7402 if (TREE_READONLY (decl
) || TYPE_VOLATILE (decl
))
7404 if (TREE_READONLY (decl
))
7405 strcat (tmpbuf
, " const");
7406 if (TYPE_VOLATILE (decl
))
7407 strcat (tmpbuf
, " volatile");
7409 strcat (tmpbuf
, " ");
7411 strcat (tmpbuf
, str
);
7412 strcpy (str
, tmpbuf
);
7417 gen_declarator (decl
, buf
, name
)
7424 enum tree_code code
= TREE_CODE (decl
);
7434 op
= TREE_OPERAND (decl
, 0);
7436 /* We have a pointer to a function or array...(*)(), (*)[] */
7437 if ((code
== ARRAY_REF
|| code
== CALL_EXPR
)
7438 && op
&& TREE_CODE (op
) == INDIRECT_REF
)
7441 str
= gen_declarator (op
, buf
, name
);
7445 strcpy (tmpbuf
, "(");
7446 strcat (tmpbuf
, str
);
7447 strcat (tmpbuf
, ")");
7448 strcpy (str
, tmpbuf
);
7451 adorn_decl (decl
, str
);
7460 /* This clause is done iteratively rather than recursively. */
7463 op
= (is_complex_decl (TREE_TYPE (decl
))
7464 ? TREE_TYPE (decl
) : NULL_TREE
);
7466 adorn_decl (decl
, str
);
7468 /* We have a pointer to a function or array...(*)(), (*)[] */
7469 if (code
== POINTER_TYPE
7470 && op
&& (TREE_CODE (op
) == FUNCTION_TYPE
7471 || TREE_CODE (op
) == ARRAY_TYPE
))
7473 strcpy (tmpbuf
, "(");
7474 strcat (tmpbuf
, str
);
7475 strcat (tmpbuf
, ")");
7476 strcpy (str
, tmpbuf
);
7479 decl
= (is_complex_decl (TREE_TYPE (decl
))
7480 ? TREE_TYPE (decl
) : NULL_TREE
);
7483 while (decl
&& (code
= TREE_CODE (decl
)))
7488 case IDENTIFIER_NODE
:
7489 /* Will only happen if we are processing a "raw" expr-decl. */
7490 strcpy (buf
, IDENTIFIER_POINTER (decl
));
7501 /* We have an abstract declarator or a _DECL node. */
7509 gen_declspecs (declspecs
, buf
, raw
)
7518 for (chain
= nreverse (copy_list (declspecs
));
7519 chain
; chain
= TREE_CHAIN (chain
))
7521 tree aspec
= TREE_VALUE (chain
);
7523 if (TREE_CODE (aspec
) == IDENTIFIER_NODE
)
7524 strcat (buf
, IDENTIFIER_POINTER (aspec
));
7525 else if (TREE_CODE (aspec
) == RECORD_TYPE
)
7527 if (TYPE_NAME (aspec
))
7529 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7531 if (! TREE_STATIC_TEMPLATE (aspec
))
7532 strcat (buf
, "struct ");
7533 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7538 tree chain
= protocol_list
;
7545 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7546 chain
= TREE_CHAIN (chain
);
7555 strcat (buf
, "untagged struct");
7558 else if (TREE_CODE (aspec
) == UNION_TYPE
)
7560 if (TYPE_NAME (aspec
))
7562 if (! TREE_STATIC_TEMPLATE (aspec
))
7563 strcat (buf
, "union ");
7564 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7567 strcat (buf
, "untagged union");
7570 else if (TREE_CODE (aspec
) == ENUMERAL_TYPE
)
7572 if (TYPE_NAME (aspec
))
7574 if (! TREE_STATIC_TEMPLATE (aspec
))
7575 strcat (buf
, "enum ");
7576 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7579 strcat (buf
, "untagged enum");
7582 else if (TREE_CODE (aspec
) == TYPE_DECL
&& DECL_NAME (aspec
))
7583 strcat (buf
, IDENTIFIER_POINTER (DECL_NAME (aspec
)));
7585 else if (IS_ID (aspec
))
7587 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7592 tree chain
= protocol_list
;
7599 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7600 chain
= TREE_CHAIN (chain
);
7607 if (TREE_CHAIN (chain
))
7613 /* Type qualifiers. */
7614 if (TREE_READONLY (declspecs
))
7615 strcat (buf
, "const ");
7616 if (TYPE_VOLATILE (declspecs
))
7617 strcat (buf
, "volatile ");
7619 switch (TREE_CODE (declspecs
))
7621 /* Type specifiers. */
7624 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7626 /* Signed integer types. */
7628 if (declspecs
== short_integer_type_node
)
7629 strcat (buf
, "short int ");
7630 else if (declspecs
== integer_type_node
)
7631 strcat (buf
, "int ");
7632 else if (declspecs
== long_integer_type_node
)
7633 strcat (buf
, "long int ");
7634 else if (declspecs
== long_long_integer_type_node
)
7635 strcat (buf
, "long long int ");
7636 else if (declspecs
== signed_char_type_node
7637 || declspecs
== char_type_node
)
7638 strcat (buf
, "char ");
7640 /* Unsigned integer types. */
7642 else if (declspecs
== short_unsigned_type_node
)
7643 strcat (buf
, "unsigned short ");
7644 else if (declspecs
== unsigned_type_node
)
7645 strcat (buf
, "unsigned int ");
7646 else if (declspecs
== long_unsigned_type_node
)
7647 strcat (buf
, "unsigned long ");
7648 else if (declspecs
== long_long_unsigned_type_node
)
7649 strcat (buf
, "unsigned long long ");
7650 else if (declspecs
== unsigned_char_type_node
)
7651 strcat (buf
, "unsigned char ");
7655 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7657 if (declspecs
== float_type_node
)
7658 strcat (buf
, "float ");
7659 else if (declspecs
== double_type_node
)
7660 strcat (buf
, "double ");
7661 else if (declspecs
== long_double_type_node
)
7662 strcat (buf
, "long double ");
7666 if (TYPE_NAME (declspecs
)
7667 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7669 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7671 if (! TREE_STATIC_TEMPLATE (declspecs
))
7672 strcat (buf
, "struct ");
7673 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7677 tree chain
= protocol_list
;
7684 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7685 chain
= TREE_CHAIN (chain
);
7694 strcat (buf
, "untagged struct");
7700 if (TYPE_NAME (declspecs
)
7701 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7703 strcat (buf
, "union ");
7704 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7709 strcat (buf
, "untagged union ");
7713 if (TYPE_NAME (declspecs
)
7714 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7716 strcat (buf
, "enum ");
7717 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7722 strcat (buf
, "untagged enum ");
7726 strcat (buf
, "void ");
7731 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7736 tree chain
= protocol_list
;
7743 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7744 chain
= TREE_CHAIN (chain
);
7760 /* Given a tree node, produce a printable description of it in the given
7761 buffer, overwriting the buffer. */
7764 gen_declaration (atype_or_adecl
, buf
)
7765 tree atype_or_adecl
;
7769 gen_declaration_1 (atype_or_adecl
, buf
);
7773 /* Given a tree node, append a printable description to the end of the
7777 gen_declaration_1 (atype_or_adecl
, buf
)
7778 tree atype_or_adecl
;
7783 if (TREE_CODE (atype_or_adecl
) == TREE_LIST
)
7785 tree declspecs
; /* "identifier_node", "record_type" */
7786 tree declarator
; /* "array_ref", "indirect_ref", "call_expr"... */
7788 /* We have a "raw", abstract declarator (typename). */
7789 declarator
= TREE_VALUE (atype_or_adecl
);
7790 declspecs
= TREE_PURPOSE (atype_or_adecl
);
7792 gen_declspecs (declspecs
, buf
, 1);
7796 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7803 tree declspecs
; /* "integer_type", "real_type", "record_type"... */
7804 tree declarator
; /* "array_type", "function_type", "pointer_type". */
7806 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7807 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7808 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7809 atype
= TREE_TYPE (atype_or_adecl
);
7811 /* Assume we have a *_type node. */
7812 atype
= atype_or_adecl
;
7814 if (is_complex_decl (atype
))
7818 /* Get the declaration specifier; it is at the end of the list. */
7819 declarator
= chain
= atype
;
7821 chain
= TREE_TYPE (chain
); /* not TREE_CHAIN (chain); */
7822 while (is_complex_decl (chain
));
7829 declarator
= NULL_TREE
;
7832 gen_declspecs (declspecs
, buf
, 0);
7834 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7835 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7836 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7838 const char *const decl_name
=
7839 (DECL_NAME (atype_or_adecl
)
7840 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl
)) : "");
7845 strcat (buf
, gen_declarator (declarator
, declbuf
, decl_name
));
7848 else if (decl_name
[0])
7851 strcat (buf
, decl_name
);
7854 else if (declarator
)
7857 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7862 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7864 /* Given a method tree, put a printable description into the given
7865 buffer (overwriting) and return a pointer to the buffer. */
7868 gen_method_decl (method
, buf
)
7875 if (RAW_TYPESPEC (method
) != objc_object_reference
)
7878 gen_declaration_1 (TREE_TYPE (method
), buf
);
7882 chain
= METHOD_SEL_ARGS (method
);
7885 /* We have a chain of keyword_decls. */
7888 if (KEYWORD_KEY_NAME (chain
))
7889 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain
)));
7892 if (RAW_TYPESPEC (chain
) != objc_object_reference
)
7895 gen_declaration_1 (TREE_TYPE (chain
), buf
);
7899 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain
)));
7900 if ((chain
= TREE_CHAIN (chain
)))
7905 if (METHOD_ADD_ARGS (method
) == objc_ellipsis_node
)
7906 strcat (buf
, ", ...");
7907 else if (METHOD_ADD_ARGS (method
))
7909 /* We have a tree list node as generate by get_parm_info. */
7910 chain
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
7912 /* Know we have a chain of parm_decls. */
7916 gen_declaration_1 (chain
, buf
);
7917 chain
= TREE_CHAIN (chain
);
7923 /* We have a unary selector. */
7924 strcat (buf
, IDENTIFIER_POINTER (METHOD_SEL_NAME (method
)));
7932 dump_interface (fp
, chain
)
7936 char *buf
= (char *)xmalloc (256);
7937 const char *my_name
= IDENTIFIER_POINTER (CLASS_NAME (chain
));
7938 tree ivar_decls
= CLASS_RAW_IVARS (chain
);
7939 tree nst_methods
= CLASS_NST_METHODS (chain
);
7940 tree cls_methods
= CLASS_CLS_METHODS (chain
);
7942 fprintf (fp
, "\n@interface %s", my_name
);
7944 if (CLASS_SUPER_NAME (chain
))
7946 const char *super_name
= IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain
));
7947 fprintf (fp
, " : %s\n", super_name
);
7954 fprintf (fp
, "{\n");
7957 fprintf (fp
, "\t%s;\n", gen_declaration (ivar_decls
, buf
));
7958 ivar_decls
= TREE_CHAIN (ivar_decls
);
7961 fprintf (fp
, "}\n");
7966 fprintf (fp
, "- %s;\n", gen_method_decl (nst_methods
, buf
));
7967 nst_methods
= TREE_CHAIN (nst_methods
);
7972 fprintf (fp
, "+ %s;\n", gen_method_decl (cls_methods
, buf
));
7973 cls_methods
= TREE_CHAIN (cls_methods
);
7975 fprintf (fp
, "\n@end");
7978 /* Demangle function for Objective-C */
7980 objc_demangle (mangled
)
7981 const char *mangled
;
7983 char *demangled
, *cp
;
7985 if (mangled
[0] == '_' &&
7986 (mangled
[1] == 'i' || mangled
[1] == 'c') &&
7989 cp
= demangled
= xmalloc(strlen(mangled
) + 2);
7990 if (mangled
[1] == 'i')
7991 *cp
++ = '-'; /* for instance method */
7993 *cp
++ = '+'; /* for class method */
7994 *cp
++ = '['; /* opening left brace */
7995 strcpy(cp
, mangled
+3); /* tack on the rest of the mangled name */
7996 while (*cp
&& *cp
== '_')
7997 cp
++; /* skip any initial underbars in class name */
7998 cp
= strchr(cp
, '_'); /* find first non-initial underbar */
8001 free(demangled
); /* not mangled name */
8004 if (cp
[1] == '_') /* easy case: no category name */
8006 *cp
++ = ' '; /* replace two '_' with one ' ' */
8007 strcpy(cp
, mangled
+ (cp
- demangled
) + 2);
8011 *cp
++ = '('; /* less easy case: category name */
8012 cp
= strchr(cp
, '_');
8015 free(demangled
); /* not mangled name */
8019 *cp
++ = ' '; /* overwriting 1st char of method name... */
8020 strcpy(cp
, mangled
+ (cp
- demangled
)); /* get it back */
8022 while (*cp
&& *cp
== '_')
8023 cp
++; /* skip any initial underbars in method name */
8026 *cp
= ':'; /* replace remaining '_' with ':' */
8027 *cp
++ = ']'; /* closing right brace */
8028 *cp
++ = 0; /* string terminator */
8032 return mangled
; /* not an objc mangled name */
8036 objc_printable_name (decl
, kind
)
8038 int kind ATTRIBUTE_UNUSED
;
8040 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl
)));
8046 /* Add the special tree codes of Objective C to the tables. */
8048 gcc_obstack_init (&util_obstack
);
8049 util_firstobj
= (char *) obstack_finish (&util_obstack
);
8051 memcpy (tree_code_type
+ (int) LAST_BASE_TREE_CODE
,
8052 objc_tree_code_type
,
8053 (int) LAST_OBJC_TREE_CODE
- (int) LAST_BASE_TREE_CODE
);
8054 memcpy (tree_code_length
+ (int) LAST_BASE_TREE_CODE
,
8055 objc_tree_code_length
,
8056 (((int) LAST_OBJC_TREE_CODE
- (int) LAST_BASE_TREE_CODE
) * sizeof (int)));
8057 memcpy (tree_code_name
+ (int) LAST_BASE_TREE_CODE
,
8058 objc_tree_code_name
,
8059 (((int) LAST_OBJC_TREE_CODE
- (int) LAST_BASE_TREE_CODE
) * sizeof (char *)));
8061 errbuf
= (char *)xmalloc (BUFSIZE
);
8063 synth_module_prologue ();
8065 /* Change the default error function */
8066 save_lang_status
= &push_c_function_context
;
8067 restore_lang_status
= &pop_c_function_context
;
8068 mark_lang_status
= &mark_c_function_context
;
8069 decl_printable_name
= objc_printable_name
;
8070 lang_expand_expr
= c_expand_expr
;
8071 lang_expand_decl_stmt
= c_expand_decl_stmt
;
8077 struct imp_entry
*impent
;
8079 /* The internally generated initializers appear to have missing braces.
8080 Don't warn about this. */
8081 int save_warn_missing_braces
= warn_missing_braces
;
8082 warn_missing_braces
= 0;
8084 /* A missing @end may not be detected by the parser. */
8085 if (objc_implementation_context
)
8087 warning ("`@end' missing in implementation context");
8088 finish_class (objc_implementation_context
);
8089 objc_ivar_chain
= NULL_TREE
;
8090 objc_implementation_context
= NULL_TREE
;
8093 generate_forward_declaration_to_string_table ();
8095 #ifdef OBJC_PROLOGUE
8099 /* Process the static instances here because initialization of objc_symtab
8101 if (objc_static_instances
)
8102 generate_static_references ();
8104 if (imp_list
|| class_names_chain
8105 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8106 generate_objc_symtab_decl ();
8108 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8110 objc_implementation_context
= impent
->imp_context
;
8111 implementation_template
= impent
->imp_template
;
8113 UOBJC_CLASS_decl
= impent
->class_decl
;
8114 UOBJC_METACLASS_decl
= impent
->meta_decl
;
8116 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
8118 /* all of the following reference the string pool... */
8119 generate_ivar_lists ();
8120 generate_dispatch_tables ();
8121 generate_shared_structures ();
8125 generate_dispatch_tables ();
8126 generate_category (objc_implementation_context
);
8130 /* If we are using an array of selectors, we must always
8131 finish up the array decl even if no selectors were used. */
8132 if (! flag_next_runtime
|| sel_ref_chain
)
8133 build_selector_translation_table ();
8136 generate_protocols ();
8138 if (objc_implementation_context
|| class_names_chain
|| objc_static_instances
8139 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8141 /* Arrange for Objc data structures to be initialized at run time. */
8142 rtx init_sym
= build_module_descriptor ();
8143 if (init_sym
&& targetm
.have_ctors_dtors
)
8144 (* targetm
.asm_out
.constructor
) (init_sym
, DEFAULT_INIT_PRIORITY
);
8147 /* Dump the class references. This forces the appropriate classes
8148 to be linked into the executable image, preserving unix archive
8149 semantics. This can be removed when we move to a more dynamically
8150 linked environment. */
8152 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
8154 handle_class_ref (chain
);
8155 if (TREE_PURPOSE (chain
))
8156 generate_classref_translation_entry (chain
);
8159 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8160 handle_impent (impent
);
8162 /* Dump the string table last. */
8164 generate_strings ();
8166 if (flag_gen_declaration
)
8168 add_class (objc_implementation_context
);
8169 dump_interface (gen_declaration_file
, objc_implementation_context
);
8177 /* Run through the selector hash tables and print a warning for any
8178 selector which has multiple methods. */
8180 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8181 for (hsh
= cls_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8184 tree meth
= hsh
->key
;
8185 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8189 warning ("potential selector conflict for method `%s'",
8190 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8191 warn_with_method ("found", type
, meth
);
8192 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8193 warn_with_method ("found", type
, loop
->value
);
8196 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8197 for (hsh
= nst_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
);
8213 warn_missing_braces
= save_warn_missing_braces
;
8216 /* Subroutines of finish_objc. */
8219 generate_classref_translation_entry (chain
)
8222 tree expr
, name
, decl_specs
, decl
, sc_spec
;
8225 type
= TREE_TYPE (TREE_PURPOSE (chain
));
8227 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
8228 expr
= build_c_cast (type
, expr
); /* cast! */
8230 name
= DECL_NAME (TREE_PURPOSE (chain
));
8232 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
8234 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8235 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
8237 /* The decl that is returned from start_decl is the one that we
8238 forward declared in build_class_reference. */
8239 decl
= start_decl (name
, decl_specs
, 1, NULL_TREE
);
8240 DECL_CONTEXT (decl
) = NULL_TREE
;
8241 finish_decl (decl
, expr
, NULL_TREE
);
8246 handle_class_ref (chain
)
8249 const char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
8250 char *string
= (char *) alloca (strlen (name
) + 30);
8254 sprintf (string
, "%sobjc_class_name_%s",
8255 (flag_next_runtime
? "." : "__"), name
);
8257 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8258 if (flag_next_runtime
)
8260 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file
, string
);
8265 /* Make a decl for this name, so we can use its address in a tree. */
8266 decl
= build_decl (VAR_DECL
, get_identifier (string
), char_type_node
);
8267 DECL_EXTERNAL (decl
) = 1;
8268 TREE_PUBLIC (decl
) = 1;
8271 rest_of_decl_compilation (decl
, 0, 0, 0);
8273 /* Make a decl for the address. */
8274 sprintf (string
, "%sobjc_class_ref_%s",
8275 (flag_next_runtime
? "." : "__"), name
);
8276 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
8277 decl
= build_decl (VAR_DECL
, get_identifier (string
), string_type_node
);
8278 DECL_INITIAL (decl
) = exp
;
8279 TREE_STATIC (decl
) = 1;
8282 rest_of_decl_compilation (decl
, 0, 0, 0);
8286 handle_impent (impent
)
8287 struct imp_entry
*impent
;
8291 objc_implementation_context
= impent
->imp_context
;
8292 implementation_template
= impent
->imp_template
;
8294 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
8296 const char *const class_name
=
8297 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8299 string
= (char *) alloca (strlen (class_name
) + 30);
8301 sprintf (string
, "*%sobjc_class_name_%s",
8302 (flag_next_runtime
? "." : "__"), class_name
);
8304 else if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
8306 const char *const class_name
=
8307 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8308 const char *const class_super_name
=
8309 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
8311 string
= (char *) alloca (strlen (class_name
)
8312 + strlen (class_super_name
) + 30);
8314 /* Do the same for categories. Even though no references to
8315 these symbols are generated automatically by the compiler, it
8316 gives you a handle to pull them into an archive by hand. */
8317 sprintf (string
, "*%sobjc_category_name_%s_%s",
8318 (flag_next_runtime
? "." : "__"), class_name
, class_super_name
);
8323 #ifdef ASM_DECLARE_CLASS_REFERENCE
8324 if (flag_next_runtime
)
8326 ASM_DECLARE_CLASS_REFERENCE (asm_out_file
, string
);
8331 /* (Should this be a routine in varasm.c?) */
8332 readonly_data_section ();
8333 assemble_global (string
);
8334 assemble_align (UNITS_PER_WORD
);
8335 assemble_label (string
);
8336 assemble_zeros (UNITS_PER_WORD
);
8340 print_lang_statistics ()
8345 ggc_mark_imp_list (arg
)
8348 struct imp_entry
*impent
;
8350 for (impent
= *(struct imp_entry
**)arg
; impent
; impent
= impent
->next
)
8352 ggc_mark_tree (impent
->imp_context
);
8353 ggc_mark_tree (impent
->imp_template
);
8354 ggc_mark_tree (impent
->class_decl
);
8355 ggc_mark_tree (impent
->meta_decl
);
8360 ggc_mark_hash_table (arg
)
8363 hash
*hash_table
= *(hash
**)arg
;
8368 if (hash_table
== NULL
)
8370 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
8371 for (hst
= hash_table
[i
]; hst
; hst
= hst
->next
)
8373 ggc_mark_tree (hst
->key
);
8374 for (list
= hst
->list
; list
; list
= list
->next
)
8375 ggc_mark_tree (list
->value
);
8379 /* Add GC roots for variables local to this file. */
8381 objc_act_parse_init ()
8383 ggc_add_tree_root (objc_global_trees
, OCTI_MAX
);
8384 ggc_add_root (&imp_list
, 1, sizeof imp_list
, ggc_mark_imp_list
);
8385 ggc_add_root (&nst_method_hash_list
, 1, sizeof nst_method_hash_list
, ggc_mark_hash_table
);
8386 ggc_add_root (&cls_method_hash_list
, 1, sizeof cls_method_hash_list
, ggc_mark_hash_table
);
8389 /* Look up ID as an instance variable. */
8391 lookup_objc_ivar (id
)
8396 if (objc_receiver_context
&& !strcmp (IDENTIFIER_POINTER (id
), "super"))
8397 /* we have a message to super */
8398 return get_super_receiver ();
8399 else if (objc_method_context
&& (decl
= is_ivar (objc_ivar_chain
, id
)))
8401 if (is_private (decl
))
8402 return error_mark_node
;
8404 return build_ivar_reference (id
);