1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998,
3 1999, 2000 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':
40 - OBJC_INT_SELECTORS */
57 extern cpp_reader parse_in
;
58 extern cpp_options parse_options
;
61 /* This is the default way of generating a method name. */
62 /* I am not sure it is really correct.
63 Perhaps there's a danger that it will make name conflicts
64 if method names contain underscores. -- rms. */
65 #ifndef OBJC_GEN_METHOD_LABEL
66 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
69 sprintf ((BUF), "_%s_%s_%s_%s", \
70 ((IS_INST) ? "i" : "c"), \
72 ((CAT_NAME)? (CAT_NAME) : ""), \
74 for (temp = (BUF); *temp; temp++) \
75 if (*temp == ':') *temp = '_'; \
79 /* These need specifying. */
80 #ifndef OBJC_FORWARDING_STACK_OFFSET
81 #define OBJC_FORWARDING_STACK_OFFSET 0
84 #ifndef OBJC_FORWARDING_MIN_OFFSET
85 #define OBJC_FORWARDING_MIN_OFFSET 0
88 /* Define the special tree codes that we use. */
90 /* Table indexed by tree code giving a string containing a character
91 classifying the tree code. Possibilities are
92 t, d, s, c, r, <, 1 and 2. See objc-tree.def for details. */
94 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
96 static const char objc_tree_code_type
[] = {
98 #include "objc-tree.def"
102 /* Table indexed by tree code giving number of expression
103 operands beyond the fixed part of the node structure.
104 Not used for types or decls. */
106 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
108 static const int objc_tree_code_length
[] = {
110 #include "objc-tree.def"
114 /* Names of tree components.
115 Used for printing out the tree and error messages. */
116 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
118 static const char * const objc_tree_code_name
[] = {
120 #include "objc-tree.def"
124 /* Set up for use of obstacks. */
128 #define obstack_chunk_alloc xmalloc
129 #define obstack_chunk_free free
131 /* This obstack is used to accumulate the encoding of a data type. */
132 static struct obstack util_obstack
;
133 /* This points to the beginning of obstack contents,
134 so we can free the whole contents. */
137 /* List of classes with list of their static instances. */
138 static tree objc_static_instances
= NULL_TREE
;
140 /* The declaration of the array administrating the static instances. */
141 static tree static_instances_decl
= NULL_TREE
;
143 /* for encode_method_def */
147 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
148 #define PROTOCOL_VERSION 2
150 #define OBJC_ENCODE_INLINE_DEFS 0
151 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
153 /*** Private Interface (procedures) ***/
155 /* Used by compile_file. */
157 static void init_objc
PARAMS ((void));
158 static void finish_objc
PARAMS ((void));
160 /* Code generation. */
162 static void synth_module_prologue
PARAMS ((void));
163 static tree build_constructor
PARAMS ((tree
, tree
));
164 static const char *build_module_descriptor
PARAMS ((void));
165 static tree init_module_descriptor
PARAMS ((tree
));
166 static tree build_objc_method_call
PARAMS ((int, tree
, tree
,
168 static void generate_strings
PARAMS ((void));
169 static tree get_proto_encoding
PARAMS ((tree
));
170 static void build_selector_translation_table
PARAMS ((void));
171 static tree build_ivar_chain
PARAMS ((tree
, int));
173 static tree objc_add_static_instance
PARAMS ((tree
, tree
));
175 static tree build_ivar_template
PARAMS ((void));
176 static tree build_method_template
PARAMS ((void));
177 static tree build_private_template
PARAMS ((tree
));
178 static void build_class_template
PARAMS ((void));
179 static void build_selector_template
PARAMS ((void));
180 static void build_category_template
PARAMS ((void));
181 static tree build_super_template
PARAMS ((void));
182 static tree build_category_initializer
PARAMS ((tree
, tree
, tree
,
184 static tree build_protocol_initializer
PARAMS ((tree
, tree
, tree
,
187 static void synth_forward_declarations
PARAMS ((void));
188 static void generate_ivar_lists
PARAMS ((void));
189 static void generate_dispatch_tables
PARAMS ((void));
190 static void generate_shared_structures
PARAMS ((void));
191 static tree generate_protocol_list
PARAMS ((tree
));
192 static void generate_forward_declaration_to_string_table
PARAMS ((void));
193 static void build_protocol_reference
PARAMS ((tree
));
196 static tree init_selector
PARAMS ((int));
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));
209 /* Misc. bookkeeping */
211 typedef struct hashed_entry
*hash
;
212 typedef struct hashed_attribute
*attr
;
214 struct hashed_attribute
226 static void hash_init
PARAMS ((void));
227 static void hash_enter
PARAMS ((hash
*, tree
));
228 static hash hash_lookup
PARAMS ((hash
*, tree
));
229 static void hash_add_attr
PARAMS ((hash
, tree
));
230 static tree lookup_method
PARAMS ((tree
, tree
));
231 static tree lookup_instance_method_static
PARAMS ((tree
, tree
));
232 static tree lookup_class_method_static
PARAMS ((tree
, tree
));
233 static tree add_class
PARAMS ((tree
));
234 static void add_category
PARAMS ((tree
, tree
));
238 class_names
, /* class, category, protocol, module names */
239 meth_var_names
, /* method and variable names */
240 meth_var_types
/* method and variable type descriptors */
243 static tree add_objc_string
PARAMS ((tree
,
244 enum string_section
));
245 static tree get_objc_string_decl
PARAMS ((tree
,
246 enum string_section
));
247 static tree build_objc_string_decl
PARAMS ((enum string_section
));
248 static tree build_selector_reference_decl
PARAMS ((void));
250 /* Protocol additions. */
252 static tree add_protocol
PARAMS ((tree
));
253 static tree lookup_protocol
PARAMS ((tree
));
254 static tree lookup_and_install_protocols
PARAMS ((tree
));
258 static void encode_type_qualifiers
PARAMS ((tree
));
259 static void encode_pointer
PARAMS ((tree
, int, int));
260 static void encode_array
PARAMS ((tree
, int, int));
261 static void encode_aggregate
PARAMS ((tree
, int, int));
262 static void encode_bitfield
PARAMS ((int));
263 static void encode_type
PARAMS ((tree
, int, int));
264 static void encode_field_decl
PARAMS ((tree
, int, int));
266 static void really_start_method
PARAMS ((tree
, tree
));
267 static int comp_method_with_proto
PARAMS ((tree
, tree
));
268 static int comp_proto_with_proto
PARAMS ((tree
, tree
));
269 static tree get_arg_type_list
PARAMS ((tree
, int, int));
270 static tree expr_last
PARAMS ((tree
));
272 /* Utilities for debugging and error diagnostics. */
274 static void warn_with_method
PARAMS ((const char *, int, tree
));
275 static void error_with_ivar
PARAMS ((const char *, tree
, tree
));
276 static char *gen_method_decl
PARAMS ((tree
, char *));
277 static char *gen_declaration
PARAMS ((tree
, char *));
278 static char *gen_declarator
PARAMS ((tree
, char *,
280 static int is_complex_decl
PARAMS ((tree
));
281 static void adorn_decl
PARAMS ((tree
, char *));
282 static void dump_interface
PARAMS ((FILE *, tree
));
284 /* Everything else. */
286 static void objc_fatal
PARAMS ((void))
288 static tree define_decl
PARAMS ((tree
, tree
));
289 static tree lookup_method_in_protocol_list
PARAMS ((tree
, tree
, int));
290 static tree lookup_protocol_in_reflist
PARAMS ((tree
, tree
));
291 static tree create_builtin_decl
PARAMS ((enum tree_code
,
292 tree
, const char *));
293 static tree my_build_string
PARAMS ((int, const char *));
294 static void build_objc_symtab_template
PARAMS ((void));
295 static tree init_def_list
PARAMS ((tree
));
296 static tree init_objc_symtab
PARAMS ((tree
));
297 static void forward_declare_categories
PARAMS ((void));
298 static void generate_objc_symtab_decl
PARAMS ((void));
299 static tree build_selector
PARAMS ((tree
));
301 static tree build_msg_pool_reference
PARAMS ((int));
303 static tree build_typed_selector_reference
PARAMS ((tree
, tree
));
304 static tree build_selector_reference
PARAMS ((tree
));
305 static tree build_class_reference_decl
PARAMS ((void));
306 static void add_class_reference
PARAMS ((tree
));
307 static tree objc_copy_list
PARAMS ((tree
, tree
*));
308 static tree build_protocol_template
PARAMS ((void));
309 static tree build_descriptor_table_initializer
PARAMS ((tree
, tree
));
310 static tree build_method_prototype_list_template
PARAMS ((tree
, int));
311 static tree build_method_prototype_template
PARAMS ((void));
312 static int forwarding_offset
PARAMS ((tree
));
313 static tree encode_method_prototype
PARAMS ((tree
, tree
));
314 static tree generate_descriptor_table
PARAMS ((tree
, const char *,
316 static void generate_method_descriptors
PARAMS ((tree
));
317 static tree build_tmp_function_decl
PARAMS ((void));
318 static void hack_method_prototype
PARAMS ((tree
, tree
));
319 static void generate_protocol_references
PARAMS ((tree
));
320 static void generate_protocols
PARAMS ((void));
321 static void check_ivars
PARAMS ((tree
, tree
));
322 static tree build_ivar_list_template
PARAMS ((tree
, int));
323 static tree build_method_list_template
PARAMS ((tree
, int));
324 static tree build_ivar_list_initializer
PARAMS ((tree
, tree
));
325 static tree generate_ivars_list
PARAMS ((tree
, const char *,
327 static tree build_dispatch_table_initializer
PARAMS ((tree
, tree
));
328 static tree generate_dispatch_table
PARAMS ((tree
, const char *,
330 static tree build_shared_structure_initializer
PARAMS ((tree
, tree
, tree
, tree
,
331 tree
, int, tree
, tree
,
333 static void generate_category
PARAMS ((tree
));
334 static int is_objc_type_qualifier
PARAMS ((tree
));
335 static tree adjust_type_for_id_default
PARAMS ((tree
));
336 static tree check_duplicates
PARAMS ((hash
));
337 static tree receiver_is_class_object
PARAMS ((tree
));
338 static int check_methods
PARAMS ((tree
, tree
, int));
339 static int conforms_to_protocol
PARAMS ((tree
, tree
));
340 static void check_protocols
PARAMS ((tree
, const char *,
342 static tree encode_method_def
PARAMS ((tree
));
343 static void gen_declspecs
PARAMS ((tree
, char *, int));
344 static void generate_classref_translation_entry
PARAMS ((tree
));
345 static void handle_class_ref
PARAMS ((tree
));
346 static void generate_struct_by_value_array
PARAMS ((void))
349 /*** Private Interface (data) ***/
351 /* Reserved tag definitions. */
354 #define TAG_OBJECT "objc_object"
355 #define TAG_CLASS "objc_class"
356 #define TAG_SUPER "objc_super"
357 #define TAG_SELECTOR "objc_selector"
359 #define UTAG_CLASS "_objc_class"
360 #define UTAG_IVAR "_objc_ivar"
361 #define UTAG_IVAR_LIST "_objc_ivar_list"
362 #define UTAG_METHOD "_objc_method"
363 #define UTAG_METHOD_LIST "_objc_method_list"
364 #define UTAG_CATEGORY "_objc_category"
365 #define UTAG_MODULE "_objc_module"
366 #define UTAG_STATICS "_objc_statics"
367 #define UTAG_SYMTAB "_objc_symtab"
368 #define UTAG_SUPER "_objc_super"
369 #define UTAG_SELECTOR "_objc_selector"
371 #define UTAG_PROTOCOL "_objc_protocol"
372 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
373 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
374 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
376 #define STRING_OBJECT_CLASS_NAME "NXConstantString"
377 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
379 static const char *TAG_GETCLASS
;
380 static const char *TAG_GETMETACLASS
;
381 static const char *TAG_MSGSEND
;
382 static const char *TAG_MSGSENDSUPER
;
383 static const char *TAG_EXECCLASS
;
385 /* Set by `continue_class' and checked by `is_public'. */
387 #define TREE_STATIC_TEMPLATE(record_type) (TREE_PUBLIC (record_type))
388 #define TYPED_OBJECT(type) \
389 (TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type))
391 /* Some commonly used instances of "identifier_node". */
393 static tree self_id
, ucmd_id
;
394 static tree unused_list
;
396 static tree self_decl
, umsg_decl
, umsg_super_decl
;
397 static tree objc_get_class_decl
, objc_get_meta_class_decl
;
399 static tree super_type
, selector_type
, id_type
, objc_class_type
;
400 static tree instance_type
, protocol_type
;
402 /* Type checking macros. */
404 #define IS_ID(TYPE) \
405 (TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (id_type))
406 #define IS_PROTOCOL_QUALIFIED_ID(TYPE) \
407 (IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE))
408 #define IS_SUPER(TYPE) \
409 (super_type && TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (super_type))
411 static tree class_chain
= NULL_TREE
;
412 static tree alias_chain
= NULL_TREE
;
413 static tree interface_chain
= NULL_TREE
;
414 static tree protocol_chain
= NULL_TREE
;
416 /* Chains to manage selectors that are referenced and defined in the
419 static tree cls_ref_chain
= NULL_TREE
; /* Classes referenced. */
420 static tree sel_ref_chain
= NULL_TREE
; /* Selectors referenced. */
422 /* Chains to manage uniquing of strings. */
424 static tree class_names_chain
= NULL_TREE
;
425 static tree meth_var_names_chain
= NULL_TREE
;
426 static tree meth_var_types_chain
= NULL_TREE
;
428 /* Hash tables to manage the global pool of method prototypes. */
430 static hash
*nst_method_hash_list
= 0;
431 static hash
*cls_method_hash_list
= 0;
433 /* Backend data declarations. */
435 static tree UOBJC_SYMBOLS_decl
;
436 static tree UOBJC_INSTANCE_VARIABLES_decl
, UOBJC_CLASS_VARIABLES_decl
;
437 static tree UOBJC_INSTANCE_METHODS_decl
, UOBJC_CLASS_METHODS_decl
;
438 static tree UOBJC_CLASS_decl
, UOBJC_METACLASS_decl
;
439 static tree UOBJC_SELECTOR_TABLE_decl
;
440 static tree UOBJC_MODULES_decl
;
441 static tree UOBJC_STRINGS_decl
;
443 /* The following are used when compiling a class implementation.
444 implementation_template will normally be an interface, however if
445 none exists this will be equal to implementation_context...it is
446 set in start_class. */
448 static tree implementation_context
= NULL_TREE
;
449 static tree implementation_template
= NULL_TREE
;
453 struct imp_entry
*next
;
456 tree class_decl
; /* _OBJC_CLASS_<my_name>; */
457 tree meta_decl
; /* _OBJC_METACLASS_<my_name>; */
460 static void handle_impent
PARAMS ((struct imp_entry
*));
462 static struct imp_entry
*imp_list
= 0;
463 static int imp_count
= 0; /* `@implementation' */
464 static int cat_count
= 0; /* `@category' */
466 static tree objc_class_template
, objc_category_template
, uprivate_record
;
467 static tree objc_protocol_template
, objc_selector_template
;
468 static tree ucls_super_ref
, uucls_super_ref
;
470 static tree objc_method_template
, objc_ivar_template
;
471 static tree objc_symtab_template
, objc_module_template
;
472 static tree objc_super_template
, objc_object_reference
;
474 static tree objc_object_id
, objc_class_id
, objc_id_id
;
475 static tree constant_string_id
;
476 static tree constant_string_type
;
477 static tree UOBJC_SUPER_decl
;
479 static tree method_context
= NULL_TREE
;
480 static int method_slot
= 0; /* Used by start_method_def, */
484 static char *errbuf
; /* Buffer for error diagnostics */
486 /* Data imported from tree.c. */
488 extern enum debug_info_type write_symbols
;
490 /* Data imported from toplev.c. */
492 extern const char *dump_base_name
;
494 /* Generate code for GNU or NeXT runtime environment. */
496 #ifdef NEXT_OBJC_RUNTIME
497 int flag_next_runtime
= 1;
499 int flag_next_runtime
= 0;
502 int flag_typed_selectors
;
504 /* Open and close the file for outputting class declarations, if requested. */
506 int flag_gen_declaration
= 0;
508 FILE *gen_declaration_file
;
510 /* Warn if multiple methods are seen for the same selector, but with
511 different argument types. */
513 int warn_selector
= 0;
515 /* Warn if methods required by a protocol are not implemented in the
516 class adopting it. When turned off, methods inherited to that
517 class are also considered implemented */
519 int flag_warn_protocol
= 1;
521 /* Tells "encode_pointer/encode_aggregate" whether we are generating
522 type descriptors for instance variables (as opposed to methods).
523 Type descriptors for instance variables contain more information
524 than methods (for static typing and embedded structures). This
525 was added to support features being planned for dbkit2. */
527 static int generating_instance_variables
= 0;
529 /* Tells the compiler that this is a special run. Do not perform
530 any compiling, instead we are to test some platform dependent
531 features and output a C header file with appropriate definitions. */
533 static int print_struct_values
= 0;
535 /* Some platforms pass small structures through registers versus through
536 an invisible pointer. Determine at what size structure is the
537 transition point between the two possibilities. */
540 generate_struct_by_value_array ()
543 tree field_decl
, field_decl_chain
;
545 int aggregate_in_mem
[32];
548 /* Presumbaly no platform passes 32 byte structures in a register. */
549 for (i
= 1; i
< 32; i
++)
553 /* Create an unnamed struct that has `i' character components */
554 type
= start_struct (RECORD_TYPE
, NULL_TREE
);
556 strcpy (buffer
, "c1");
557 field_decl
= create_builtin_decl (FIELD_DECL
,
560 field_decl_chain
= field_decl
;
562 for (j
= 1; j
< i
; j
++)
564 sprintf (buffer
, "c%d", j
+ 1);
565 field_decl
= create_builtin_decl (FIELD_DECL
,
568 chainon (field_decl_chain
, field_decl
);
570 finish_struct (type
, field_decl_chain
, NULL_TREE
);
572 aggregate_in_mem
[i
] = aggregate_value_p (type
);
573 if (!aggregate_in_mem
[i
])
577 /* We found some structures that are returned in registers instead of memory
578 so output the necessary data. */
581 for (i
= 31; i
>= 0; i
--)
582 if (!aggregate_in_mem
[i
])
584 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i
);
586 /* The first member of the structure is always 0 because we don't handle
587 structures with 0 members */
588 printf ("static int struct_forward_array[] = {\n 0");
590 for (j
= 1; j
<= i
; j
++)
591 printf (", %d", aggregate_in_mem
[j
]);
606 cpp_reader_init (&parse_in
);
607 parse_in
.opts
= &parse_options
;
608 cpp_options_init (&parse_options
);
616 /* The beginning of the file is a new line; check for #.
617 With luck, we discover the real source file's name from that
618 and put it in input_filename. */
619 ungetc (check_newline (), finput
);
625 /* The line number can be -1 if we had -g3 and the input file
626 had a directive specifying line 0. But we want predefined
627 functions to have a line number of 0, not -1. */
631 /* If gen_declaration desired, open the output file. */
632 if (flag_gen_declaration
)
634 register char * const dumpname
= concat (dumpname
, ".decl", NULL
);
635 gen_declaration_file
= fopen (dumpname
, "w");
636 if (gen_declaration_file
== 0)
637 pfatal_with_name (dumpname
);
641 if (flag_next_runtime
)
643 TAG_GETCLASS
= "objc_getClass";
644 TAG_GETMETACLASS
= "objc_getMetaClass";
645 TAG_MSGSEND
= "objc_msgSend";
646 TAG_MSGSENDSUPER
= "objc_msgSendSuper";
647 TAG_EXECCLASS
= "__objc_execClass";
651 TAG_GETCLASS
= "objc_get_class";
652 TAG_GETMETACLASS
= "objc_get_meta_class";
653 TAG_MSGSEND
= "objc_msg_lookup";
654 TAG_MSGSENDSUPER
= "objc_msg_lookup_super";
655 TAG_EXECCLASS
= "__objc_exec_class";
656 flag_typed_selectors
= 1;
659 if (doing_objc_thang
)
662 if (print_struct_values
)
663 generate_struct_by_value_array ();
669 fatal ("Objective-C text in C source file");
675 if (doing_objc_thang
)
676 finish_objc (); /* Objective-C finalization */
678 if (gen_declaration_file
)
679 fclose (gen_declaration_file
);
694 lang_decode_option (argc
, argv
)
698 const char *p
= argv
[0];
699 if (!strcmp (p
, "-lang-objc"))
700 doing_objc_thang
= 1;
701 else if (!strcmp (p
, "-gen-decls"))
702 flag_gen_declaration
= 1;
703 else if (!strcmp (p
, "-Wselector"))
705 else if (!strcmp (p
, "-Wno-selector"))
707 else if (!strcmp (p
, "-Wprotocol"))
708 flag_warn_protocol
= 1;
709 else if (!strcmp (p
, "-Wno-protocol"))
710 flag_warn_protocol
= 0;
711 else if (!strcmp (p
, "-fgnu-runtime"))
712 flag_next_runtime
= 0;
713 else if (!strcmp (p
, "-fno-next-runtime"))
714 flag_next_runtime
= 0;
715 else if (!strcmp (p
, "-fno-gnu-runtime"))
716 flag_next_runtime
= 1;
717 else if (!strcmp (p
, "-fnext-runtime"))
718 flag_next_runtime
= 1;
719 else if (!strcmp (p
, "-print-objc-runtime-info"))
720 print_struct_values
= 1;
722 return c_decode_option (argc
, argv
);
727 /* used by print-tree.c */
730 lang_print_xnode (file
, node
, indent
)
731 FILE *file ATTRIBUTE_UNUSED
;
732 tree node ATTRIBUTE_UNUSED
;
733 int indent ATTRIBUTE_UNUSED
;
739 define_decl (declarator
, declspecs
)
743 tree decl
= start_decl (declarator
, declspecs
, 0, NULL_TREE
, NULL_TREE
);
744 finish_decl (decl
, NULL_TREE
, NULL_TREE
);
748 /* Return 1 if LHS and RHS are compatible types for assignment or
749 various other operations. Return 0 if they are incompatible, and
750 return -1 if we choose to not decide. When the operation is
751 REFLEXIVE, check for compatibility in either direction.
753 For statically typed objects, an assignment of the form `a' = `b'
757 `a' and `b' are the same class type, or
758 `a' and `b' are of class types A and B such that B is a descendant of A. */
761 maybe_objc_comptypes (lhs
, rhs
, reflexive
)
765 if (doing_objc_thang
)
766 return objc_comptypes (lhs
, rhs
, reflexive
);
771 lookup_method_in_protocol_list (rproto_list
, sel_name
, class_meth
)
779 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
781 p
= TREE_VALUE (rproto
);
783 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
785 if ((fnd
= lookup_method (class_meth
786 ? PROTOCOL_CLS_METHODS (p
)
787 : PROTOCOL_NST_METHODS (p
), sel_name
)))
789 else if (PROTOCOL_LIST (p
))
790 fnd
= lookup_method_in_protocol_list (PROTOCOL_LIST (p
),
791 sel_name
, class_meth
);
795 ; /* An identifier...if we could not find a protocol. */
806 lookup_protocol_in_reflist (rproto_list
, lproto
)
812 /* Make sure the protocol is support by the object on the rhs. */
813 if (TREE_CODE (lproto
) == PROTOCOL_INTERFACE_TYPE
)
816 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
818 p
= TREE_VALUE (rproto
);
820 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
825 else if (PROTOCOL_LIST (p
))
826 fnd
= lookup_protocol_in_reflist (PROTOCOL_LIST (p
), lproto
);
835 ; /* An identifier...if we could not find a protocol. */
841 /* Return 1 if LHS and RHS are compatible types for assignment
842 or various other operations. Return 0 if they are incompatible,
843 and return -1 if we choose to not decide. When the operation
844 is REFLEXIVE, check for compatibility in either direction. */
847 objc_comptypes (lhs
, rhs
, reflexive
)
852 /* New clause for protocols. */
854 if (TREE_CODE (lhs
) == POINTER_TYPE
855 && TREE_CODE (TREE_TYPE (lhs
)) == RECORD_TYPE
856 && TREE_CODE (rhs
) == POINTER_TYPE
857 && TREE_CODE (TREE_TYPE (rhs
)) == RECORD_TYPE
)
859 int lhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (lhs
);
860 int rhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (rhs
);
864 tree lproto
, lproto_list
= TYPE_PROTOCOL_LIST (lhs
);
865 tree rproto
, rproto_list
;
870 rproto_list
= TYPE_PROTOCOL_LIST (rhs
);
872 /* Make sure the protocol is supported by the object
874 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
876 p
= TREE_VALUE (lproto
);
877 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
880 warning ("object does not conform to the `%s' protocol",
881 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
884 else if (TYPED_OBJECT (TREE_TYPE (rhs
)))
886 tree rname
= TYPE_NAME (TREE_TYPE (rhs
));
889 /* Make sure the protocol is supported by the object
891 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
893 p
= TREE_VALUE (lproto
);
895 rinter
= lookup_interface (rname
);
897 while (rinter
&& !rproto
)
901 rproto_list
= CLASS_PROTOCOL_LIST (rinter
);
902 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
904 /* Check for protocols adopted by categories. */
905 cat
= CLASS_CATEGORY_LIST (rinter
);
906 while (cat
&& !rproto
)
908 rproto_list
= CLASS_PROTOCOL_LIST (cat
);
909 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
911 cat
= CLASS_CATEGORY_LIST (cat
);
914 rinter
= lookup_interface (CLASS_SUPER_NAME (rinter
));
918 warning ("class `%s' does not implement the `%s' protocol",
919 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs
))),
920 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
924 /* May change...based on whether there was any mismatch */
927 else if (rhs_is_proto
)
928 /* Lhs is not a protocol...warn if it is statically typed */
929 return (TYPED_OBJECT (TREE_TYPE (lhs
)) != 0);
932 /* Defer to comptypes .*/
936 else if (TREE_CODE (lhs
) == RECORD_TYPE
&& TREE_CODE (rhs
) == RECORD_TYPE
)
937 ; /* Fall thru. This is the case we have been handling all along */
939 /* Defer to comptypes. */
942 /* `id' = `<class> *', `<class> *' = `id' */
944 if ((TYPE_NAME (lhs
) == objc_object_id
&& TYPED_OBJECT (rhs
))
945 || (TYPE_NAME (rhs
) == objc_object_id
&& TYPED_OBJECT (lhs
)))
948 /* `id' = `Class', `Class' = `id' */
950 else if ((TYPE_NAME (lhs
) == objc_object_id
951 && TYPE_NAME (rhs
) == objc_class_id
)
952 || (TYPE_NAME (lhs
) == objc_class_id
953 && TYPE_NAME (rhs
) == objc_object_id
))
956 /* `<class> *' = `<class> *' */
958 else if (TYPED_OBJECT (lhs
) && TYPED_OBJECT (rhs
))
960 tree lname
= TYPE_NAME (lhs
);
961 tree rname
= TYPE_NAME (rhs
);
967 /* If the left hand side is a super class of the right hand side,
969 for (inter
= lookup_interface (rname
); inter
;
970 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
971 if (lname
== CLASS_SUPER_NAME (inter
))
974 /* Allow the reverse when reflexive. */
976 for (inter
= lookup_interface (lname
); inter
;
977 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
978 if (rname
== CLASS_SUPER_NAME (inter
))
984 /* Defer to comptypes. */
988 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
991 objc_check_decl (decl
)
994 tree type
= TREE_TYPE (decl
);
996 if (TREE_CODE (type
) == RECORD_TYPE
997 && TREE_STATIC_TEMPLATE (type
)
998 && type
!= constant_string_type
)
1000 error_with_decl (decl
, "`%s' cannot be statically allocated");
1001 fatal ("statically allocated objects not supported");
1006 maybe_objc_check_decl (decl
)
1009 if (doing_objc_thang
)
1010 objc_check_decl (decl
);
1013 /* Implement static typing. At this point, we know we have an interface. */
1016 get_static_reference (interface
, protocols
)
1020 tree type
= xref_tag (RECORD_TYPE
, interface
);
1024 tree t
, m
= TYPE_MAIN_VARIANT (type
);
1026 t
= copy_node (type
);
1027 TYPE_BINFO (t
) = make_tree_vec (2);
1029 /* Add this type to the chain of variants of TYPE. */
1030 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
1031 TYPE_NEXT_VARIANT (m
) = t
;
1033 /* Look up protocols and install in lang specific list. */
1034 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
1036 /* This forces a new pointer type to be created later
1037 (in build_pointer_type)...so that the new template
1038 we just created will actually be used...what a hack! */
1039 if (TYPE_POINTER_TO (t
))
1040 TYPE_POINTER_TO (t
) = 0;
1049 get_object_reference (protocols
)
1052 tree type_decl
= lookup_name (objc_id_id
);
1055 if (type_decl
&& TREE_CODE (type_decl
) == TYPE_DECL
)
1057 type
= TREE_TYPE (type_decl
);
1058 if (TYPE_MAIN_VARIANT (type
) != id_type
)
1059 warning ("Unexpected type for `id' (%s)",
1060 gen_declaration (type
, errbuf
));
1063 fatal ("Undefined type `id', please import <objc/objc.h>");
1065 /* This clause creates a new pointer type that is qualified with
1066 the protocol specification...this info is used later to do more
1067 elaborate type checking. */
1071 tree t
, m
= TYPE_MAIN_VARIANT (type
);
1073 t
= copy_node (type
);
1074 TYPE_BINFO (t
) = make_tree_vec (2);
1076 /* Add this type to the chain of variants of TYPE. */
1077 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
1078 TYPE_NEXT_VARIANT (m
) = t
;
1080 /* Look up protocols...and install in lang specific list */
1081 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
1083 /* This forces a new pointer type to be created later
1084 (in build_pointer_type)...so that the new template
1085 we just created will actually be used...what a hack! */
1086 if (TYPE_POINTER_TO (t
))
1087 TYPE_POINTER_TO (t
) = NULL
;
1095 lookup_and_install_protocols (protocols
)
1100 tree return_value
= protocols
;
1102 for (proto
= protocols
; proto
; proto
= TREE_CHAIN (proto
))
1104 tree ident
= TREE_VALUE (proto
);
1105 tree p
= lookup_protocol (ident
);
1109 error ("Cannot find protocol declaration for `%s'",
1110 IDENTIFIER_POINTER (ident
));
1112 TREE_CHAIN (prev
) = TREE_CHAIN (proto
);
1114 return_value
= TREE_CHAIN (proto
);
1118 /* Replace identifier with actual protocol node. */
1119 TREE_VALUE (proto
) = p
;
1124 return return_value
;
1127 /* Create and push a decl for a built-in external variable or field NAME.
1129 TYPE is its data type. */
1132 create_builtin_decl (code
, type
, name
)
1133 enum tree_code code
;
1137 tree decl
= build_decl (code
, get_identifier (name
), type
);
1139 if (code
== VAR_DECL
)
1141 TREE_STATIC (decl
) = 1;
1142 make_decl_rtl (decl
, 0, 1);
1146 DECL_ARTIFICIAL (decl
) = 1;
1150 /* Purpose: "play" parser, creating/installing representations
1151 of the declarations that are required by Objective-C.
1155 type_spec--------->sc_spec
1156 (tree_list) (tree_list)
1159 identifier_node identifier_node */
1162 synth_module_prologue ()
1167 /* Defined in `objc.h' */
1168 objc_object_id
= get_identifier (TAG_OBJECT
);
1170 objc_object_reference
= xref_tag (RECORD_TYPE
, objc_object_id
);
1172 id_type
= build_pointer_type (objc_object_reference
);
1174 objc_id_id
= get_identifier (TYPE_ID
);
1175 objc_class_id
= get_identifier (TAG_CLASS
);
1177 objc_class_type
= build_pointer_type (xref_tag (RECORD_TYPE
, objc_class_id
));
1178 protocol_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
1179 get_identifier (PROTOCOL_OBJECT_CLASS_NAME
)));
1181 /* Declare type of selector-objects that represent an operation name. */
1183 #ifdef OBJC_INT_SELECTORS
1184 /* `unsigned int' */
1185 selector_type
= unsigned_type_node
;
1187 /* `struct objc_selector *' */
1189 = build_pointer_type (xref_tag (RECORD_TYPE
,
1190 get_identifier (TAG_SELECTOR
)));
1191 #endif /* not OBJC_INT_SELECTORS */
1193 /* Forward declare type, or else the prototype for msgSendSuper will
1196 super_p
= build_pointer_type (xref_tag (RECORD_TYPE
,
1197 get_identifier (TAG_SUPER
)));
1200 /* id objc_msgSend (id, SEL, ...); */
1203 = build_function_type (id_type
,
1204 tree_cons (NULL_TREE
, id_type
,
1205 tree_cons (NULL_TREE
, selector_type
,
1208 if (! flag_next_runtime
)
1210 umsg_decl
= build_decl (FUNCTION_DECL
,
1211 get_identifier (TAG_MSGSEND
), temp_type
);
1212 DECL_EXTERNAL (umsg_decl
) = 1;
1213 TREE_PUBLIC (umsg_decl
) = 1;
1214 DECL_INLINE (umsg_decl
) = 1;
1215 DECL_ARTIFICIAL (umsg_decl
) = 1;
1217 if (flag_traditional
&& TAG_MSGSEND
[0] != '_')
1218 DECL_BUILT_IN_NONANSI (umsg_decl
) = 1;
1220 make_decl_rtl (umsg_decl
, NULL_PTR
, 1);
1221 pushdecl (umsg_decl
);
1224 umsg_decl
= builtin_function (TAG_MSGSEND
, temp_type
, 0, NOT_BUILT_IN
, 0);
1226 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1229 = build_function_type (id_type
,
1230 tree_cons (NULL_TREE
, super_p
,
1231 tree_cons (NULL_TREE
, selector_type
,
1234 umsg_super_decl
= builtin_function (TAG_MSGSENDSUPER
,
1235 temp_type
, 0, NOT_BUILT_IN
, 0);
1237 /* id objc_getClass (const char *); */
1239 temp_type
= build_function_type (id_type
,
1240 tree_cons (NULL_TREE
,
1241 const_string_type_node
,
1242 tree_cons (NULL_TREE
, void_type_node
,
1246 = builtin_function (TAG_GETCLASS
, temp_type
, 0, NOT_BUILT_IN
, 0);
1248 /* id objc_getMetaClass (const char *); */
1250 objc_get_meta_class_decl
1251 = builtin_function (TAG_GETMETACLASS
, temp_type
, 0, NOT_BUILT_IN
, 0);
1253 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1255 if (! flag_next_runtime
)
1257 if (flag_typed_selectors
)
1259 /* Suppress outputting debug symbols, because
1260 dbxout_init hasn'r been called yet. */
1261 enum debug_info_type save_write_symbols
= write_symbols
;
1262 write_symbols
= NO_DEBUG
;
1264 build_selector_template ();
1265 temp_type
= build_array_type (objc_selector_template
, NULL_TREE
);
1267 write_symbols
= save_write_symbols
;
1270 temp_type
= build_array_type (selector_type
, NULL_TREE
);
1272 layout_type (temp_type
);
1273 UOBJC_SELECTOR_TABLE_decl
1274 = create_builtin_decl (VAR_DECL
, temp_type
,
1275 "_OBJC_SELECTOR_TABLE");
1277 /* Avoid warning when not sending messages. */
1278 TREE_USED (UOBJC_SELECTOR_TABLE_decl
) = 1;
1281 generate_forward_declaration_to_string_table ();
1283 /* Forward declare constant_string_id and constant_string_type. */
1284 constant_string_id
= get_identifier (STRING_OBJECT_CLASS_NAME
);
1285 constant_string_type
= xref_tag (RECORD_TYPE
, constant_string_id
);
1288 /* Custom build_string which sets TREE_TYPE! */
1291 my_build_string (len
, str
)
1296 tree a_string
= build_string (len
, str
);
1298 /* Some code from combine_strings, which is local to c-parse.y. */
1299 if (TREE_TYPE (a_string
) == int_array_type_node
)
1302 TREE_TYPE (a_string
)
1303 = build_array_type (wide_flag
? integer_type_node
: char_type_node
,
1304 build_index_type (build_int_2 (len
- 1, 0)));
1306 TREE_CONSTANT (a_string
) = 1; /* Puts string in the readonly segment */
1307 TREE_STATIC (a_string
) = 1;
1312 /* Return a newly constructed OBJC_STRING_CST node whose value is
1313 the LEN characters at STR.
1314 The TREE_TYPE is not initialized. */
1317 build_objc_string (len
, str
)
1321 tree s
= build_string (len
, str
);
1323 TREE_SET_CODE (s
, OBJC_STRING_CST
);
1327 /* Given a chain of OBJC_STRING_CST's, build a static instance of
1328 NXConstanString which points at the concatenation of those strings.
1329 We place the string object in the __string_objects section of the
1330 __OBJC segment. The Objective-C runtime will initialize the isa
1331 pointers of the string objects to point at the NXConstandString class
1335 build_objc_string_object (strings
)
1338 tree string
, initlist
, constructor
;
1341 if (!doing_objc_thang
)
1344 if (lookup_interface (constant_string_id
) == NULL_TREE
)
1346 error ("Cannot find interface declaration for `%s'",
1347 IDENTIFIER_POINTER (constant_string_id
));
1348 return error_mark_node
;
1351 add_class_reference (constant_string_id
);
1353 /* Combine_strings will work for OBJC_STRING_CST's too. */
1354 string
= combine_strings (strings
);
1355 TREE_SET_CODE (string
, STRING_CST
);
1356 length
= TREE_STRING_LENGTH (string
) - 1;
1358 /* & ((NXConstantString) {0, string, length}) */
1360 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1362 = tree_cons (NULL_TREE
, copy_node (build_unary_op (ADDR_EXPR
, string
, 1)),
1364 initlist
= tree_cons (NULL_TREE
, build_int_2 (length
, 0), initlist
);
1365 constructor
= build_constructor (constant_string_type
, nreverse (initlist
));
1367 if (!flag_next_runtime
)
1370 = objc_add_static_instance (constructor
, constant_string_type
);
1373 return (build_unary_op (ADDR_EXPR
, constructor
, 1));
1376 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1379 objc_add_static_instance (constructor
, class_decl
)
1380 tree constructor
, class_decl
;
1382 static int num_static_inst
;
1386 /* Find the list of static instances for the CLASS_DECL. Create one if
1388 for (chain
= &objc_static_instances
;
1389 *chain
&& TREE_VALUE (*chain
) != class_decl
;
1390 chain
= &TREE_CHAIN (*chain
));
1393 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
1394 add_objc_string (TYPE_NAME (class_decl
), class_names
);
1397 sprintf (buf
, "_OBJC_INSTANCE_%d", num_static_inst
++);
1398 decl
= build_decl (VAR_DECL
, get_identifier (buf
), class_decl
);
1399 DECL_COMMON (decl
) = 1;
1400 TREE_STATIC (decl
) = 1;
1401 DECL_ARTIFICIAL (decl
) = 1;
1402 pushdecl_top_level (decl
);
1403 rest_of_decl_compilation (decl
, 0, 1, 0);
1405 /* Do this here so it gets output later instead of possibly
1406 inside something else we are writing. */
1407 DECL_INITIAL (decl
) = constructor
;
1409 /* Add the DECL to the head of this CLASS' list. */
1410 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
1415 /* Build a static constant CONSTRUCTOR
1416 with type TYPE and elements ELTS. */
1419 build_constructor (type
, elts
)
1422 tree constructor
= build (CONSTRUCTOR
, type
, NULL_TREE
, elts
);
1424 TREE_CONSTANT (constructor
) = 1;
1425 TREE_STATIC (constructor
) = 1;
1426 TREE_READONLY (constructor
) = 1;
1431 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1433 /* Predefine the following data type:
1441 void *defs[cls_def_cnt + cat_def_cnt];
1445 build_objc_symtab_template ()
1447 tree field_decl
, field_decl_chain
, index
;
1449 objc_symtab_template
1450 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SYMTAB
));
1452 /* long sel_ref_cnt; */
1454 field_decl
= create_builtin_decl (FIELD_DECL
,
1455 long_integer_type_node
,
1457 field_decl_chain
= field_decl
;
1461 field_decl
= create_builtin_decl (FIELD_DECL
,
1462 build_pointer_type (selector_type
),
1464 chainon (field_decl_chain
, field_decl
);
1466 /* short cls_def_cnt; */
1468 field_decl
= create_builtin_decl (FIELD_DECL
,
1469 short_integer_type_node
,
1471 chainon (field_decl_chain
, field_decl
);
1473 /* short cat_def_cnt; */
1475 field_decl
= create_builtin_decl (FIELD_DECL
,
1476 short_integer_type_node
,
1478 chainon (field_decl_chain
, field_decl
);
1480 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1482 if (!flag_next_runtime
)
1483 index
= build_index_type (build_int_2 (imp_count
+ cat_count
, 0));
1485 index
= build_index_type (build_int_2 (imp_count
+ cat_count
- 1,
1486 imp_count
== 0 && cat_count
== 0
1488 field_decl
= create_builtin_decl (FIELD_DECL
,
1489 build_array_type (ptr_type_node
, index
),
1491 chainon (field_decl_chain
, field_decl
);
1493 finish_struct (objc_symtab_template
, field_decl_chain
, NULL_TREE
);
1496 /* Create the initial value for the `defs' field of _objc_symtab.
1497 This is a CONSTRUCTOR. */
1500 init_def_list (type
)
1503 tree expr
, initlist
= NULL_TREE
;
1504 struct imp_entry
*impent
;
1507 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1509 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
1511 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1512 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1517 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1519 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1521 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1522 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1526 if (!flag_next_runtime
)
1528 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1531 if (static_instances_decl
)
1532 expr
= build_unary_op (ADDR_EXPR
, static_instances_decl
, 0);
1534 expr
= build_int_2 (0, 0);
1536 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1539 return build_constructor (type
, nreverse (initlist
));
1542 /* Construct the initial value for all of _objc_symtab. */
1545 init_objc_symtab (type
)
1550 /* sel_ref_cnt = { ..., 5, ... } */
1552 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1554 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1556 if (flag_next_runtime
|| ! sel_ref_chain
)
1557 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1559 initlist
= tree_cons (NULL_TREE
,
1560 build_unary_op (ADDR_EXPR
,
1561 UOBJC_SELECTOR_TABLE_decl
, 1),
1564 /* cls_def_cnt = { ..., 5, ... } */
1566 initlist
= tree_cons (NULL_TREE
, build_int_2 (imp_count
, 0), initlist
);
1568 /* cat_def_cnt = { ..., 5, ... } */
1570 initlist
= tree_cons (NULL_TREE
, build_int_2 (cat_count
, 0), initlist
);
1572 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1574 if (imp_count
|| cat_count
|| static_instances_decl
)
1577 tree field
= TYPE_FIELDS (type
);
1578 field
= TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field
))));
1580 initlist
= tree_cons (NULL_TREE
, init_def_list (TREE_TYPE (field
)),
1584 return build_constructor (type
, nreverse (initlist
));
1587 /* Push forward-declarations of all the categories
1588 so that init_def_list can use them in a CONSTRUCTOR. */
1591 forward_declare_categories ()
1593 struct imp_entry
*impent
;
1594 tree sav
= implementation_context
;
1596 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1598 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1600 /* Set an invisible arg to synth_id_with_class_suffix. */
1601 implementation_context
= impent
->imp_context
;
1603 = create_builtin_decl (VAR_DECL
, objc_category_template
,
1604 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", implementation_context
)));
1607 implementation_context
= sav
;
1610 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1611 and initialized appropriately. */
1614 generate_objc_symtab_decl ()
1618 if (!objc_category_template
)
1619 build_category_template ();
1621 /* forward declare categories */
1623 forward_declare_categories ();
1625 if (!objc_symtab_template
)
1626 build_objc_symtab_template ();
1628 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
1630 UOBJC_SYMBOLS_decl
= start_decl (get_identifier ("_OBJC_SYMBOLS"),
1631 tree_cons (NULL_TREE
,
1632 objc_symtab_template
, sc_spec
),
1634 NULL_TREE
, NULL_TREE
);
1636 TREE_USED (UOBJC_SYMBOLS_decl
) = 1;
1637 DECL_IGNORED_P (UOBJC_SYMBOLS_decl
) = 1;
1638 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl
) = 1;
1639 finish_decl (UOBJC_SYMBOLS_decl
,
1640 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)),
1645 init_module_descriptor (type
)
1648 tree initlist
, expr
;
1650 /* version = { 1, ... } */
1652 expr
= build_int_2 (OBJC_VERSION
, 0);
1653 initlist
= build_tree_list (NULL_TREE
, expr
);
1655 /* size = { ..., sizeof (struct objc_module), ... } */
1657 expr
= size_in_bytes (objc_module_template
);
1658 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1660 /* name = { ..., "foo.m", ... } */
1662 expr
= add_objc_string (get_identifier (input_filename
), class_names
);
1663 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1665 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1667 if (UOBJC_SYMBOLS_decl
)
1668 expr
= build_unary_op (ADDR_EXPR
, UOBJC_SYMBOLS_decl
, 0);
1670 expr
= build_int_2 (0, 0);
1671 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1673 return build_constructor (type
, nreverse (initlist
));
1676 /* Write out the data structures to describe Objective C classes defined.
1677 If appropriate, compile and output a setup function to initialize them.
1678 Return a string which is the name of a function to call to initialize
1679 the Objective C data structures for this file (and perhaps for other files
1682 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1685 build_module_descriptor ()
1687 tree decl_specs
, field_decl
, field_decl_chain
;
1689 objc_module_template
1690 = start_struct (RECORD_TYPE
, get_identifier (UTAG_MODULE
));
1694 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1695 field_decl
= get_identifier ("version");
1697 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1698 field_decl_chain
= field_decl
;
1702 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1703 field_decl
= get_identifier ("size");
1705 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1706 chainon (field_decl_chain
, field_decl
);
1710 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
1711 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
1713 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1714 chainon (field_decl_chain
, field_decl
);
1716 /* struct objc_symtab *symtab; */
1718 decl_specs
= get_identifier (UTAG_SYMTAB
);
1719 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
1720 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("symtab"));
1722 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1723 chainon (field_decl_chain
, field_decl
);
1725 finish_struct (objc_module_template
, field_decl_chain
, NULL_TREE
);
1727 /* Create an instance of "objc_module". */
1729 decl_specs
= tree_cons (NULL_TREE
, objc_module_template
,
1730 build_tree_list (NULL_TREE
,
1731 ridpointers
[(int) RID_STATIC
]));
1733 UOBJC_MODULES_decl
= start_decl (get_identifier ("_OBJC_MODULES"),
1734 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
1736 DECL_ARTIFICIAL (UOBJC_MODULES_decl
) = 1;
1737 DECL_IGNORED_P (UOBJC_MODULES_decl
) = 1;
1738 finish_decl (UOBJC_MODULES_decl
,
1739 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl
)),
1742 /* Mark the decl to avoid "defined but not used" warning. */
1743 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl
) = 1;
1745 /* Generate a constructor call for the module descriptor.
1746 This code was generated by reading the grammar rules
1747 of c-parse.in; Therefore, it may not be the most efficient
1748 way of generating the requisite code. */
1750 if (flag_next_runtime
)
1754 tree parms
, function_decl
, decelerator
, void_list_node_1
;
1756 tree init_function_name
= get_file_function_name ('I');
1758 /* Declare void __objc_execClass (void *); */
1760 void_list_node_1
= build_tree_list (NULL_TREE
, void_type_node
);
1762 = build_function_type (void_type_node
,
1763 tree_cons (NULL_TREE
, ptr_type_node
,
1765 function_decl
= build_decl (FUNCTION_DECL
,
1766 get_identifier (TAG_EXECCLASS
),
1768 DECL_EXTERNAL (function_decl
) = 1;
1769 DECL_ARTIFICIAL (function_decl
) = 1;
1770 TREE_PUBLIC (function_decl
) = 1;
1772 pushdecl (function_decl
);
1773 rest_of_decl_compilation (function_decl
, 0, 0, 0);
1776 = build_tree_list (NULL_TREE
,
1777 build_unary_op (ADDR_EXPR
, UOBJC_MODULES_decl
, 0));
1778 decelerator
= build_function_call (function_decl
, parms
);
1780 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1782 start_function (void_list_node_1
,
1783 build_parse_node (CALL_EXPR
, init_function_name
,
1784 /* This has the format of the output
1785 of get_parm_info. */
1786 tree_cons (NULL_TREE
, NULL_TREE
,
1789 NULL_TREE
, NULL_TREE
);
1790 #if 0 /* This should be turned back on later
1791 for the systems where collect is not needed. */
1792 /* Make these functions nonglobal
1793 so each file can use the same name. */
1794 TREE_PUBLIC (current_function_decl
) = 0;
1796 TREE_USED (current_function_decl
) = 1;
1797 store_parm_decls ();
1799 assemble_external (function_decl
);
1800 c_expand_expr_stmt (decelerator
);
1802 TREE_PUBLIC (current_function_decl
) = 1;
1804 function_decl
= current_function_decl
;
1805 finish_function (0);
1807 /* Return the name of the constructor function. */
1808 return XSTR (XEXP (DECL_RTL (function_decl
), 0), 0);
1812 /* extern const char _OBJC_STRINGS[]; */
1815 generate_forward_declaration_to_string_table ()
1817 tree sc_spec
, decl_specs
, expr_decl
;
1819 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_EXTERN
], NULL_TREE
);
1820 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1823 = build_nt (ARRAY_REF
, get_identifier ("_OBJC_STRINGS"), NULL_TREE
);
1825 UOBJC_STRINGS_decl
= define_decl (expr_decl
, decl_specs
);
1828 /* Return the DECL of the string IDENT in the SECTION. */
1831 get_objc_string_decl (ident
, section
)
1833 enum string_section section
;
1837 if (section
== class_names
)
1838 chain
= class_names_chain
;
1839 else if (section
== meth_var_names
)
1840 chain
= meth_var_names_chain
;
1841 else if (section
== meth_var_types
)
1842 chain
= meth_var_types_chain
;
1846 for (; chain
!= 0; chain
= TREE_VALUE (chain
))
1847 if (TREE_VALUE (chain
) == ident
)
1848 return (TREE_PURPOSE (chain
));
1854 /* Output references to all statically allocated objects. Return the DECL
1855 for the array built. */
1858 generate_static_references ()
1860 tree decls
= NULL_TREE
, ident
, decl_spec
, expr_decl
, expr
= NULL_TREE
;
1861 tree class_name
, class, decl
, initlist
;
1862 tree cl_chain
, in_chain
, type
;
1863 int num_inst
, num_class
;
1866 if (flag_next_runtime
)
1869 for (cl_chain
= objc_static_instances
, num_class
= 0;
1870 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
1872 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
1873 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
1875 sprintf (buf
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
1876 ident
= get_identifier (buf
);
1878 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1879 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1880 build_tree_list (NULL_TREE
,
1881 ridpointers
[(int) RID_STATIC
]));
1882 decl
= start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
, NULL_TREE
);
1883 DECL_CONTEXT (decl
) = 0;
1884 DECL_ARTIFICIAL (decl
) = 1;
1886 /* Output {class_name, ...}. */
1887 class = TREE_VALUE (cl_chain
);
1888 class_name
= get_objc_string_decl (TYPE_NAME (class), class_names
);
1889 initlist
= build_tree_list (NULL_TREE
,
1890 build_unary_op (ADDR_EXPR
, class_name
, 1));
1892 /* Output {..., instance, ...}. */
1893 for (in_chain
= TREE_PURPOSE (cl_chain
);
1894 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
1896 expr
= build_unary_op (ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
1897 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1900 /* Output {..., NULL}. */
1901 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1903 expr
= build_constructor (TREE_TYPE (decl
), nreverse (initlist
));
1904 finish_decl (decl
, expr
, NULL_TREE
);
1905 TREE_USED (decl
) = 1;
1907 type
= build_array_type (build_pointer_type (void_type_node
), 0);
1908 decl
= build_decl (VAR_DECL
, ident
, type
);
1909 make_decl_rtl (decl
, 0, 1);
1910 TREE_USED (decl
) = 1;
1912 = tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, decl
, 1), decls
);
1915 decls
= tree_cons (NULL_TREE
, build_int_2 (0, 0), decls
);
1916 ident
= get_identifier ("_OBJC_STATIC_INSTANCES");
1917 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1918 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1919 build_tree_list (NULL_TREE
,
1920 ridpointers
[(int) RID_STATIC
]));
1921 static_instances_decl
1922 = start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
, NULL_TREE
);
1923 TREE_USED (static_instances_decl
) = 1;
1924 DECL_CONTEXT (static_instances_decl
) = 0;
1925 DECL_ARTIFICIAL (static_instances_decl
) = 1;
1926 expr
= build_constructor (TREE_TYPE (static_instances_decl
),
1928 finish_decl (static_instances_decl
, expr
, NULL_TREE
);
1931 /* Output all strings. */
1936 tree sc_spec
, decl_specs
, expr_decl
;
1937 tree chain
, string_expr
;
1940 for (chain
= class_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1942 string
= TREE_VALUE (chain
);
1943 decl
= TREE_PURPOSE (chain
);
1945 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1946 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1947 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1948 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
1949 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1950 IDENTIFIER_POINTER (string
));
1951 finish_decl (decl
, string_expr
, NULL_TREE
);
1954 for (chain
= meth_var_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1956 string
= TREE_VALUE (chain
);
1957 decl
= TREE_PURPOSE (chain
);
1959 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1960 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1961 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1962 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
1963 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1964 IDENTIFIER_POINTER (string
));
1965 finish_decl (decl
, string_expr
, NULL_TREE
);
1968 for (chain
= meth_var_types_chain
; chain
; chain
= TREE_CHAIN (chain
))
1970 string
= TREE_VALUE (chain
);
1971 decl
= TREE_PURPOSE (chain
);
1973 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1974 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1975 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1976 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
1977 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1978 IDENTIFIER_POINTER (string
));
1979 finish_decl (decl
, string_expr
, NULL_TREE
);
1984 build_selector_reference_decl ()
1990 sprintf (buf
, "_OBJC_SELECTOR_REFERENCES_%d", idx
++);
1992 ident
= get_identifier (buf
);
1994 decl
= build_decl (VAR_DECL
, ident
, selector_type
);
1995 DECL_EXTERNAL (decl
) = 1;
1996 TREE_PUBLIC (decl
) = 1;
1997 TREE_USED (decl
) = 1;
1998 TREE_READONLY (decl
) = 1;
1999 DECL_ARTIFICIAL (decl
) = 1;
2000 DECL_CONTEXT (decl
) = 0;
2002 make_decl_rtl (decl
, 0, 1);
2003 pushdecl_top_level (decl
);
2008 /* Just a handy wrapper for add_objc_string. */
2011 build_selector (ident
)
2014 tree expr
= add_objc_string (ident
, meth_var_names
);
2015 if (flag_typed_selectors
)
2018 return build_c_cast (selector_type
, expr
); /* cast! */
2021 /* Synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>]
2022 The cast stops the compiler from issuing the following message:
2023 grok.m: warning: initialization of non-const * pointer from const *
2024 grok.m: warning: initialization between incompatible pointer types. */
2028 build_msg_pool_reference (offset
)
2031 tree expr
= build_int_2 (offset
, 0);
2034 expr
= build_array_ref (UOBJC_STRINGS_decl
, expr
);
2035 expr
= build_unary_op (ADDR_EXPR
, expr
, 0);
2037 cast
= build_tree_list (build_tree_list (NULL_TREE
,
2038 ridpointers
[(int) RID_CHAR
]),
2039 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
2040 TREE_TYPE (expr
) = groktypename (cast
);
2045 init_selector (offset
)
2048 tree expr
= build_msg_pool_reference (offset
);
2049 TREE_TYPE (expr
) = selector_type
;
2055 build_selector_translation_table ()
2057 tree sc_spec
, decl_specs
;
2058 tree chain
, initlist
= NULL_TREE
;
2060 tree decl
= NULL_TREE
, var_decl
, name
;
2062 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
2066 expr
= build_selector (TREE_VALUE (chain
));
2068 if (flag_next_runtime
)
2070 name
= DECL_NAME (TREE_PURPOSE (chain
));
2072 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
2074 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2075 decl_specs
= tree_cons (NULL_TREE
, selector_type
, sc_spec
);
2079 /* The `decl' that is returned from start_decl is the one that we
2080 forward declared in `build_selector_reference' */
2081 decl
= start_decl (var_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2084 /* add one for the '\0' character */
2085 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (chain
)) + 1;
2087 if (flag_next_runtime
)
2088 finish_decl (decl
, expr
, NULL_TREE
);
2091 if (flag_typed_selectors
)
2093 tree eltlist
= NULL_TREE
;
2094 tree encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
2095 eltlist
= tree_cons (NULL_TREE
, expr
, NULL_TREE
);
2096 eltlist
= tree_cons (NULL_TREE
, encoding
, eltlist
);
2097 expr
= build_constructor (objc_selector_template
,
2098 nreverse (eltlist
));
2100 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2105 if (! flag_next_runtime
)
2107 /* Cause the variable and its initial value to be actually output. */
2108 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl
) = 0;
2109 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl
) = 1;
2110 /* NULL terminate the list and fix the decl for output. */
2111 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
2112 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl
) = (tree
) 1;
2113 initlist
= build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
2114 nreverse (initlist
));
2115 finish_decl (UOBJC_SELECTOR_TABLE_decl
, initlist
, NULL_TREE
);
2116 current_function_decl
= NULL_TREE
;
2121 get_proto_encoding (proto
)
2129 if (! METHOD_ENCODING (proto
))
2131 tmp_decl
= build_tmp_function_decl ();
2132 hack_method_prototype (proto
, tmp_decl
);
2133 encoding
= encode_method_prototype (proto
, tmp_decl
);
2134 METHOD_ENCODING (proto
) = encoding
;
2137 encoding
= METHOD_ENCODING (proto
);
2139 return add_objc_string (encoding
, meth_var_types
);
2142 return build_int_2 (0, 0);
2145 /* sel_ref_chain is a list whose "value" fields will be instances of
2146 identifier_node that represent the selector. */
2149 build_typed_selector_reference (ident
, proto
)
2152 tree
*chain
= &sel_ref_chain
;
2158 if (TREE_PURPOSE (*chain
) == ident
&& TREE_VALUE (*chain
) == proto
)
2159 goto return_at_index
;
2162 chain
= &TREE_CHAIN (*chain
);
2165 *chain
= tree_cons (proto
, ident
, NULL_TREE
);
2168 expr
= build_unary_op (ADDR_EXPR
,
2169 build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2170 build_int_2 (index
, 0)),
2172 return build_c_cast (selector_type
, expr
);
2176 build_selector_reference (ident
)
2179 tree
*chain
= &sel_ref_chain
;
2185 if (TREE_VALUE (*chain
) == ident
)
2186 return (flag_next_runtime
2187 ? TREE_PURPOSE (*chain
)
2188 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2189 build_int_2 (index
, 0)));
2192 chain
= &TREE_CHAIN (*chain
);
2195 expr
= build_selector_reference_decl ();
2197 *chain
= tree_cons (expr
, ident
, NULL_TREE
);
2199 return (flag_next_runtime
2201 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2202 build_int_2 (index
, 0)));
2206 build_class_reference_decl ()
2212 sprintf (buf
, "_OBJC_CLASS_REFERENCES_%d", idx
++);
2214 ident
= get_identifier (buf
);
2216 decl
= build_decl (VAR_DECL
, ident
, objc_class_type
);
2217 DECL_EXTERNAL (decl
) = 1;
2218 TREE_PUBLIC (decl
) = 1;
2219 TREE_USED (decl
) = 1;
2220 TREE_READONLY (decl
) = 1;
2221 DECL_CONTEXT (decl
) = 0;
2222 DECL_ARTIFICIAL (decl
) = 1;
2224 make_decl_rtl (decl
, 0, 1);
2225 pushdecl_top_level (decl
);
2230 /* Create a class reference, but don't create a variable to reference
2234 add_class_reference (ident
)
2239 if ((chain
= cls_ref_chain
))
2244 if (ident
== TREE_VALUE (chain
))
2248 chain
= TREE_CHAIN (chain
);
2252 /* Append to the end of the list */
2253 TREE_CHAIN (tail
) = tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2256 cls_ref_chain
= tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2259 /* Get a class reference, creating it if necessary. Also create the
2260 reference variable. */
2263 get_class_reference (ident
)
2266 if (flag_next_runtime
)
2271 for (chain
= &cls_ref_chain
; *chain
; chain
= &TREE_CHAIN (*chain
))
2272 if (TREE_VALUE (*chain
) == ident
)
2274 if (! TREE_PURPOSE (*chain
))
2275 TREE_PURPOSE (*chain
) = build_class_reference_decl ();
2277 return TREE_PURPOSE (*chain
);
2280 decl
= build_class_reference_decl ();
2281 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2288 add_class_reference (ident
);
2290 params
= build_tree_list (NULL_TREE
,
2291 my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
2292 IDENTIFIER_POINTER (ident
)));
2294 assemble_external (objc_get_class_decl
);
2295 return build_function_call (objc_get_class_decl
, params
);
2299 /* SEL_REFDEF_CHAIN is a list whose "value" fields will be instances
2300 of identifier_node that represent the selector. It returns the
2301 offset of the selector from the beginning of the _OBJC_STRINGS
2302 pool. This offset is typically used by init_selector during code
2305 For each string section we have a chain which maps identifier nodes
2306 to decls for the strings. */
2309 add_objc_string (ident
, section
)
2311 enum string_section section
;
2315 if (section
== class_names
)
2316 chain
= &class_names_chain
;
2317 else if (section
== meth_var_names
)
2318 chain
= &meth_var_names_chain
;
2319 else if (section
== meth_var_types
)
2320 chain
= &meth_var_types_chain
;
2326 if (TREE_VALUE (*chain
) == ident
)
2327 return build_unary_op (ADDR_EXPR
, TREE_PURPOSE (*chain
), 1);
2329 chain
= &TREE_CHAIN (*chain
);
2332 decl
= build_objc_string_decl (section
);
2334 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2336 return build_unary_op (ADDR_EXPR
, decl
, 1);
2340 build_objc_string_decl (section
)
2341 enum string_section section
;
2345 static int class_names_idx
= 0;
2346 static int meth_var_names_idx
= 0;
2347 static int meth_var_types_idx
= 0;
2349 if (section
== class_names
)
2350 sprintf (buf
, "_OBJC_CLASS_NAME_%d", class_names_idx
++);
2351 else if (section
== meth_var_names
)
2352 sprintf (buf
, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx
++);
2353 else if (section
== meth_var_types
)
2354 sprintf (buf
, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx
++);
2356 ident
= get_identifier (buf
);
2358 decl
= build_decl (VAR_DECL
, ident
, build_array_type (char_type_node
, 0));
2359 DECL_EXTERNAL (decl
) = 1;
2360 TREE_PUBLIC (decl
) = 1;
2361 TREE_USED (decl
) = 1;
2362 TREE_READONLY (decl
) = 1;
2363 TREE_CONSTANT (decl
) = 1;
2364 DECL_CONTEXT (decl
) = 0;
2365 DECL_ARTIFICIAL (decl
) = 1;
2367 make_decl_rtl (decl
, 0, 1);
2368 pushdecl_top_level (decl
);
2375 objc_declare_alias (alias_ident
, class_ident
)
2379 if (!doing_objc_thang
)
2382 if (is_class_name (class_ident
) != class_ident
)
2383 warning ("Cannot find class `%s'", IDENTIFIER_POINTER (class_ident
));
2384 else if (is_class_name (alias_ident
))
2385 warning ("Class `%s' already exists", IDENTIFIER_POINTER (alias_ident
));
2387 alias_chain
= tree_cons (class_ident
, alias_ident
, alias_chain
);
2391 objc_declare_class (ident_list
)
2396 if (!doing_objc_thang
)
2399 for (list
= ident_list
; list
; list
= TREE_CHAIN (list
))
2401 tree ident
= TREE_VALUE (list
);
2404 if ((decl
= lookup_name (ident
)))
2406 error ("`%s' redeclared as different kind of symbol",
2407 IDENTIFIER_POINTER (ident
));
2408 error_with_decl (decl
, "previous declaration of `%s'");
2411 if (! is_class_name (ident
))
2413 tree record
= xref_tag (RECORD_TYPE
, ident
);
2414 TREE_STATIC_TEMPLATE (record
) = 1;
2415 class_chain
= tree_cons (NULL_TREE
, ident
, class_chain
);
2421 is_class_name (ident
)
2426 if (lookup_interface (ident
))
2429 for (chain
= class_chain
; chain
; chain
= TREE_CHAIN (chain
))
2431 if (ident
== TREE_VALUE (chain
))
2435 for (chain
= alias_chain
; chain
; chain
= TREE_CHAIN (chain
))
2437 if (ident
== TREE_VALUE (chain
))
2438 return TREE_PURPOSE (chain
);
2445 lookup_interface (ident
)
2450 for (chain
= interface_chain
; chain
; chain
= TREE_CHAIN (chain
))
2452 if (ident
== CLASS_NAME (chain
))
2459 objc_copy_list (list
, head
)
2463 tree newlist
= NULL_TREE
, tail
= NULL_TREE
;
2467 tail
= copy_node (list
);
2469 /* The following statement fixes a bug when inheriting instance
2470 variables that are declared to be bitfields. finish_struct
2471 expects to find the width of the bitfield in DECL_INITIAL. */
2472 if (DECL_BIT_FIELD (tail
) && DECL_INITIAL (tail
) == 0)
2473 DECL_INITIAL (tail
) = DECL_SIZE (tail
);
2475 newlist
= chainon (newlist
, tail
);
2476 list
= TREE_CHAIN (list
);
2483 /* Used by: build_private_template, get_class_ivars, and
2484 continue_class. COPY is 1 when called from @defs. In this case
2485 copy all fields. Otherwise don't copy leaf ivars since we rely on
2486 them being side-effected exactly once by finish_struct. */
2489 build_ivar_chain (interface
, copy
)
2493 tree my_name
, super_name
, ivar_chain
;
2495 my_name
= CLASS_NAME (interface
);
2496 super_name
= CLASS_SUPER_NAME (interface
);
2498 /* Possibly copy leaf ivars. */
2500 objc_copy_list (CLASS_IVARS (interface
), &ivar_chain
);
2502 ivar_chain
= CLASS_IVARS (interface
);
2507 tree super_interface
= lookup_interface (super_name
);
2509 if (!super_interface
)
2511 /* fatal did not work with 2 args...should fix */
2512 error ("Cannot find interface declaration for `%s', superclass of `%s'",
2513 IDENTIFIER_POINTER (super_name
),
2514 IDENTIFIER_POINTER (my_name
));
2515 exit (FATAL_EXIT_CODE
);
2518 if (super_interface
== interface
)
2520 fatal ("Circular inheritance in interface declaration for `%s'",
2521 IDENTIFIER_POINTER (super_name
));
2524 interface
= super_interface
;
2525 my_name
= CLASS_NAME (interface
);
2526 super_name
= CLASS_SUPER_NAME (interface
);
2528 op1
= CLASS_IVARS (interface
);
2531 tree head
, tail
= objc_copy_list (op1
, &head
);
2533 /* Prepend super class ivars...make a copy of the list, we
2534 do not want to alter the original. */
2535 TREE_CHAIN (tail
) = ivar_chain
;
2542 /* struct <classname> {
2543 struct objc_class *isa;
2548 build_private_template (class)
2553 if (CLASS_STATIC_TEMPLATE (class))
2555 uprivate_record
= CLASS_STATIC_TEMPLATE (class);
2556 ivar_context
= TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2560 uprivate_record
= start_struct (RECORD_TYPE
, CLASS_NAME (class));
2562 ivar_context
= build_ivar_chain (class, 0);
2564 finish_struct (uprivate_record
, ivar_context
, NULL_TREE
);
2566 CLASS_STATIC_TEMPLATE (class) = uprivate_record
;
2568 /* mark this record as class template - for class type checking */
2569 TREE_STATIC_TEMPLATE (uprivate_record
) = 1;
2573 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
2575 build1 (INDIRECT_REF
, NULL_TREE
,
2578 return ivar_context
;
2581 /* Begin code generation for protocols... */
2583 /* struct objc_protocol {
2584 char *protocol_name;
2585 struct objc_protocol **protocol_list;
2586 struct objc_method_desc *instance_methods;
2587 struct objc_method_desc *class_methods;
2591 build_protocol_template ()
2593 tree decl_specs
, field_decl
, field_decl_chain
;
2596 template = start_struct (RECORD_TYPE
, get_identifier (UTAG_PROTOCOL
));
2598 /* struct objc_class *isa; */
2600 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2601 get_identifier (UTAG_CLASS
)));
2602 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
2604 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2605 field_decl_chain
= field_decl
;
2607 /* char *protocol_name; */
2609 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
2611 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_name"));
2613 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2614 chainon (field_decl_chain
, field_decl
);
2616 /* struct objc_protocol **protocol_list; */
2618 decl_specs
= build_tree_list (NULL_TREE
, template);
2620 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
2621 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
2623 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2624 chainon (field_decl_chain
, field_decl
);
2626 /* struct objc_method_list *instance_methods; */
2629 = build_tree_list (NULL_TREE
,
2630 xref_tag (RECORD_TYPE
,
2631 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2633 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
2635 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2636 chainon (field_decl_chain
, field_decl
);
2638 /* struct objc_method_list *class_methods; */
2641 = build_tree_list (NULL_TREE
,
2642 xref_tag (RECORD_TYPE
,
2643 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2645 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
2647 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2648 chainon (field_decl_chain
, field_decl
);
2650 return finish_struct (template, field_decl_chain
, NULL_TREE
);
2654 build_descriptor_table_initializer (type
, entries
)
2658 tree initlist
= NULL_TREE
;
2662 tree eltlist
= NULL_TREE
;
2665 = tree_cons (NULL_TREE
,
2666 build_selector (METHOD_SEL_NAME (entries
)), NULL_TREE
);
2668 = tree_cons (NULL_TREE
,
2669 add_objc_string (METHOD_ENCODING (entries
),
2674 = tree_cons (NULL_TREE
,
2675 build_constructor (type
, nreverse (eltlist
)), initlist
);
2677 entries
= TREE_CHAIN (entries
);
2681 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
2684 /* struct objc_method_prototype_list {
2686 struct objc_method_prototype {
2693 build_method_prototype_list_template (list_type
, size
)
2697 tree objc_ivar_list_record
;
2698 tree decl_specs
, field_decl
, field_decl_chain
;
2700 /* Generate an unnamed struct definition. */
2702 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
2704 /* int method_count; */
2706 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
2707 field_decl
= get_identifier ("method_count");
2710 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2711 field_decl_chain
= field_decl
;
2713 /* struct objc_method method_list[]; */
2715 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
2716 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
2717 build_int_2 (size
, 0));
2720 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2721 chainon (field_decl_chain
, field_decl
);
2723 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
2725 return objc_ivar_list_record
;
2729 build_method_prototype_template ()
2732 tree decl_specs
, field_decl
, field_decl_chain
;
2735 = start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD_PROTOTYPE
));
2737 #ifdef OBJC_INT_SELECTORS
2738 /* unsigned int _cmd; */
2740 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_UNSIGNED
], NULL_TREE
);
2741 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_INT
], decl_specs
);
2742 field_decl
= get_identifier ("_cmd");
2743 #else /* OBJC_INT_SELECTORS */
2744 /* struct objc_selector *_cmd; */
2745 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
2746 get_identifier (TAG_SELECTOR
)), NULL_TREE
);
2747 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
2748 #endif /* OBJC_INT_SELECTORS */
2751 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2752 field_decl_chain
= field_decl
;
2754 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
2756 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_types"));
2758 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2759 chainon (field_decl_chain
, field_decl
);
2761 finish_struct (proto_record
, field_decl_chain
, NULL_TREE
);
2763 return proto_record
;
2766 /* True if last call to forwarding_offset yielded a register offset. */
2767 static int offset_is_register
;
2770 forwarding_offset (parm
)
2773 int offset_in_bytes
;
2775 if (GET_CODE (DECL_INCOMING_RTL (parm
)) == MEM
)
2777 rtx addr
= XEXP (DECL_INCOMING_RTL (parm
), 0);
2779 /* ??? Here we assume that the parm address is indexed
2780 off the frame pointer or arg pointer.
2781 If that is not true, we produce meaningless results,
2782 but do not crash. */
2783 if (GET_CODE (addr
) == PLUS
2784 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
2785 offset_in_bytes
= INTVAL (XEXP (addr
, 1));
2787 offset_in_bytes
= 0;
2789 offset_in_bytes
+= OBJC_FORWARDING_STACK_OFFSET
;
2790 offset_is_register
= 0;
2792 else if (GET_CODE (DECL_INCOMING_RTL (parm
)) == REG
)
2794 int regno
= REGNO (DECL_INCOMING_RTL (parm
));
2795 offset_in_bytes
= apply_args_register_offset (regno
);
2796 offset_is_register
= 1;
2801 /* This is the case where the parm is passed as an int or double
2802 and it is converted to a char, short or float and stored back
2803 in the parmlist. In this case, describe the parm
2804 with the variable's declared type, and adjust the address
2805 if the least significant bytes (which we are using) are not
2807 if (BYTES_BIG_ENDIAN
&& TREE_TYPE (parm
) != DECL_ARG_TYPE (parm
))
2808 offset_in_bytes
+= (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm
)))
2809 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm
))));
2811 return offset_in_bytes
;
2815 encode_method_prototype (method_decl
, func_decl
)
2822 int max_parm_end
= 0;
2826 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2827 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl
)));
2830 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
2831 obstack_object_size (&util_obstack
),
2832 OBJC_ENCODE_INLINE_DEFS
);
2835 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
2836 parms
= TREE_CHAIN (parms
))
2838 int parm_end
= (forwarding_offset (parms
)
2839 + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms
)))
2842 if (!offset_is_register
&& max_parm_end
< parm_end
)
2843 max_parm_end
= parm_end
;
2846 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
2848 sprintf (buf
, "%d", stack_size
);
2849 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2851 user_args
= METHOD_SEL_ARGS (method_decl
);
2853 /* Argument types. */
2854 for (parms
= DECL_ARGUMENTS (func_decl
), i
= 0; parms
;
2855 parms
= TREE_CHAIN (parms
), i
++)
2857 /* Process argument qualifiers for user supplied arguments. */
2860 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args
)));
2861 user_args
= TREE_CHAIN (user_args
);
2865 encode_type (TREE_TYPE (parms
),
2866 obstack_object_size (&util_obstack
),
2867 OBJC_ENCODE_INLINE_DEFS
);
2869 /* Compute offset. */
2870 sprintf (buf
, "%d", forwarding_offset (parms
));
2872 /* Indicate register. */
2873 if (offset_is_register
)
2874 obstack_1grow (&util_obstack
, '+');
2876 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2879 obstack_1grow (&util_obstack
, '\0');
2880 result
= get_identifier (obstack_finish (&util_obstack
));
2881 obstack_free (&util_obstack
, util_firstobj
);
2886 generate_descriptor_table (type
, name
, size
, list
, proto
)
2893 tree sc_spec
, decl_specs
, decl
, initlist
;
2895 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2896 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
2898 decl
= start_decl (synth_id_with_class_suffix (name
, proto
),
2899 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2901 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
2902 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
2904 finish_decl (decl
, build_constructor (type
, nreverse (initlist
)),
2911 generate_method_descriptors (protocol
) /* generate_dispatch_tables */
2914 static tree objc_method_prototype_template
;
2915 tree initlist
, chain
, method_list_template
;
2916 tree cast
, variable_length_type
;
2919 if (!objc_method_prototype_template
)
2920 objc_method_prototype_template
= build_method_prototype_template ();
2922 cast
= build_tree_list (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2923 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
))),
2925 variable_length_type
= groktypename (cast
);
2927 chain
= PROTOCOL_CLS_METHODS (protocol
);
2930 size
= list_length (chain
);
2932 method_list_template
2933 = build_method_prototype_list_template (objc_method_prototype_template
,
2937 = build_descriptor_table_initializer (objc_method_prototype_template
,
2940 UOBJC_CLASS_METHODS_decl
2941 = generate_descriptor_table (method_list_template
,
2942 "_OBJC_PROTOCOL_CLASS_METHODS",
2943 size
, initlist
, protocol
);
2944 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
2947 UOBJC_CLASS_METHODS_decl
= 0;
2949 chain
= PROTOCOL_NST_METHODS (protocol
);
2952 size
= list_length (chain
);
2954 method_list_template
2955 = build_method_prototype_list_template (objc_method_prototype_template
,
2958 = build_descriptor_table_initializer (objc_method_prototype_template
,
2961 UOBJC_INSTANCE_METHODS_decl
2962 = generate_descriptor_table (method_list_template
,
2963 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2964 size
, initlist
, protocol
);
2965 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
2968 UOBJC_INSTANCE_METHODS_decl
= 0;
2972 build_tmp_function_decl ()
2974 tree decl_specs
, expr_decl
, parms
;
2978 /* struct objc_object *objc_xxx (id, SEL, ...); */
2980 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
2981 push_parm_decl (build_tree_list
2982 (build_tree_list (decl_specs
,
2983 build1 (INDIRECT_REF
, NULL_TREE
,
2985 build_tree_list (NULL_TREE
, NULL_TREE
)));
2987 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2988 get_identifier (TAG_SELECTOR
)));
2989 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
);
2991 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, expr_decl
),
2992 build_tree_list (NULL_TREE
, NULL_TREE
)));
2993 parms
= get_parm_info (0);
2996 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
2997 sprintf (buffer
, "__objc_tmp_%x", xxx
++);
2998 expr_decl
= build_nt (CALL_EXPR
, get_identifier (buffer
), parms
, NULL_TREE
);
2999 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
3001 return define_decl (expr_decl
, decl_specs
);
3005 hack_method_prototype (nst_methods
, tmp_decl
)
3012 /* Hack to avoid problem with static typing of self arg. */
3013 TREE_SET_CODE (nst_methods
, CLASS_METHOD_DECL
);
3014 start_method_def (nst_methods
);
3015 TREE_SET_CODE (nst_methods
, INSTANCE_METHOD_DECL
);
3017 if (METHOD_ADD_ARGS (nst_methods
) == (tree
) 1)
3018 parms
= get_parm_info (0); /* we have a `, ...' */
3020 parms
= get_parm_info (1); /* place a `void_at_end' */
3022 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
3024 /* Usually called from store_parm_decls -> init_function_start. */
3026 DECL_ARGUMENTS (tmp_decl
) = TREE_PURPOSE (parms
);
3027 current_function_decl
= tmp_decl
;
3030 /* Code taken from start_function. */
3031 tree restype
= TREE_TYPE (TREE_TYPE (tmp_decl
));
3032 /* Promote the value to int before returning it. */
3033 if (TREE_CODE (restype
) == INTEGER_TYPE
3034 && TYPE_PRECISION (restype
) < TYPE_PRECISION (integer_type_node
))
3035 restype
= integer_type_node
;
3036 DECL_RESULT (tmp_decl
) = build_decl (RESULT_DECL
, 0, restype
);
3039 for (parm
= DECL_ARGUMENTS (tmp_decl
); parm
; parm
= TREE_CHAIN (parm
))
3040 DECL_CONTEXT (parm
) = tmp_decl
;
3042 init_function_start (tmp_decl
, "objc-act", 0);
3044 /* Typically called from expand_function_start for function definitions. */
3045 assign_parms (tmp_decl
);
3047 /* install return type */
3048 TREE_TYPE (TREE_TYPE (tmp_decl
)) = groktypename (TREE_TYPE (nst_methods
));
3053 generate_protocol_references (plist
)
3058 /* Forward declare protocols referenced. */
3059 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
3061 tree proto
= TREE_VALUE (lproto
);
3063 if (TREE_CODE (proto
) == PROTOCOL_INTERFACE_TYPE
3064 && PROTOCOL_NAME (proto
))
3066 if (! PROTOCOL_FORWARD_DECL (proto
))
3067 build_protocol_reference (proto
);
3069 if (PROTOCOL_LIST (proto
))
3070 generate_protocol_references (PROTOCOL_LIST (proto
));
3076 generate_protocols ()
3078 tree p
, tmp_decl
, encoding
;
3079 tree sc_spec
, decl_specs
, decl
;
3080 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
3081 tree cast_type2
= 0;
3083 tmp_decl
= build_tmp_function_decl ();
3085 if (! objc_protocol_template
)
3086 objc_protocol_template
= build_protocol_template ();
3088 /* If a protocol was directly referenced, pull in indirect references. */
3089 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3090 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
3091 generate_protocol_references (PROTOCOL_LIST (p
));
3093 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3095 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
3096 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
3098 /* If protocol wasn't referenced, don't generate any code. */
3099 if (! PROTOCOL_FORWARD_DECL (p
))
3102 /* Make sure we link in the Protocol class. */
3103 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
3107 if (! METHOD_ENCODING (nst_methods
))
3109 hack_method_prototype (nst_methods
, tmp_decl
);
3110 encoding
= encode_method_prototype (nst_methods
, tmp_decl
);
3111 METHOD_ENCODING (nst_methods
) = encoding
;
3113 nst_methods
= TREE_CHAIN (nst_methods
);
3118 if (! METHOD_ENCODING (cls_methods
))
3120 hack_method_prototype (cls_methods
, tmp_decl
);
3121 encoding
= encode_method_prototype (cls_methods
, tmp_decl
);
3122 METHOD_ENCODING (cls_methods
) = encoding
;
3125 cls_methods
= TREE_CHAIN (cls_methods
);
3127 generate_method_descriptors (p
);
3129 if (PROTOCOL_LIST (p
))
3130 refs_decl
= generate_protocol_list (p
);
3134 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3136 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
],
3138 decl_specs
= tree_cons (NULL_TREE
, objc_protocol_template
, sc_spec
);
3140 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
),
3141 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
3143 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
3150 (build_tree_list (build_tree_list (NULL_TREE
,
3151 objc_protocol_template
),
3152 build1 (INDIRECT_REF
, NULL_TREE
,
3153 build1 (INDIRECT_REF
, NULL_TREE
,
3156 refs_expr
= build_unary_op (ADDR_EXPR
, refs_decl
, 0);
3157 TREE_TYPE (refs_expr
) = cast_type2
;
3160 refs_expr
= build_int_2 (0, 0);
3162 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3163 by generate_method_descriptors, which is called above. */
3164 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
3165 protocol_name_expr
, refs_expr
,
3166 UOBJC_INSTANCE_METHODS_decl
,
3167 UOBJC_CLASS_METHODS_decl
);
3168 finish_decl (decl
, initlist
, NULL_TREE
);
3170 /* Mark the decl as used to avoid "defined but not used" warning. */
3171 TREE_USED (decl
) = 1;
3176 build_protocol_initializer (type
, protocol_name
, protocol_list
,
3177 instance_methods
, class_methods
)
3181 tree instance_methods
;
3184 tree initlist
= NULL_TREE
, expr
;
3185 static tree cast_type
= 0;
3191 (build_tree_list (NULL_TREE
,
3192 xref_tag (RECORD_TYPE
,
3193 get_identifier (UTAG_CLASS
))),
3194 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
3196 /* Filling the "isa" in with one allows the runtime system to
3197 detect that the version change...should remove before final release. */
3199 expr
= build_int_2 (PROTOCOL_VERSION
, 0);
3200 TREE_TYPE (expr
) = cast_type
;
3201 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3202 initlist
= tree_cons (NULL_TREE
, protocol_name
, initlist
);
3203 initlist
= tree_cons (NULL_TREE
, protocol_list
, initlist
);
3205 if (!instance_methods
)
3206 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3209 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
3210 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3214 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3217 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
3218 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3221 return build_constructor (type
, nreverse (initlist
));
3224 /* struct objc_category {
3225 char *category_name;
3227 struct objc_method_list *instance_methods;
3228 struct objc_method_list *class_methods;
3229 struct objc_protocol_list *protocols;
3233 build_category_template ()
3235 tree decl_specs
, field_decl
, field_decl_chain
;
3237 objc_category_template
= start_struct (RECORD_TYPE
,
3238 get_identifier (UTAG_CATEGORY
));
3239 /* char *category_name; */
3241 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3243 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("category_name"));
3245 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3246 field_decl_chain
= field_decl
;
3248 /* char *class_name; */
3250 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3251 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_name"));
3253 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3254 chainon (field_decl_chain
, field_decl
);
3256 /* struct objc_method_list *instance_methods; */
3258 decl_specs
= build_tree_list (NULL_TREE
,
3259 xref_tag (RECORD_TYPE
,
3260 get_identifier (UTAG_METHOD_LIST
)));
3262 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
3264 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3265 chainon (field_decl_chain
, field_decl
);
3267 /* struct objc_method_list *class_methods; */
3269 decl_specs
= build_tree_list (NULL_TREE
,
3270 xref_tag (RECORD_TYPE
,
3271 get_identifier (UTAG_METHOD_LIST
)));
3273 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
3275 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3276 chainon (field_decl_chain
, field_decl
);
3278 /* struct objc_protocol **protocol_list; */
3280 decl_specs
= build_tree_list (NULL_TREE
,
3281 xref_tag (RECORD_TYPE
,
3282 get_identifier (UTAG_PROTOCOL
)));
3284 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3285 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3287 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3288 chainon (field_decl_chain
, field_decl
);
3290 finish_struct (objc_category_template
, field_decl_chain
, NULL_TREE
);
3293 /* struct objc_selector {
3299 build_selector_template ()
3302 tree decl_specs
, field_decl
, field_decl_chain
;
3304 objc_selector_template
3305 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SELECTOR
));
3309 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3310 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3312 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3313 field_decl_chain
= field_decl
;
3315 /* char *sel_type; */
3317 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3318 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_type"));
3320 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3321 chainon (field_decl_chain
, field_decl
);
3323 finish_struct (objc_selector_template
, field_decl_chain
, NULL_TREE
);
3326 /* struct objc_class {
3327 struct objc_class *isa;
3328 struct objc_class *super_class;
3333 struct objc_ivar_list *ivars;
3334 struct objc_method_list *methods;
3335 if (flag_next_runtime)
3336 struct objc_cache *cache;
3338 struct sarray *dtable;
3339 struct objc_class *subclass_list;
3340 struct objc_class *sibling_class;
3342 struct objc_protocol_list *protocols;
3343 void *gc_object_type;
3347 build_class_template ()
3349 tree decl_specs
, field_decl
, field_decl_chain
;
3352 = start_struct (RECORD_TYPE
, get_identifier (UTAG_CLASS
));
3354 /* struct objc_class *isa; */
3356 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3357 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
3359 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3360 field_decl_chain
= field_decl
;
3362 /* struct objc_class *super_class; */
3364 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3366 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("super_class"));
3368 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3369 chainon (field_decl_chain
, field_decl
);
3373 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3374 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
3376 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3377 chainon (field_decl_chain
, field_decl
);
3381 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3382 field_decl
= get_identifier ("version");
3384 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3385 chainon (field_decl_chain
, field_decl
);
3389 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3390 field_decl
= get_identifier ("info");
3392 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3393 chainon (field_decl_chain
, field_decl
);
3395 /* long instance_size; */
3397 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3398 field_decl
= get_identifier ("instance_size");
3400 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3401 chainon (field_decl_chain
, field_decl
);
3403 /* struct objc_ivar_list *ivars; */
3405 decl_specs
= build_tree_list (NULL_TREE
,
3406 xref_tag (RECORD_TYPE
,
3407 get_identifier (UTAG_IVAR_LIST
)));
3408 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivars"));
3410 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3411 chainon (field_decl_chain
, field_decl
);
3413 /* struct objc_method_list *methods; */
3415 decl_specs
= build_tree_list (NULL_TREE
,
3416 xref_tag (RECORD_TYPE
,
3417 get_identifier (UTAG_METHOD_LIST
)));
3418 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("methods"));
3420 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3421 chainon (field_decl_chain
, field_decl
);
3423 if (flag_next_runtime
)
3425 /* struct objc_cache *cache; */
3427 decl_specs
= build_tree_list (NULL_TREE
,
3428 xref_tag (RECORD_TYPE
,
3429 get_identifier ("objc_cache")));
3430 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("cache"));
3431 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3432 decl_specs
, NULL_TREE
);
3433 chainon (field_decl_chain
, field_decl
);
3437 /* struct sarray *dtable; */
3439 decl_specs
= build_tree_list (NULL_TREE
,
3440 xref_tag (RECORD_TYPE
,
3441 get_identifier ("sarray")));
3442 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("dtable"));
3443 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3444 decl_specs
, NULL_TREE
);
3445 chainon (field_decl_chain
, field_decl
);
3447 /* struct objc_class *subclass_list; */
3449 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3451 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("subclass_list"));
3452 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3453 decl_specs
, NULL_TREE
);
3454 chainon (field_decl_chain
, field_decl
);
3456 /* struct objc_class *sibling_class; */
3458 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3460 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sibling_class"));
3461 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3462 decl_specs
, NULL_TREE
);
3463 chainon (field_decl_chain
, field_decl
);
3466 /* struct objc_protocol **protocol_list; */
3468 decl_specs
= build_tree_list (NULL_TREE
,
3469 xref_tag (RECORD_TYPE
,
3470 get_identifier (UTAG_PROTOCOL
)));
3472 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3474 = build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3475 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3476 decl_specs
, NULL_TREE
);
3477 chainon (field_decl_chain
, field_decl
);
3481 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3482 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3484 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3485 chainon (field_decl_chain
, field_decl
);
3487 /* void *gc_object_type; */
3489 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3490 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("gc_object_type"));
3492 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3493 chainon (field_decl_chain
, field_decl
);
3495 finish_struct (objc_class_template
, field_decl_chain
, NULL_TREE
);
3498 /* Generate appropriate forward declarations for an implementation. */
3501 synth_forward_declarations ()
3503 tree sc_spec
, decl_specs
, an_id
;
3505 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3507 an_id
= synth_id_with_class_suffix ("_OBJC_CLASS", implementation_context
);
3509 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
3510 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
3511 UOBJC_CLASS_decl
= define_decl (an_id
, decl_specs
);
3512 TREE_USED (UOBJC_CLASS_decl
) = 1;
3513 DECL_ARTIFICIAL (UOBJC_CLASS_decl
) = 1;
3515 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3517 an_id
= synth_id_with_class_suffix ("_OBJC_METACLASS",
3518 implementation_context
);
3520 UOBJC_METACLASS_decl
= define_decl (an_id
, decl_specs
);
3521 TREE_USED (UOBJC_METACLASS_decl
) = 1;
3522 DECL_ARTIFICIAL(UOBJC_METACLASS_decl
) = 1;
3524 /* Pre-build the following entities - for speed/convenience. */
3526 an_id
= get_identifier ("super_class");
3527 ucls_super_ref
= build_component_ref (UOBJC_CLASS_decl
, an_id
);
3528 uucls_super_ref
= build_component_ref (UOBJC_METACLASS_decl
, an_id
);
3532 error_with_ivar (message
, decl
, rawdecl
)
3533 const char *message
;
3539 report_error_function (DECL_SOURCE_FILE (decl
));
3541 fprintf (stderr
, "%s:%d: ",
3542 DECL_SOURCE_FILE (decl
), DECL_SOURCE_LINE (decl
));
3543 bzero (errbuf
, BUFSIZE
);
3544 fprintf (stderr
, "%s `%s'\n", message
, gen_declaration (rawdecl
, errbuf
));
3547 #define USERTYPE(t) \
3548 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3549 || TREE_CODE (t) == ENUMERAL_TYPE)
3552 check_ivars (inter
, imp
)
3556 tree intdecls
= CLASS_IVARS (inter
);
3557 tree impdecls
= CLASS_IVARS (imp
);
3558 tree rawintdecls
= CLASS_RAW_IVARS (inter
);
3559 tree rawimpdecls
= CLASS_RAW_IVARS (imp
);
3565 if (intdecls
== 0 && impdecls
== 0)
3567 if (intdecls
== 0 || impdecls
== 0)
3569 error ("inconsistent instance variable specification");
3573 t1
= TREE_TYPE (intdecls
); t2
= TREE_TYPE (impdecls
);
3575 if (!comptypes (t1
, t2
))
3577 if (DECL_NAME (intdecls
) == DECL_NAME (impdecls
))
3579 error_with_ivar ("conflicting instance variable type",
3580 impdecls
, rawimpdecls
);
3581 error_with_ivar ("previous declaration of",
3582 intdecls
, rawintdecls
);
3584 else /* both the type and the name don't match */
3586 error ("inconsistent instance variable specification");
3591 else if (DECL_NAME (intdecls
) != DECL_NAME (impdecls
))
3593 error_with_ivar ("conflicting instance variable name",
3594 impdecls
, rawimpdecls
);
3595 error_with_ivar ("previous declaration of",
3596 intdecls
, rawintdecls
);
3599 intdecls
= TREE_CHAIN (intdecls
);
3600 impdecls
= TREE_CHAIN (impdecls
);
3601 rawintdecls
= TREE_CHAIN (rawintdecls
);
3602 rawimpdecls
= TREE_CHAIN (rawimpdecls
);
3606 /* Set super_type to the data type node for struct objc_super *,
3607 first defining struct objc_super itself.
3608 This needs to be done just once per compilation. */
3611 build_super_template ()
3613 tree record
, decl_specs
, field_decl
, field_decl_chain
;
3615 record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_SUPER
));
3617 /* struct objc_object *self; */
3619 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3620 field_decl
= get_identifier ("self");
3621 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3622 field_decl
= grokfield (input_filename
, lineno
,
3623 field_decl
, decl_specs
, NULL_TREE
);
3624 field_decl_chain
= field_decl
;
3626 /* struct objc_class *class; */
3628 decl_specs
= get_identifier (UTAG_CLASS
);
3629 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
3630 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class"));
3632 field_decl
= grokfield (input_filename
, lineno
,
3633 field_decl
, decl_specs
, NULL_TREE
);
3634 chainon (field_decl_chain
, field_decl
);
3636 finish_struct (record
, field_decl_chain
, NULL_TREE
);
3638 /* `struct objc_super *' */
3639 super_type
= groktypename (build_tree_list (build_tree_list (NULL_TREE
,
3641 build1 (INDIRECT_REF
,
3642 NULL_TREE
, NULL_TREE
)));
3646 /* struct objc_ivar {
3653 build_ivar_template ()
3655 tree objc_ivar_id
, objc_ivar_record
;
3656 tree decl_specs
, field_decl
, field_decl_chain
;
3658 objc_ivar_id
= get_identifier (UTAG_IVAR
);
3659 objc_ivar_record
= start_struct (RECORD_TYPE
, objc_ivar_id
);
3661 /* char *ivar_name; */
3663 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3664 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_name"));
3666 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3667 decl_specs
, NULL_TREE
);
3668 field_decl_chain
= field_decl
;
3670 /* char *ivar_type; */
3672 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3673 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_type"));
3675 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3676 decl_specs
, NULL_TREE
);
3677 chainon (field_decl_chain
, field_decl
);
3679 /* int ivar_offset; */
3681 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3682 field_decl
= get_identifier ("ivar_offset");
3684 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3685 decl_specs
, NULL_TREE
);
3686 chainon (field_decl_chain
, field_decl
);
3688 finish_struct (objc_ivar_record
, field_decl_chain
, NULL_TREE
);
3690 return objc_ivar_record
;
3695 struct objc_ivar ivar_list[ivar_count];
3699 build_ivar_list_template (list_type
, size
)
3703 tree objc_ivar_list_record
;
3704 tree decl_specs
, field_decl
, field_decl_chain
;
3706 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3708 /* int ivar_count; */
3710 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3711 field_decl
= get_identifier ("ivar_count");
3713 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3714 decl_specs
, NULL_TREE
);
3715 field_decl_chain
= field_decl
;
3717 /* struct objc_ivar ivar_list[]; */
3719 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3720 field_decl
= build_nt (ARRAY_REF
, get_identifier ("ivar_list"),
3721 build_int_2 (size
, 0));
3723 field_decl
= grokfield (input_filename
, lineno
,
3724 field_decl
, decl_specs
, NULL_TREE
);
3725 chainon (field_decl_chain
, field_decl
);
3727 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3729 return objc_ivar_list_record
;
3735 struct objc_method method_list[method_count];
3739 build_method_list_template (list_type
, size
)
3743 tree objc_ivar_list_record
;
3744 tree decl_specs
, field_decl
, field_decl_chain
;
3746 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3748 /* int method_next; */
3753 xref_tag (RECORD_TYPE
,
3754 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
3756 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_next"));
3757 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3758 decl_specs
, NULL_TREE
);
3759 field_decl_chain
= field_decl
;
3761 /* int method_count; */
3763 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3764 field_decl
= get_identifier ("method_count");
3766 field_decl
= grokfield (input_filename
, lineno
,
3767 field_decl
, decl_specs
, NULL_TREE
);
3768 chainon (field_decl_chain
, field_decl
);
3770 /* struct objc_method method_list[]; */
3772 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3773 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
3774 build_int_2 (size
, 0));
3776 field_decl
= grokfield (input_filename
, lineno
,
3777 field_decl
, decl_specs
, NULL_TREE
);
3778 chainon (field_decl_chain
, field_decl
);
3780 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3782 return objc_ivar_list_record
;
3786 build_ivar_list_initializer (type
, field_decl
)
3790 tree initlist
= NULL_TREE
;
3794 tree ivar
= NULL_TREE
;
3797 if (DECL_NAME (field_decl
))
3798 ivar
= tree_cons (NULL_TREE
,
3799 add_objc_string (DECL_NAME (field_decl
),
3803 /* Unnamed bit-field ivar (yuck). */
3804 ivar
= tree_cons (NULL_TREE
, build_int_2 (0, 0), ivar
);
3807 encode_field_decl (field_decl
,
3808 obstack_object_size (&util_obstack
),
3809 OBJC_ENCODE_DONT_INLINE_DEFS
);
3811 /* Null terminate string. */
3812 obstack_1grow (&util_obstack
, 0);
3816 add_objc_string (get_identifier (obstack_finish (&util_obstack
)),
3819 obstack_free (&util_obstack
, util_firstobj
);
3825 build_int_2 ((TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl
))
3830 initlist
= tree_cons (NULL_TREE
,
3831 build_constructor (type
, nreverse (ivar
)),
3834 field_decl
= TREE_CHAIN (field_decl
);
3838 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3842 generate_ivars_list (type
, name
, size
, list
)
3848 tree sc_spec
, decl_specs
, decl
, initlist
;
3850 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3851 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
3853 decl
= start_decl (synth_id_with_class_suffix (name
, implementation_context
),
3854 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
3856 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
3857 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3860 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3867 generate_ivar_lists ()
3869 tree initlist
, ivar_list_template
, chain
;
3870 tree cast
, variable_length_type
;
3873 generating_instance_variables
= 1;
3875 if (!objc_ivar_template
)
3876 objc_ivar_template
= build_ivar_template ();
3880 (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3881 get_identifier (UTAG_IVAR_LIST
))),
3883 variable_length_type
= groktypename (cast
);
3885 /* Only generate class variables for the root of the inheritance
3886 hierarchy since these will be the same for every class. */
3888 if (CLASS_SUPER_NAME (implementation_template
) == NULL_TREE
3889 && (chain
= TYPE_FIELDS (objc_class_template
)))
3891 size
= list_length (chain
);
3893 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3894 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3896 UOBJC_CLASS_VARIABLES_decl
3897 = generate_ivars_list (ivar_list_template
, "_OBJC_CLASS_VARIABLES",
3899 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl
) = variable_length_type
;
3902 UOBJC_CLASS_VARIABLES_decl
= 0;
3904 chain
= CLASS_IVARS (implementation_template
);
3907 size
= list_length (chain
);
3908 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3909 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3911 UOBJC_INSTANCE_VARIABLES_decl
3912 = generate_ivars_list (ivar_list_template
, "_OBJC_INSTANCE_VARIABLES",
3914 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl
) = variable_length_type
;
3917 UOBJC_INSTANCE_VARIABLES_decl
= 0;
3919 generating_instance_variables
= 0;
3923 build_dispatch_table_initializer (type
, entries
)
3927 tree initlist
= NULL_TREE
;
3931 tree elemlist
= NULL_TREE
;
3933 elemlist
= tree_cons (NULL_TREE
,
3934 build_selector (METHOD_SEL_NAME (entries
)),
3937 elemlist
= tree_cons (NULL_TREE
,
3938 add_objc_string (METHOD_ENCODING (entries
),
3942 elemlist
= tree_cons (NULL_TREE
,
3943 build_unary_op (ADDR_EXPR
,
3944 METHOD_DEFINITION (entries
), 1),
3947 initlist
= tree_cons (NULL_TREE
,
3948 build_constructor (type
, nreverse (elemlist
)),
3951 entries
= TREE_CHAIN (entries
);
3955 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3958 /* To accomplish method prototyping without generating all kinds of
3959 inane warnings, the definition of the dispatch table entries were
3962 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3964 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3967 build_method_template ()
3970 tree decl_specs
, field_decl
, field_decl_chain
;
3972 _SLT_record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD
));
3974 #ifdef OBJC_INT_SELECTORS
3975 /* unsigned int _cmd; */
3976 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_UNSIGNED
],
3978 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_INT
], decl_specs
);
3979 field_decl
= get_identifier ("_cmd");
3980 #else /* not OBJC_INT_SELECTORS */
3981 /* struct objc_selector *_cmd; */
3982 decl_specs
= tree_cons (NULL_TREE
,
3983 xref_tag (RECORD_TYPE
,
3984 get_identifier (TAG_SELECTOR
)),
3986 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
3987 #endif /* not OBJC_INT_SELECTORS */
3989 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3990 decl_specs
, NULL_TREE
);
3991 field_decl_chain
= field_decl
;
3993 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
3994 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
,
3995 get_identifier ("method_types"));
3996 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3997 decl_specs
, NULL_TREE
);
3998 chainon (field_decl_chain
, field_decl
);
4002 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_VOID
], NULL_TREE
);
4003 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_imp"));
4004 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
4005 decl_specs
, NULL_TREE
);
4006 chainon (field_decl_chain
, field_decl
);
4008 finish_struct (_SLT_record
, field_decl_chain
, NULL_TREE
);
4015 generate_dispatch_table (type
, name
, size
, list
)
4021 tree sc_spec
, decl_specs
, decl
, initlist
;
4023 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4024 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
4026 decl
= start_decl (synth_id_with_class_suffix (name
, implementation_context
),
4027 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
4029 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
4030 initlist
= tree_cons (NULL_TREE
, build_int_2 (size
, 0), initlist
);
4031 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
4034 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
4041 generate_dispatch_tables ()
4043 tree initlist
, chain
, method_list_template
;
4044 tree cast
, variable_length_type
;
4047 if (!objc_method_template
)
4048 objc_method_template
= build_method_template ();
4052 (build_tree_list (NULL_TREE
,
4053 xref_tag (RECORD_TYPE
,
4054 get_identifier (UTAG_METHOD_LIST
))),
4057 variable_length_type
= groktypename (cast
);
4059 chain
= CLASS_CLS_METHODS (implementation_context
);
4062 size
= list_length (chain
);
4064 method_list_template
4065 = build_method_list_template (objc_method_template
, size
);
4067 = build_dispatch_table_initializer (objc_method_template
, chain
);
4069 UOBJC_CLASS_METHODS_decl
4070 = generate_dispatch_table (method_list_template
,
4071 ((TREE_CODE (implementation_context
)
4072 == CLASS_IMPLEMENTATION_TYPE
)
4073 ? "_OBJC_CLASS_METHODS"
4074 : "_OBJC_CATEGORY_CLASS_METHODS"),
4076 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
4079 UOBJC_CLASS_METHODS_decl
= 0;
4081 chain
= CLASS_NST_METHODS (implementation_context
);
4084 size
= list_length (chain
);
4086 method_list_template
4087 = build_method_list_template (objc_method_template
, size
);
4089 = build_dispatch_table_initializer (objc_method_template
, chain
);
4091 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
4092 UOBJC_INSTANCE_METHODS_decl
4093 = generate_dispatch_table (method_list_template
,
4094 "_OBJC_INSTANCE_METHODS",
4097 /* We have a category. */
4098 UOBJC_INSTANCE_METHODS_decl
4099 = generate_dispatch_table (method_list_template
,
4100 "_OBJC_CATEGORY_INSTANCE_METHODS",
4102 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
4105 UOBJC_INSTANCE_METHODS_decl
= 0;
4109 generate_protocol_list (i_or_p
)
4112 static tree cast_type
= 0;
4113 tree initlist
, decl_specs
, sc_spec
;
4114 tree refs_decl
, expr_decl
, lproto
, e
, plist
;
4117 if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
4118 || TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4119 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
4120 else if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4121 plist
= PROTOCOL_LIST (i_or_p
);
4129 (build_tree_list (NULL_TREE
,
4130 xref_tag (RECORD_TYPE
,
4131 get_identifier (UTAG_PROTOCOL
))),
4132 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
4135 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4136 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
4137 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
4140 /* Build initializer. */
4141 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), NULL_TREE
);
4143 e
= build_int_2 (size
, 0);
4144 TREE_TYPE (e
) = cast_type
;
4145 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4147 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4149 tree pval
= TREE_VALUE (lproto
);
4151 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
4152 && PROTOCOL_FORWARD_DECL (pval
))
4154 e
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (pval
), 0);
4155 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4159 /* static struct objc_protocol *refs[n]; */
4161 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4162 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
4163 get_identifier (UTAG_PROTOCOL
)),
4166 if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4167 expr_decl
= build_nt (ARRAY_REF
,
4168 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4170 build_int_2 (size
+ 2, 0));
4171 else if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
)
4172 expr_decl
= build_nt (ARRAY_REF
,
4173 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4175 build_int_2 (size
+ 2, 0));
4176 else if (TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4178 = build_nt (ARRAY_REF
,
4179 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4181 build_int_2 (size
+ 2, 0));
4185 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
4187 refs_decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
4189 finish_decl (refs_decl
, build_constructor (TREE_TYPE (refs_decl
),
4190 nreverse (initlist
)),
4197 build_category_initializer (type
, cat_name
, class_name
,
4198 instance_methods
, class_methods
, protocol_list
)
4202 tree instance_methods
;
4206 tree initlist
= NULL_TREE
, expr
;
4208 initlist
= tree_cons (NULL_TREE
, cat_name
, initlist
);
4209 initlist
= tree_cons (NULL_TREE
, class_name
, initlist
);
4211 if (!instance_methods
)
4212 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4215 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
4216 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4219 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4222 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
4223 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4226 /* protocol_list = */
4228 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4231 static tree cast_type2
;
4237 (build_tree_list (NULL_TREE
,
4238 xref_tag (RECORD_TYPE
,
4239 get_identifier (UTAG_PROTOCOL
))),
4240 build1 (INDIRECT_REF
, NULL_TREE
,
4241 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4243 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4244 TREE_TYPE (expr
) = cast_type2
;
4245 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4248 return build_constructor (type
, nreverse (initlist
));
4251 /* struct objc_class {
4252 struct objc_class *isa;
4253 struct objc_class *super_class;
4258 struct objc_ivar_list *ivars;
4259 struct objc_method_list *methods;
4260 if (flag_next_runtime)
4261 struct objc_cache *cache;
4263 struct sarray *dtable;
4264 struct objc_class *subclass_list;
4265 struct objc_class *sibling_class;
4267 struct objc_protocol_list *protocols;
4268 void *gc_object_type;
4272 build_shared_structure_initializer (type
, isa
, super
, name
, size
, status
,
4273 dispatch_table
, ivar_list
, protocol_list
)
4280 tree dispatch_table
;
4284 tree initlist
= NULL_TREE
, expr
;
4287 initlist
= tree_cons (NULL_TREE
, isa
, initlist
);
4290 initlist
= tree_cons (NULL_TREE
, super
, initlist
);
4293 initlist
= tree_cons (NULL_TREE
, default_conversion (name
), initlist
);
4296 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4299 initlist
= tree_cons (NULL_TREE
, build_int_2 (status
, 0), initlist
);
4301 /* instance_size = */
4302 initlist
= tree_cons (NULL_TREE
, size
, initlist
);
4304 /* objc_ivar_list = */
4306 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4309 expr
= build_unary_op (ADDR_EXPR
, ivar_list
, 0);
4310 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4313 /* objc_method_list = */
4314 if (!dispatch_table
)
4315 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4318 expr
= build_unary_op (ADDR_EXPR
, dispatch_table
, 0);
4319 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4322 if (flag_next_runtime
)
4323 /* method_cache = */
4324 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4328 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4330 /* subclass_list = */
4331 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4333 /* sibling_class = */
4334 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4337 /* protocol_list = */
4338 if (! protocol_list
)
4339 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4342 static tree cast_type2
;
4348 (build_tree_list (NULL_TREE
,
4349 xref_tag (RECORD_TYPE
,
4350 get_identifier (UTAG_PROTOCOL
))),
4351 build1 (INDIRECT_REF
, NULL_TREE
,
4352 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4354 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4355 TREE_TYPE (expr
) = cast_type2
;
4356 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4359 /* gc_object_type = NULL */
4360 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4362 return build_constructor (type
, nreverse (initlist
));
4365 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4368 generate_category (cat
)
4371 tree sc_spec
, decl_specs
, decl
;
4372 tree initlist
, cat_name_expr
, class_name_expr
;
4373 tree protocol_decl
, category
;
4375 add_class_reference (CLASS_NAME (cat
));
4376 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
4378 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
4380 category
= CLASS_CATEGORY_LIST (implementation_template
);
4382 /* find the category interface from the class it is associated with */
4385 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
4387 category
= CLASS_CATEGORY_LIST (category
);
4390 if (category
&& CLASS_PROTOCOL_LIST (category
))
4392 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
4393 protocol_decl
= generate_protocol_list (category
);
4398 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4399 decl_specs
= tree_cons (NULL_TREE
, objc_category_template
, sc_spec
);
4401 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4402 implementation_context
),
4403 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
4405 initlist
= build_category_initializer (TREE_TYPE (decl
),
4406 cat_name_expr
, class_name_expr
,
4407 UOBJC_INSTANCE_METHODS_decl
,
4408 UOBJC_CLASS_METHODS_decl
,
4411 TREE_USED (decl
) = 1;
4412 finish_decl (decl
, initlist
, NULL_TREE
);
4415 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4416 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4419 generate_shared_structures ()
4421 tree sc_spec
, decl_specs
, decl
;
4422 tree name_expr
, super_expr
, root_expr
;
4423 tree my_root_id
= NULL_TREE
, my_super_id
= NULL_TREE
;
4424 tree cast_type
, initlist
, protocol_decl
;
4426 my_super_id
= CLASS_SUPER_NAME (implementation_template
);
4429 add_class_reference (my_super_id
);
4431 /* Compute "my_root_id" - this is required for code generation.
4432 the "isa" for all meta class structures points to the root of
4433 the inheritance hierarchy (e.g. "__Object")... */
4434 my_root_id
= my_super_id
;
4437 tree my_root_int
= lookup_interface (my_root_id
);
4439 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
4440 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
4447 /* No super class. */
4448 my_root_id
= CLASS_NAME (implementation_template
);
4451 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
4452 objc_class_template
),
4453 build1 (INDIRECT_REF
,
4454 NULL_TREE
, NULL_TREE
)));
4456 name_expr
= add_objc_string (CLASS_NAME (implementation_template
),
4459 /* Install class `isa' and `super' pointers at runtime. */
4462 super_expr
= add_objc_string (my_super_id
, class_names
);
4463 super_expr
= build_c_cast (cast_type
, super_expr
); /* cast! */
4466 super_expr
= build_int_2 (0, 0);
4468 root_expr
= add_objc_string (my_root_id
, class_names
);
4469 root_expr
= build_c_cast (cast_type
, root_expr
); /* cast! */
4471 if (CLASS_PROTOCOL_LIST (implementation_template
))
4473 generate_protocol_references
4474 (CLASS_PROTOCOL_LIST (implementation_template
));
4475 protocol_decl
= generate_protocol_list (implementation_template
);
4480 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4482 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
4483 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
4485 decl
= start_decl (DECL_NAME (UOBJC_METACLASS_decl
), decl_specs
, 1,
4486 NULL_TREE
, NULL_TREE
);
4489 = build_shared_structure_initializer
4491 root_expr
, super_expr
, name_expr
,
4492 build_int_2 ((TREE_INT_CST_LOW (TYPE_SIZE (objc_class_template
))
4496 UOBJC_CLASS_METHODS_decl
,
4497 UOBJC_CLASS_VARIABLES_decl
,
4500 finish_decl (decl
, initlist
, NULL_TREE
);
4502 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4504 decl
= start_decl (DECL_NAME (UOBJC_CLASS_decl
), decl_specs
, 1,
4505 NULL_TREE
, NULL_TREE
);
4508 = build_shared_structure_initializer
4510 build_unary_op (ADDR_EXPR
, UOBJC_METACLASS_decl
, 0),
4511 super_expr
, name_expr
,
4514 (TYPE_SIZE (CLASS_STATIC_TEMPLATE (implementation_template
)))
4518 UOBJC_INSTANCE_METHODS_decl
,
4519 UOBJC_INSTANCE_VARIABLES_decl
,
4522 finish_decl (decl
, initlist
, NULL_TREE
);
4526 synth_id_with_class_suffix (preamble
, ctxt
)
4527 const char *preamble
;
4531 if (TREE_CODE (ctxt
) == CLASS_IMPLEMENTATION_TYPE
4532 || TREE_CODE (ctxt
) == CLASS_INTERFACE_TYPE
)
4534 const char *class_name
4535 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
4536 string
= (char *) alloca (strlen (preamble
) + strlen (class_name
) + 3);
4537 sprintf (string
, "%s_%s", preamble
,
4538 IDENTIFIER_POINTER (CLASS_NAME (ctxt
)));
4540 else if (TREE_CODE (ctxt
) == CATEGORY_IMPLEMENTATION_TYPE
4541 || TREE_CODE (ctxt
) == CATEGORY_INTERFACE_TYPE
)
4543 /* We have a category. */
4544 const char *class_name
4545 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
4546 const char *class_super_name
4547 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
));
4548 string
= (char *) alloca (strlen (preamble
)
4549 + strlen (class_name
)
4550 + strlen (class_super_name
)
4552 sprintf (string
, "%s_%s_%s", preamble
, class_name
, class_super_name
);
4554 else if (TREE_CODE (ctxt
) == PROTOCOL_INTERFACE_TYPE
)
4556 const char *protocol_name
= IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt
));
4558 = (char *) alloca (strlen (preamble
) + strlen (protocol_name
) + 3);
4559 sprintf (string
, "%s_%s", preamble
, protocol_name
);
4564 return get_identifier (string
);
4568 is_objc_type_qualifier (node
)
4571 return (TREE_CODE (node
) == IDENTIFIER_NODE
4572 && (node
== ridpointers
[(int) RID_CONST
]
4573 || node
== ridpointers
[(int) RID_VOLATILE
]
4574 || node
== ridpointers
[(int) RID_IN
]
4575 || node
== ridpointers
[(int) RID_OUT
]
4576 || node
== ridpointers
[(int) RID_INOUT
]
4577 || node
== ridpointers
[(int) RID_BYCOPY
]
4578 || node
== ridpointers
[(int) RID_BYREF
]
4579 || node
== ridpointers
[(int) RID_ONEWAY
]));
4582 /* If type is empty or only type qualifiers are present, add default
4583 type of id (otherwise grokdeclarator will default to int). */
4586 adjust_type_for_id_default (type
)
4589 tree declspecs
, chain
;
4592 return build_tree_list (build_tree_list (NULL_TREE
, objc_object_reference
),
4593 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4595 declspecs
= TREE_PURPOSE (type
);
4597 /* Determine if a typespec is present. */
4598 for (chain
= declspecs
;
4600 chain
= TREE_CHAIN (chain
))
4602 if (!is_objc_type_qualifier (TREE_VALUE (chain
)))
4606 return build_tree_list (tree_cons (NULL_TREE
, objc_object_reference
,
4608 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4613 selector ':' '(' typename ')' identifier
4616 Transform an Objective-C keyword argument into
4617 the C equivalent parameter declarator.
4619 In: key_name, an "identifier_node" (optional).
4620 arg_type, a "tree_list" (optional).
4621 arg_name, an "identifier_node".
4623 Note: It would be really nice to strongly type the preceding
4624 arguments in the function prototype; however, then I
4625 could not use the "accessor" macros defined in "tree.h".
4627 Out: an instance of "keyword_decl". */
4630 build_keyword_decl (key_name
, arg_type
, arg_name
)
4637 /* If no type is specified, default to "id". */
4638 arg_type
= adjust_type_for_id_default (arg_type
);
4640 keyword_decl
= make_node (KEYWORD_DECL
);
4642 TREE_TYPE (keyword_decl
) = arg_type
;
4643 KEYWORD_ARG_NAME (keyword_decl
) = arg_name
;
4644 KEYWORD_KEY_NAME (keyword_decl
) = key_name
;
4646 return keyword_decl
;
4649 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4652 build_keyword_selector (selector
)
4656 tree key_chain
, key_name
;
4659 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4661 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4662 key_name
= KEYWORD_KEY_NAME (key_chain
);
4663 else if (TREE_CODE (selector
) == TREE_LIST
)
4664 key_name
= TREE_PURPOSE (key_chain
);
4669 len
+= IDENTIFIER_LENGTH (key_name
) + 1;
4671 /* Just a ':' arg. */
4675 buf
= (char *)alloca (len
+ 1);
4676 bzero (buf
, len
+ 1);
4678 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4680 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4681 key_name
= KEYWORD_KEY_NAME (key_chain
);
4682 else if (TREE_CODE (selector
) == TREE_LIST
)
4683 key_name
= TREE_PURPOSE (key_chain
);
4688 strcat (buf
, IDENTIFIER_POINTER (key_name
));
4692 return get_identifier (buf
);
4695 /* Used for declarations and definitions. */
4698 build_method_decl (code
, ret_type
, selector
, add_args
)
4699 enum tree_code code
;
4706 /* If no type is specified, default to "id". */
4707 ret_type
= adjust_type_for_id_default (ret_type
);
4709 method_decl
= make_node (code
);
4710 TREE_TYPE (method_decl
) = ret_type
;
4712 /* If we have a keyword selector, create an identifier_node that
4713 represents the full selector name (`:' included)... */
4714 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4716 METHOD_SEL_NAME (method_decl
) = build_keyword_selector (selector
);
4717 METHOD_SEL_ARGS (method_decl
) = selector
;
4718 METHOD_ADD_ARGS (method_decl
) = add_args
;
4722 METHOD_SEL_NAME (method_decl
) = selector
;
4723 METHOD_SEL_ARGS (method_decl
) = NULL_TREE
;
4724 METHOD_ADD_ARGS (method_decl
) = NULL_TREE
;
4730 #define METHOD_DEF 0
4731 #define METHOD_REF 1
4733 /* Used by `build_message_expr' and `comp_method_types'. Return an
4734 argument list for method METH. CONTEXT is either METHOD_DEF or
4735 METHOD_REF, saying whether we are trying to define a method or call
4736 one. SUPERFLAG says this is for a send to super; this makes a
4737 difference for the NeXT calling sequence in which the lookup and
4738 the method call are done together. */
4741 get_arg_type_list (meth
, context
, superflag
)
4748 /* Receiver type. */
4749 if (flag_next_runtime
&& superflag
)
4750 arglist
= build_tree_list (NULL_TREE
, super_type
);
4751 else if (context
== METHOD_DEF
)
4752 arglist
= build_tree_list (NULL_TREE
, TREE_TYPE (self_decl
));
4754 arglist
= build_tree_list (NULL_TREE
, id_type
);
4756 /* Selector type - will eventually change to `int'. */
4757 chainon (arglist
, build_tree_list (NULL_TREE
, selector_type
));
4759 /* Build a list of argument types. */
4760 for (akey
= METHOD_SEL_ARGS (meth
); akey
; akey
= TREE_CHAIN (akey
))
4762 tree arg_decl
= groktypename_in_parm_context (TREE_TYPE (akey
));
4763 chainon (arglist
, build_tree_list (NULL_TREE
, TREE_TYPE (arg_decl
)));
4766 if (METHOD_ADD_ARGS (meth
) == (tree
)1)
4767 /* We have a `, ...' immediately following the selector,
4768 finalize the arglist...simulate get_parm_info (0). */
4770 else if (METHOD_ADD_ARGS (meth
))
4772 /* we have a variable length selector */
4773 tree add_arg_list
= TREE_CHAIN (METHOD_ADD_ARGS (meth
));
4774 chainon (arglist
, add_arg_list
);
4777 /* finalize the arglist...simulate get_parm_info (1) */
4778 chainon (arglist
, build_tree_list (NULL_TREE
, void_type_node
));
4784 check_duplicates (hsh
)
4787 tree meth
= NULL_TREE
;
4795 /* We have two methods with the same name and different types. */
4797 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
) ? '-' : '+';
4799 warning ("multiple declarations for method `%s'",
4800 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
4802 warn_with_method ("using", type
, meth
);
4803 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
4804 warn_with_method ("also found", type
, loop
->value
);
4810 /* If RECEIVER is a class reference, return the identifier node for the
4811 referenced class. RECEIVER is created by get_class_reference, so we
4812 check the exact form created depending on which runtimes are used. */
4815 receiver_is_class_object (receiver
)
4818 tree chain
, exp
, arg
;
4819 if (flag_next_runtime
)
4821 /* The receiver is a variable created by build_class_reference_decl. */
4822 if (TREE_CODE (receiver
) == VAR_DECL
4823 && TREE_TYPE (receiver
) == objc_class_type
)
4824 /* Look up the identifier. */
4825 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
4826 if (TREE_PURPOSE (chain
) == receiver
)
4827 return TREE_VALUE (chain
);
4831 /* The receiver is a function call that returns an id. Check if
4832 it is a call to objc_getClass, if so, pick up the class name. */
4833 if ((exp
= TREE_OPERAND (receiver
, 0))
4834 && TREE_CODE (exp
) == ADDR_EXPR
4835 && (exp
= TREE_OPERAND (exp
, 0))
4836 && TREE_CODE (exp
) == FUNCTION_DECL
4837 && exp
== objc_get_class_decl
4838 /* we have a call to objc_getClass! */
4839 && (arg
= TREE_OPERAND (receiver
, 1))
4840 && TREE_CODE (arg
) == TREE_LIST
4841 && (arg
= TREE_VALUE (arg
)))
4844 if (TREE_CODE (arg
) == ADDR_EXPR
4845 && (arg
= TREE_OPERAND (arg
, 0))
4846 && TREE_CODE (arg
) == STRING_CST
)
4847 /* Finally, we have the class name. */
4848 return get_identifier (TREE_STRING_POINTER (arg
));
4854 /* If we are currently building a message expr, this holds
4855 the identifier of the selector of the message. This is
4856 used when printing warnings about argument mismatches. */
4858 static tree building_objc_message_expr
= 0;
4861 maybe_building_objc_message_expr ()
4863 return building_objc_message_expr
;
4866 /* Construct an expression for sending a message.
4867 MESS has the object to send to in TREE_PURPOSE
4868 and the argument list (including selector) in TREE_VALUE.
4870 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4871 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4874 build_message_expr (mess
)
4877 tree receiver
= TREE_PURPOSE (mess
);
4878 tree selector
, self_object
;
4879 tree rtype
, sel_name
;
4880 tree args
= TREE_VALUE (mess
);
4881 tree method_params
= NULL_TREE
;
4882 tree method_prototype
= NULL_TREE
;
4884 int statically_typed
= 0, statically_allocated
= 0;
4885 tree class_ident
= 0;
4887 /* 1 if this is sending to the superclass. */
4890 if (!doing_objc_thang
)
4893 if (TREE_CODE (receiver
) == ERROR_MARK
)
4894 return error_mark_node
;
4896 /* Determine receiver type. */
4897 rtype
= TREE_TYPE (receiver
);
4898 super
= IS_SUPER (rtype
);
4902 if (TREE_STATIC_TEMPLATE (rtype
))
4903 statically_allocated
= 1;
4904 else if (TREE_CODE (rtype
) == POINTER_TYPE
4905 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype
)))
4906 statically_typed
= 1;
4907 else if ((flag_next_runtime
4908 || (TREE_CODE (receiver
) == CALL_EXPR
&& IS_ID (rtype
)))
4909 && (class_ident
= receiver_is_class_object (receiver
)))
4911 else if (! IS_ID (rtype
)
4912 /* Allow any type that matches objc_class_type. */
4913 && ! comptypes (rtype
, objc_class_type
))
4915 bzero (errbuf
, BUFSIZE
);
4916 warning ("invalid receiver type `%s'",
4917 gen_declaration (rtype
, errbuf
));
4920 if (statically_allocated
)
4921 receiver
= build_unary_op (ADDR_EXPR
, receiver
, 0);
4923 /* Don't evaluate the receiver twice. */
4924 receiver
= save_expr (receiver
);
4925 self_object
= receiver
;
4928 /* If sending to `super', use current self as the object. */
4929 self_object
= self_decl
;
4931 /* Obtain the full selector name. */
4933 if (TREE_CODE (args
) == IDENTIFIER_NODE
)
4934 /* A unary selector. */
4936 else if (TREE_CODE (args
) == TREE_LIST
)
4937 sel_name
= build_keyword_selector (args
);
4941 /* Build the parameter list to give to the method. */
4943 method_params
= NULL_TREE
;
4944 if (TREE_CODE (args
) == TREE_LIST
)
4946 tree chain
= args
, prev
= NULL_TREE
;
4948 /* We have a keyword selector--check for comma expressions. */
4951 tree element
= TREE_VALUE (chain
);
4953 /* We have a comma expression, must collapse... */
4954 if (TREE_CODE (element
) == TREE_LIST
)
4957 TREE_CHAIN (prev
) = element
;
4962 chain
= TREE_CHAIN (chain
);
4964 method_params
= args
;
4967 /* Determine operation return type. */
4969 if (IS_SUPER (rtype
))
4973 if (CLASS_SUPER_NAME (implementation_template
))
4976 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
4978 if (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
)
4979 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4981 method_prototype
= lookup_class_method_static (iface
, sel_name
);
4983 if (iface
&& !method_prototype
)
4984 warning ("`%s' does not respond to `%s'",
4985 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template
)),
4986 IDENTIFIER_POINTER (sel_name
));
4990 error ("no super class declared in interface for `%s'",
4991 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
4992 return error_mark_node
;
4996 else if (statically_allocated
)
4998 tree ctype
= TREE_TYPE (rtype
);
4999 tree iface
= lookup_interface (TYPE_NAME (rtype
));
5002 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5004 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
5006 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
5009 if (!method_prototype
)
5010 warning ("`%s' does not respond to `%s'",
5011 IDENTIFIER_POINTER (TYPE_NAME (rtype
)),
5012 IDENTIFIER_POINTER (sel_name
));
5014 else if (statically_typed
)
5016 tree ctype
= TREE_TYPE (rtype
);
5018 /* `self' is now statically_typed. All methods should be visible
5019 within the context of the implementation. */
5020 if (implementation_context
5021 && CLASS_NAME (implementation_context
) == TYPE_NAME (ctype
))
5024 = lookup_instance_method_static (implementation_template
,
5027 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
5029 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
5032 if (! method_prototype
5033 && implementation_template
!= implementation_context
)
5034 /* The method is not published in the interface. Check
5037 = lookup_method (CLASS_NST_METHODS (implementation_context
),
5044 if ((iface
= lookup_interface (TYPE_NAME (ctype
))))
5045 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5047 if (! method_prototype
)
5049 tree protocol_list
= TYPE_PROTOCOL_LIST (ctype
);
5052 = lookup_method_in_protocol_list (protocol_list
,
5057 if (!method_prototype
)
5058 warning ("`%s' does not respond to `%s'",
5059 IDENTIFIER_POINTER (TYPE_NAME (ctype
)),
5060 IDENTIFIER_POINTER (sel_name
));
5062 else if (class_ident
)
5064 if (implementation_context
5065 && CLASS_NAME (implementation_context
) == class_ident
)
5068 = lookup_class_method_static (implementation_template
, sel_name
);
5070 if (!method_prototype
5071 && implementation_template
!= implementation_context
)
5072 /* The method is not published in the interface. Check
5075 = lookup_method (CLASS_CLS_METHODS (implementation_context
),
5082 if ((iface
= lookup_interface (class_ident
)))
5083 method_prototype
= lookup_class_method_static (iface
, sel_name
);
5086 if (!method_prototype
)
5088 warning ("cannot find class (factory) method.");
5089 warning ("return type for `%s' defaults to id",
5090 IDENTIFIER_POINTER (sel_name
));
5093 else if (IS_PROTOCOL_QUALIFIED_ID (rtype
))
5095 /* An anonymous object that has been qualified with a protocol. */
5097 tree protocol_list
= TYPE_PROTOCOL_LIST (rtype
);
5099 method_prototype
= lookup_method_in_protocol_list (protocol_list
,
5102 if (!method_prototype
)
5106 warning ("method `%s' not implemented by protocol.",
5107 IDENTIFIER_POINTER (sel_name
));
5109 /* Try and find the method signature in the global pools. */
5111 if (!(hsh
= hash_lookup (nst_method_hash_list
, sel_name
)))
5112 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5114 if (!(method_prototype
= check_duplicates (hsh
)))
5115 warning ("return type defaults to id");
5122 /* We think we have an instance...loophole: extern id Object; */
5123 hsh
= hash_lookup (nst_method_hash_list
, sel_name
);
5125 /* For various loopholes, like sending messages to self in a
5127 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5129 method_prototype
= check_duplicates (hsh
);
5130 if (!method_prototype
)
5132 warning ("cannot find method.");
5133 warning ("return type for `%s' defaults to id",
5134 IDENTIFIER_POINTER (sel_name
));
5138 /* Save the selector name for printing error messages. */
5139 building_objc_message_expr
= sel_name
;
5141 /* Build the parameters list for looking up the method.
5142 These are the object itself and the selector. */
5144 if (flag_typed_selectors
)
5145 selector
= build_typed_selector_reference (sel_name
, method_prototype
);
5147 selector
= build_selector_reference (sel_name
);
5149 retval
= build_objc_method_call (super
, method_prototype
,
5150 receiver
, self_object
,
5151 selector
, method_params
);
5153 building_objc_message_expr
= 0;
5158 /* Build a tree expression to send OBJECT the operation SELECTOR,
5159 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5160 assuming the method has prototype METHOD_PROTOTYPE.
5161 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5162 Use METHOD_PARAMS as list of args to pass to the method.
5163 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5166 build_objc_method_call (super_flag
, method_prototype
, lookup_object
, object
,
5167 selector
, method_params
)
5169 tree method_prototype
, lookup_object
, object
, selector
, method_params
;
5171 tree sender
= (super_flag
? umsg_super_decl
: umsg_decl
);
5172 tree rcv_p
= (super_flag
5173 ? build_pointer_type (xref_tag (RECORD_TYPE
,
5174 get_identifier (TAG_SUPER
)))
5177 if (flag_next_runtime
)
5179 if (! method_prototype
)
5181 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5182 tree_cons (NULL_TREE
, selector
,
5184 assemble_external (sender
);
5185 return build_function_call (sender
, method_params
);
5189 /* This is a real kludge, but it is used only for the Next.
5190 Clobber the data type of SENDER temporarily to accept
5191 all the arguments for this operation, and to return
5192 whatever this operation returns. */
5193 tree arglist
= NULL_TREE
;
5196 /* Save the proper contents of SENDER's data type. */
5197 tree savarg
= TYPE_ARG_TYPES (TREE_TYPE (sender
));
5198 tree savret
= TREE_TYPE (TREE_TYPE (sender
));
5200 /* Install this method's argument types. */
5201 arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5203 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = arglist
;
5205 /* Install this method's return type. */
5206 TREE_TYPE (TREE_TYPE (sender
))
5207 = groktypename (TREE_TYPE (method_prototype
));
5209 /* Call SENDER with all the parameters. This will do type
5210 checking using the arg types for this method. */
5211 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5212 tree_cons (NULL_TREE
, selector
,
5214 assemble_external (sender
);
5215 retval
= build_function_call (sender
, method_params
);
5217 /* Restore SENDER's return/argument types. */
5218 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = savarg
;
5219 TREE_TYPE (TREE_TYPE (sender
)) = savret
;
5225 /* This is the portable way.
5226 First call the lookup function to get a pointer to the method,
5227 then cast the pointer, then call it with the method arguments. */
5230 /* Avoid trouble since we may evaluate each of these twice. */
5231 object
= save_expr (object
);
5232 selector
= save_expr (selector
);
5234 lookup_object
= build_c_cast (rcv_p
, lookup_object
);
5236 assemble_external (sender
);
5238 = build_function_call (sender
,
5239 tree_cons (NULL_TREE
, lookup_object
,
5240 tree_cons (NULL_TREE
, selector
,
5243 /* If we have a method prototype, construct the data type this
5244 method needs, and cast what we got from SENDER into a pointer
5246 if (method_prototype
)
5248 tree arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5250 tree valtype
= groktypename (TREE_TYPE (method_prototype
));
5251 tree fake_function_type
= build_function_type (valtype
, arglist
);
5252 TREE_TYPE (method
) = build_pointer_type (fake_function_type
);
5256 = build_pointer_type (build_function_type (ptr_type_node
, NULL_TREE
));
5258 /* Pass the object to the method. */
5259 assemble_external (method
);
5260 return build_function_call (method
,
5261 tree_cons (NULL_TREE
, object
,
5262 tree_cons (NULL_TREE
, selector
,
5268 build_protocol_reference (p
)
5271 tree decl
, ident
, ptype
;
5273 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5275 ident
= synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
);
5277 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
5278 objc_protocol_template
),
5281 if (IDENTIFIER_GLOBAL_VALUE (ident
))
5282 decl
= IDENTIFIER_GLOBAL_VALUE (ident
); /* Set by pushdecl. */
5285 decl
= build_decl (VAR_DECL
, ident
, ptype
);
5286 DECL_EXTERNAL (decl
) = 1;
5287 TREE_PUBLIC (decl
) = 1;
5288 TREE_USED (decl
) = 1;
5289 DECL_ARTIFICIAL (decl
) = 1;
5291 make_decl_rtl (decl
, 0, 1);
5292 pushdecl_top_level (decl
);
5295 PROTOCOL_FORWARD_DECL (p
) = decl
;
5299 build_protocol_expr (protoname
)
5305 if (!doing_objc_thang
)
5308 p
= lookup_protocol (protoname
);
5312 error ("Cannot find protocol declaration for `%s'",
5313 IDENTIFIER_POINTER (protoname
));
5314 return error_mark_node
;
5317 if (!PROTOCOL_FORWARD_DECL (p
))
5318 build_protocol_reference (p
);
5320 expr
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
5322 TREE_TYPE (expr
) = protocol_type
;
5328 build_selector_expr (selnamelist
)
5333 if (!doing_objc_thang
)
5336 /* Obtain the full selector name. */
5337 if (TREE_CODE (selnamelist
) == IDENTIFIER_NODE
)
5338 /* A unary selector. */
5339 selname
= selnamelist
;
5340 else if (TREE_CODE (selnamelist
) == TREE_LIST
)
5341 selname
= build_keyword_selector (selnamelist
);
5345 if (flag_typed_selectors
)
5346 return build_typed_selector_reference (selname
, 0);
5348 return build_selector_reference (selname
);
5352 build_encode_expr (type
)
5358 if (!doing_objc_thang
)
5361 encode_type (type
, obstack_object_size (&util_obstack
),
5362 OBJC_ENCODE_INLINE_DEFS
);
5363 obstack_1grow (&util_obstack
, 0); /* null terminate string */
5364 string
= obstack_finish (&util_obstack
);
5366 /* Synthesize a string that represents the encoded struct/union. */
5367 result
= my_build_string (strlen (string
) + 1, string
);
5368 obstack_free (&util_obstack
, util_firstobj
);
5373 build_ivar_reference (id
)
5376 if (TREE_CODE (method_context
) == CLASS_METHOD_DECL
)
5378 /* Historically, a class method that produced objects (factory
5379 method) would assign `self' to the instance that it
5380 allocated. This would effectively turn the class method into
5381 an instance method. Following this assignment, the instance
5382 variables could be accessed. That practice, while safe,
5383 violates the simple rule that a class method should not refer
5384 to an instance variable. It's better to catch the cases
5385 where this is done unknowingly than to support the above
5387 warning ("instance variable `%s' accessed in class method",
5388 IDENTIFIER_POINTER (id
));
5389 TREE_TYPE (self_decl
) = instance_type
; /* cast */
5392 return build_component_ref (build_indirect_ref (self_decl
, "->"), id
);
5395 #define HASH_ALLOC_LIST_SIZE 170
5396 #define ATTR_ALLOC_LIST_SIZE 170
5397 #define SIZEHASHTABLE 257
5400 #define HASHFUNCTION(key) ((HOST_WIDE_INT) key & 0x7fffffff)
5405 nst_method_hash_list
= (hash
*)xmalloc (SIZEHASHTABLE
* sizeof (hash
));
5406 cls_method_hash_list
= (hash
*)xmalloc (SIZEHASHTABLE
* sizeof (hash
));
5408 if (!nst_method_hash_list
|| !cls_method_hash_list
)
5409 perror ("unable to allocate space in objc-tree.c");
5414 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
5416 nst_method_hash_list
[i
] = 0;
5417 cls_method_hash_list
[i
] = 0;
5423 hash_enter (hashlist
, method
)
5427 static hash hash_alloc_list
= 0;
5428 static int hash_alloc_index
= 0;
5430 int slot
= HASHFUNCTION (METHOD_SEL_NAME (method
)) % SIZEHASHTABLE
;
5432 if (! hash_alloc_list
|| hash_alloc_index
>= HASH_ALLOC_LIST_SIZE
)
5434 hash_alloc_index
= 0;
5435 hash_alloc_list
= (hash
) xmalloc (sizeof (struct hashed_entry
)
5436 * HASH_ALLOC_LIST_SIZE
);
5437 if (! hash_alloc_list
)
5438 perror ("unable to allocate in objc-tree.c");
5440 obj
= &hash_alloc_list
[hash_alloc_index
++];
5442 obj
->next
= hashlist
[slot
];
5445 hashlist
[slot
] = obj
; /* append to front */
5449 hash_lookup (hashlist
, sel_name
)
5455 target
= hashlist
[HASHFUNCTION (sel_name
) % SIZEHASHTABLE
];
5459 if (sel_name
== METHOD_SEL_NAME (target
->key
))
5462 target
= target
->next
;
5468 hash_add_attr (entry
, value
)
5472 static attr attr_alloc_list
= 0;
5473 static int attr_alloc_index
= 0;
5476 if (! attr_alloc_list
|| attr_alloc_index
>= ATTR_ALLOC_LIST_SIZE
)
5478 attr_alloc_index
= 0;
5479 attr_alloc_list
= (attr
) xmalloc (sizeof (struct hashed_attribute
)
5480 * ATTR_ALLOC_LIST_SIZE
);
5481 if (! attr_alloc_list
)
5482 perror ("unable to allocate in objc-tree.c");
5484 obj
= &attr_alloc_list
[attr_alloc_index
++];
5485 obj
->next
= entry
->list
;
5488 entry
->list
= obj
; /* append to front */
5492 lookup_method (mchain
, method
)
5498 if (TREE_CODE (method
) == IDENTIFIER_NODE
)
5501 key
= METHOD_SEL_NAME (method
);
5505 if (METHOD_SEL_NAME (mchain
) == key
)
5507 mchain
= TREE_CHAIN (mchain
);
5513 lookup_instance_method_static (interface
, ident
)
5517 tree inter
= interface
;
5518 tree chain
= CLASS_NST_METHODS (inter
);
5519 tree meth
= NULL_TREE
;
5523 if ((meth
= lookup_method (chain
, ident
)))
5526 if (CLASS_CATEGORY_LIST (inter
))
5528 tree category
= CLASS_CATEGORY_LIST (inter
);
5529 chain
= CLASS_NST_METHODS (category
);
5533 if ((meth
= lookup_method (chain
, ident
)))
5536 /* Check for instance methods in protocols in categories. */
5537 if (CLASS_PROTOCOL_LIST (category
))
5539 if ((meth
= (lookup_method_in_protocol_list
5540 (CLASS_PROTOCOL_LIST (category
), ident
, 0))))
5544 if ((category
= CLASS_CATEGORY_LIST (category
)))
5545 chain
= CLASS_NST_METHODS (category
);
5550 if (CLASS_PROTOCOL_LIST (inter
))
5552 if ((meth
= (lookup_method_in_protocol_list
5553 (CLASS_PROTOCOL_LIST (inter
), ident
, 0))))
5557 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5558 chain
= CLASS_NST_METHODS (inter
);
5566 lookup_class_method_static (interface
, ident
)
5570 tree inter
= interface
;
5571 tree chain
= CLASS_CLS_METHODS (inter
);
5572 tree meth
= NULL_TREE
;
5573 tree root_inter
= NULL_TREE
;
5577 if ((meth
= lookup_method (chain
, ident
)))
5580 if (CLASS_CATEGORY_LIST (inter
))
5582 tree category
= CLASS_CATEGORY_LIST (inter
);
5583 chain
= CLASS_CLS_METHODS (category
);
5587 if ((meth
= lookup_method (chain
, ident
)))
5590 /* Check for class methods in protocols in categories. */
5591 if (CLASS_PROTOCOL_LIST (category
))
5593 if ((meth
= (lookup_method_in_protocol_list
5594 (CLASS_PROTOCOL_LIST (category
), ident
, 1))))
5598 if ((category
= CLASS_CATEGORY_LIST (category
)))
5599 chain
= CLASS_CLS_METHODS (category
);
5604 /* Check for class methods in protocols. */
5605 if (CLASS_PROTOCOL_LIST (inter
))
5607 if ((meth
= (lookup_method_in_protocol_list
5608 (CLASS_PROTOCOL_LIST (inter
), ident
, 1))))
5613 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5614 chain
= CLASS_CLS_METHODS (inter
);
5618 /* Simulate wrap around. */
5619 return lookup_instance_method_static (root_inter
, ident
);
5623 add_class_method (class, method
)
5630 if (!(mth
= lookup_method (CLASS_CLS_METHODS (class), method
)))
5632 /* put method on list in reverse order */
5633 TREE_CHAIN (method
) = CLASS_CLS_METHODS (class);
5634 CLASS_CLS_METHODS (class) = method
;
5638 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5639 error ("duplicate definition of class method `%s'.",
5640 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5643 /* Check types; if different, complain. */
5644 if (!comp_proto_with_proto (method
, mth
))
5645 error ("duplicate declaration of class method `%s'.",
5646 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5650 if (!(hsh
= hash_lookup (cls_method_hash_list
, METHOD_SEL_NAME (method
))))
5652 /* Install on a global chain. */
5653 hash_enter (cls_method_hash_list
, method
);
5657 /* Check types; if different, add to a list. */
5658 if (!comp_proto_with_proto (method
, hsh
->key
))
5659 hash_add_attr (hsh
, method
);
5665 add_instance_method (class, method
)
5672 if (!(mth
= lookup_method (CLASS_NST_METHODS (class), method
)))
5674 /* Put method on list in reverse order. */
5675 TREE_CHAIN (method
) = CLASS_NST_METHODS (class);
5676 CLASS_NST_METHODS (class) = method
;
5680 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5681 error ("duplicate definition of instance method `%s'.",
5682 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5685 /* Check types; if different, complain. */
5686 if (!comp_proto_with_proto (method
, mth
))
5687 error ("duplicate declaration of instance method `%s'.",
5688 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5692 if (!(hsh
= hash_lookup (nst_method_hash_list
, METHOD_SEL_NAME (method
))))
5694 /* Install on a global chain. */
5695 hash_enter (nst_method_hash_list
, method
);
5699 /* Check types; if different, add to a list. */
5700 if (!comp_proto_with_proto (method
, hsh
->key
))
5701 hash_add_attr (hsh
, method
);
5710 /* Put interfaces on list in reverse order. */
5711 TREE_CHAIN (class) = interface_chain
;
5712 interface_chain
= class;
5713 return interface_chain
;
5717 add_category (class, category
)
5721 /* Put categories on list in reverse order. */
5722 tree cat
= CLASS_CATEGORY_LIST (class);
5726 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
5727 warning ("duplicate interface declaration for category `%s(%s)'",
5728 IDENTIFIER_POINTER (CLASS_NAME (class)),
5729 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category
)));
5730 cat
= CLASS_CATEGORY_LIST (cat
);
5733 CLASS_CATEGORY_LIST (category
) = CLASS_CATEGORY_LIST (class);
5734 CLASS_CATEGORY_LIST (class) = category
;
5737 /* Called after parsing each instance variable declaration. Necessary to
5738 preserve typedefs and implement public/private...
5740 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5743 add_instance_variable (class, public, declarator
, declspecs
, width
)
5750 tree field_decl
, raw_decl
;
5752 raw_decl
= build_tree_list (declspecs
, declarator
);
5754 if (CLASS_RAW_IVARS (class))
5755 chainon (CLASS_RAW_IVARS (class), raw_decl
);
5757 CLASS_RAW_IVARS (class) = raw_decl
;
5759 field_decl
= grokfield (input_filename
, lineno
,
5760 declarator
, declspecs
, width
);
5762 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5766 TREE_PUBLIC (field_decl
) = 0;
5767 TREE_PRIVATE (field_decl
) = 0;
5768 TREE_PROTECTED (field_decl
) = 1;
5772 TREE_PUBLIC (field_decl
) = 1;
5773 TREE_PRIVATE (field_decl
) = 0;
5774 TREE_PROTECTED (field_decl
) = 0;
5778 TREE_PUBLIC (field_decl
) = 0;
5779 TREE_PRIVATE (field_decl
) = 1;
5780 TREE_PROTECTED (field_decl
) = 0;
5785 if (CLASS_IVARS (class))
5786 chainon (CLASS_IVARS (class), field_decl
);
5788 CLASS_IVARS (class) = field_decl
;
5794 is_ivar (decl_chain
, ident
)
5798 for ( ; decl_chain
; decl_chain
= TREE_CHAIN (decl_chain
))
5799 if (DECL_NAME (decl_chain
) == ident
)
5804 /* True if the ivar is private and we are not in its implementation. */
5810 if (TREE_PRIVATE (decl
)
5811 && ! is_ivar (CLASS_IVARS (implementation_template
), DECL_NAME (decl
)))
5813 error ("instance variable `%s' is declared private",
5814 IDENTIFIER_POINTER (DECL_NAME (decl
)));
5821 /* We have an instance variable reference;, check to see if it is public. */
5824 is_public (expr
, identifier
)
5828 tree basetype
= TREE_TYPE (expr
);
5829 enum tree_code code
= TREE_CODE (basetype
);
5832 if (code
== RECORD_TYPE
)
5834 if (TREE_STATIC_TEMPLATE (basetype
))
5836 if (!lookup_interface (TYPE_NAME (basetype
)))
5838 error ("Cannot find interface declaration for `%s'",
5839 IDENTIFIER_POINTER (TYPE_NAME (basetype
)));
5843 if ((decl
= is_ivar (TYPE_FIELDS (basetype
), identifier
)))
5845 if (TREE_PUBLIC (decl
))
5848 /* Important difference between the Stepstone translator:
5849 all instance variables should be public within the context
5850 of the implementation. */
5851 if (implementation_context
5852 && (((TREE_CODE (implementation_context
)
5853 == CLASS_IMPLEMENTATION_TYPE
)
5854 || (TREE_CODE (implementation_context
)
5855 == CATEGORY_IMPLEMENTATION_TYPE
))
5856 && (CLASS_NAME (implementation_context
)
5857 == TYPE_NAME (basetype
))))
5858 return ! is_private (decl
);
5860 error ("instance variable `%s' is declared %s",
5861 IDENTIFIER_POINTER (identifier
),
5862 TREE_PRIVATE (decl
) ? "private" : "protected");
5867 else if (implementation_context
&& (basetype
== objc_object_reference
))
5869 TREE_TYPE (expr
) = uprivate_record
;
5870 warning ("static access to object of type `id'");
5877 /* Implement @defs (<classname>) within struct bodies. */
5880 get_class_ivars (interface
)
5883 if (!doing_objc_thang
)
5886 return build_ivar_chain (interface
, 1);
5889 /* Make sure all entries in CHAIN are also in LIST. */
5892 check_methods (chain
, list
, mtype
)
5901 if (!lookup_method (list
, chain
))
5905 if (TREE_CODE (implementation_context
)
5906 == CLASS_IMPLEMENTATION_TYPE
)
5907 warning ("incomplete implementation of class `%s'",
5908 IDENTIFIER_POINTER (CLASS_NAME (implementation_context
)));
5909 else if (TREE_CODE (implementation_context
)
5910 == CATEGORY_IMPLEMENTATION_TYPE
)
5911 warning ("incomplete implementation of category `%s'",
5912 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
5916 warning ("method definition for `%c%s' not found",
5917 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
5920 chain
= TREE_CHAIN (chain
);
5927 conforms_to_protocol (class, protocol
)
5933 tree p
= CLASS_PROTOCOL_LIST (class);
5935 while (p
&& TREE_VALUE (p
) != TREE_VALUE (protocol
))
5940 tree super
= (CLASS_SUPER_NAME (class)
5941 ? lookup_interface (CLASS_SUPER_NAME (class))
5943 int tmp
= super
? conforms_to_protocol (super
, protocol
) : 0;
5948 protocol
= TREE_CHAIN (protocol
);
5954 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5955 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5958 check_methods_accessible (chain
, context
, mtype
)
5965 tree base_context
= context
;
5969 context
= base_context
;
5973 list
= CLASS_CLS_METHODS (context
);
5975 list
= CLASS_NST_METHODS (context
);
5977 if (lookup_method (list
, chain
))
5980 else if (TREE_CODE (context
) == CLASS_IMPLEMENTATION_TYPE
5981 || TREE_CODE (context
) == CLASS_INTERFACE_TYPE
)
5982 context
= (CLASS_SUPER_NAME (context
)
5983 ? lookup_interface (CLASS_SUPER_NAME (context
))
5986 else if (TREE_CODE (context
) == CATEGORY_IMPLEMENTATION_TYPE
5987 || TREE_CODE (context
) == CATEGORY_INTERFACE_TYPE
)
5988 context
= (CLASS_NAME (context
)
5989 ? lookup_interface (CLASS_NAME (context
))
5995 if (context
== NULL_TREE
)
5999 if (TREE_CODE (implementation_context
)
6000 == CLASS_IMPLEMENTATION_TYPE
)
6001 warning ("incomplete implementation of class `%s'",
6003 (CLASS_NAME (implementation_context
)));
6004 else if (TREE_CODE (implementation_context
)
6005 == CATEGORY_IMPLEMENTATION_TYPE
)
6006 warning ("incomplete implementation of category `%s'",
6008 (CLASS_SUPER_NAME (implementation_context
)));
6011 warning ("method definition for `%c%s' not found",
6012 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
6015 chain
= TREE_CHAIN (chain
); /* next method... */
6021 check_protocols (proto_list
, type
, name
)
6026 for ( ; proto_list
; proto_list
= TREE_CHAIN (proto_list
))
6028 tree p
= TREE_VALUE (proto_list
);
6030 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
6034 /* Ensure that all protocols have bodies. */
6035 if (flag_warn_protocol
) {
6036 f1
= check_methods (PROTOCOL_CLS_METHODS (p
),
6037 CLASS_CLS_METHODS (implementation_context
),
6039 f2
= check_methods (PROTOCOL_NST_METHODS (p
),
6040 CLASS_NST_METHODS (implementation_context
),
6043 f1
= check_methods_accessible (PROTOCOL_CLS_METHODS (p
),
6044 implementation_context
,
6046 f2
= check_methods_accessible (PROTOCOL_NST_METHODS (p
),
6047 implementation_context
,
6052 warning ("%s `%s' does not fully implement the `%s' protocol",
6053 type
, name
, IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
6058 ; /* An identifier if we could not find a protocol. */
6061 /* Check protocols recursively. */
6062 if (PROTOCOL_LIST (p
))
6065 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
6066 if (! conforms_to_protocol (super_class
, PROTOCOL_LIST (p
)))
6067 check_protocols (PROTOCOL_LIST (p
), type
, name
);
6072 /* Make sure that the class CLASS_NAME is defined
6073 CODE says which kind of thing CLASS_NAME ought to be.
6074 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6075 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6078 start_class (code
, class_name
, super_name
, protocol_list
)
6079 enum tree_code code
;
6086 if (!doing_objc_thang
)
6089 class = make_node (code
);
6090 TYPE_BINFO (class) = make_tree_vec (5);
6092 CLASS_NAME (class) = class_name
;
6093 CLASS_SUPER_NAME (class) = super_name
;
6094 CLASS_CLS_METHODS (class) = NULL_TREE
;
6096 if (! is_class_name (class_name
) && (decl
= lookup_name (class_name
)))
6098 error ("`%s' redeclared as different kind of symbol",
6099 IDENTIFIER_POINTER (class_name
));
6100 error_with_decl (decl
, "previous declaration of `%s'");
6103 if (code
== CLASS_IMPLEMENTATION_TYPE
)
6106 static tree implemented_classes
= 0;
6107 tree chain
= implemented_classes
;
6108 for (chain
= implemented_classes
; chain
; chain
= TREE_CHAIN (chain
))
6109 if (TREE_VALUE (chain
) == class_name
)
6111 error ("reimplementation of class `%s'",
6112 IDENTIFIER_POINTER (class_name
));
6113 return error_mark_node
;
6115 implemented_classes
= tree_cons (NULL_TREE
, class_name
,
6116 implemented_classes
);
6119 /* Pre-build the following entities - for speed/convenience. */
6121 self_id
= get_identifier ("self");
6123 ucmd_id
= get_identifier ("_cmd");
6126 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6127 if (!objc_super_template
)
6128 objc_super_template
= build_super_template ();
6130 /* Reset for multiple classes per file. */
6133 implementation_context
= class;
6135 /* Lookup the interface for this implementation. */
6137 if (!(implementation_template
= lookup_interface (class_name
)))
6139 warning ("Cannot find interface declaration for `%s'",
6140 IDENTIFIER_POINTER (class_name
));
6141 add_class (implementation_template
= implementation_context
);
6144 /* If a super class has been specified in the implementation,
6145 insure it conforms to the one specified in the interface. */
6148 && (super_name
!= CLASS_SUPER_NAME (implementation_template
)))
6150 tree previous_name
= CLASS_SUPER_NAME (implementation_template
);
6152 previous_name
? IDENTIFIER_POINTER (previous_name
) : "";
6153 error ("conflicting super class name `%s'",
6154 IDENTIFIER_POINTER (super_name
));
6155 error ("previous declaration of `%s'", name
);
6158 else if (! super_name
)
6160 CLASS_SUPER_NAME (implementation_context
)
6161 = CLASS_SUPER_NAME (implementation_template
);
6165 else if (code
== CLASS_INTERFACE_TYPE
)
6167 if (lookup_interface (class_name
))
6168 warning ("duplicate interface declaration for class `%s'",
6169 IDENTIFIER_POINTER (class_name
));
6174 CLASS_PROTOCOL_LIST (class)
6175 = lookup_and_install_protocols (protocol_list
);
6178 else if (code
== CATEGORY_INTERFACE_TYPE
)
6180 tree class_category_is_assoc_with
;
6182 /* For a category, class_name is really the name of the class that
6183 the following set of methods will be associated with. We must
6184 find the interface so that can derive the objects template. */
6186 if (!(class_category_is_assoc_with
= lookup_interface (class_name
)))
6188 error ("Cannot find interface declaration for `%s'",
6189 IDENTIFIER_POINTER (class_name
));
6190 exit (FATAL_EXIT_CODE
);
6193 add_category (class_category_is_assoc_with
, class);
6196 CLASS_PROTOCOL_LIST (class)
6197 = lookup_and_install_protocols (protocol_list
);
6200 else if (code
== CATEGORY_IMPLEMENTATION_TYPE
)
6202 /* Pre-build the following entities for speed/convenience. */
6204 self_id
= get_identifier ("self");
6206 ucmd_id
= get_identifier ("_cmd");
6209 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6210 if (!objc_super_template
)
6211 objc_super_template
= build_super_template ();
6213 /* Reset for multiple classes per file. */
6216 implementation_context
= class;
6218 /* For a category, class_name is really the name of the class that
6219 the following set of methods will be associated with. We must
6220 find the interface so that can derive the objects template. */
6222 if (!(implementation_template
= lookup_interface (class_name
)))
6224 error ("Cannot find interface declaration for `%s'",
6225 IDENTIFIER_POINTER (class_name
));
6226 exit (FATAL_EXIT_CODE
);
6233 continue_class (class)
6236 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6237 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6239 struct imp_entry
*imp_entry
;
6242 /* Check consistency of the instance variables. */
6244 if (CLASS_IVARS (class))
6245 check_ivars (implementation_template
, class);
6247 /* code generation */
6249 ivar_context
= build_private_template (implementation_template
);
6251 if (!objc_class_template
)
6252 build_class_template ();
6255 = (struct imp_entry
*) xmalloc (sizeof (struct imp_entry
))))
6256 perror ("unable to allocate in objc-tree.c");
6258 imp_entry
->next
= imp_list
;
6259 imp_entry
->imp_context
= class;
6260 imp_entry
->imp_template
= implementation_template
;
6262 synth_forward_declarations ();
6263 imp_entry
->class_decl
= UOBJC_CLASS_decl
;
6264 imp_entry
->meta_decl
= UOBJC_METACLASS_decl
;
6266 /* Append to front and increment count. */
6267 imp_list
= imp_entry
;
6268 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6273 return ivar_context
;
6276 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6278 tree record
= xref_tag (RECORD_TYPE
, CLASS_NAME (class));
6280 if (!TYPE_FIELDS (record
))
6282 finish_struct (record
, build_ivar_chain (class, 0), NULL_TREE
);
6283 CLASS_STATIC_TEMPLATE (class) = record
;
6285 /* Mark this record as a class template for static typing. */
6286 TREE_STATIC_TEMPLATE (record
) = 1;
6293 return error_mark_node
;
6296 /* This is called once we see the "@end" in an interface/implementation. */
6299 finish_class (class)
6302 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6304 /* All code generation is done in finish_objc. */
6306 if (implementation_template
!= implementation_context
)
6308 /* Ensure that all method listed in the interface contain bodies. */
6309 check_methods (CLASS_CLS_METHODS (implementation_template
),
6310 CLASS_CLS_METHODS (implementation_context
), '+');
6311 check_methods (CLASS_NST_METHODS (implementation_template
),
6312 CLASS_NST_METHODS (implementation_context
), '-');
6314 if (CLASS_PROTOCOL_LIST (implementation_template
))
6315 check_protocols (CLASS_PROTOCOL_LIST (implementation_template
),
6317 IDENTIFIER_POINTER (CLASS_NAME (implementation_context
)));
6321 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6323 tree category
= CLASS_CATEGORY_LIST (implementation_template
);
6325 /* Find the category interface from the class it is associated with. */
6328 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category
))
6330 category
= CLASS_CATEGORY_LIST (category
);
6335 /* Ensure all method listed in the interface contain bodies. */
6336 check_methods (CLASS_CLS_METHODS (category
),
6337 CLASS_CLS_METHODS (implementation_context
), '+');
6338 check_methods (CLASS_NST_METHODS (category
),
6339 CLASS_NST_METHODS (implementation_context
), '-');
6341 if (CLASS_PROTOCOL_LIST (category
))
6342 check_protocols (CLASS_PROTOCOL_LIST (category
),
6344 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
6348 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6351 const char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (class));
6352 char *string
= (char *) alloca (strlen (class_name
) + 3);
6354 /* extern struct objc_object *_<my_name>; */
6356 sprintf (string
, "_%s", class_name
);
6358 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
6359 decl_specs
= tree_cons (NULL_TREE
, objc_object_reference
, decl_specs
);
6360 define_decl (build1 (INDIRECT_REF
, NULL_TREE
, get_identifier (string
)),
6366 add_protocol (protocol
)
6369 /* Put protocol on list in reverse order. */
6370 TREE_CHAIN (protocol
) = protocol_chain
;
6371 protocol_chain
= protocol
;
6372 return protocol_chain
;
6376 lookup_protocol (ident
)
6381 for (chain
= protocol_chain
; chain
; chain
= TREE_CHAIN (chain
))
6383 if (ident
== PROTOCOL_NAME (chain
))
6391 start_protocol (code
, name
, list
)
6392 enum tree_code code
;
6398 if (!doing_objc_thang
)
6401 /* This is as good a place as any. Need to invoke push_tag_toplevel. */
6402 if (!objc_protocol_template
)
6403 objc_protocol_template
= build_protocol_template ();
6405 protocol
= make_node (code
);
6406 TYPE_BINFO (protocol
) = make_tree_vec (2);
6408 PROTOCOL_NAME (protocol
) = name
;
6409 PROTOCOL_LIST (protocol
) = list
;
6411 lookup_and_install_protocols (list
);
6413 if (lookup_protocol (name
))
6414 warning ("duplicate declaration for protocol `%s'",
6415 IDENTIFIER_POINTER (name
));
6417 add_protocol (protocol
);
6419 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6425 finish_protocol (protocol
)
6426 tree protocol ATTRIBUTE_UNUSED
;
6431 /* "Encode" a data type into a string, which grows in util_obstack.
6432 ??? What is the FORMAT? Someone please document this! */
6435 encode_type_qualifiers (declspecs
)
6440 for (spec
= declspecs
; spec
; spec
= TREE_CHAIN (spec
))
6442 if (ridpointers
[(int) RID_CONST
] == TREE_VALUE (spec
))
6443 obstack_1grow (&util_obstack
, 'r');
6444 else if (ridpointers
[(int) RID_IN
] == TREE_VALUE (spec
))
6445 obstack_1grow (&util_obstack
, 'n');
6446 else if (ridpointers
[(int) RID_INOUT
] == TREE_VALUE (spec
))
6447 obstack_1grow (&util_obstack
, 'N');
6448 else if (ridpointers
[(int) RID_OUT
] == TREE_VALUE (spec
))
6449 obstack_1grow (&util_obstack
, 'o');
6450 else if (ridpointers
[(int) RID_BYCOPY
] == TREE_VALUE (spec
))
6451 obstack_1grow (&util_obstack
, 'O');
6452 else if (ridpointers
[(int) RID_BYREF
] == TREE_VALUE (spec
))
6453 obstack_1grow (&util_obstack
, 'R');
6454 else if (ridpointers
[(int) RID_ONEWAY
] == TREE_VALUE (spec
))
6455 obstack_1grow (&util_obstack
, 'V');
6459 /* Encode a pointer type. */
6462 encode_pointer (type
, curtype
, format
)
6467 tree pointer_to
= TREE_TYPE (type
);
6469 if (TREE_CODE (pointer_to
) == RECORD_TYPE
)
6471 if (TYPE_NAME (pointer_to
)
6472 && TREE_CODE (TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
)
6474 const char *name
= IDENTIFIER_POINTER (TYPE_NAME (pointer_to
));
6476 if (strcmp (name
, TAG_OBJECT
) == 0) /* '@' */
6478 obstack_1grow (&util_obstack
, '@');
6481 else if (TREE_STATIC_TEMPLATE (pointer_to
))
6483 if (generating_instance_variables
)
6485 obstack_1grow (&util_obstack
, '@');
6486 obstack_1grow (&util_obstack
, '"');
6487 obstack_grow (&util_obstack
, name
, strlen (name
));
6488 obstack_1grow (&util_obstack
, '"');
6493 obstack_1grow (&util_obstack
, '@');
6497 else if (strcmp (name
, TAG_CLASS
) == 0) /* '#' */
6499 obstack_1grow (&util_obstack
, '#');
6502 #ifndef OBJC_INT_SELECTORS
6503 else if (strcmp (name
, TAG_SELECTOR
) == 0) /* ':' */
6505 obstack_1grow (&util_obstack
, ':');
6508 #endif /* OBJC_INT_SELECTORS */
6511 else if (TREE_CODE (pointer_to
) == INTEGER_TYPE
6512 && TYPE_MODE (pointer_to
) == QImode
)
6514 obstack_1grow (&util_obstack
, '*');
6518 /* We have a type that does not get special treatment. */
6520 /* NeXT extension */
6521 obstack_1grow (&util_obstack
, '^');
6522 encode_type (pointer_to
, curtype
, format
);
6526 encode_array (type
, curtype
, format
)
6531 tree an_int_cst
= TYPE_SIZE (type
);
6532 tree array_of
= TREE_TYPE (type
);
6535 /* An incomplete array is treated like a pointer. */
6536 if (an_int_cst
== NULL
)
6538 encode_pointer (type
, curtype
, format
);
6542 sprintf (buffer
, "[%ld",
6543 (long) (TREE_INT_CST_LOW (an_int_cst
)
6544 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
6546 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6547 encode_type (array_of
, curtype
, format
);
6548 obstack_1grow (&util_obstack
, ']');
6553 encode_aggregate_within (type
, curtype
, format
, left
, right
)
6560 if (obstack_object_size (&util_obstack
) > 0
6561 && *(obstack_next_free (&util_obstack
) - 1) == '^')
6563 tree name
= TYPE_NAME (type
);
6565 /* we have a reference; this is a NeXT extension. */
6567 if (obstack_object_size (&util_obstack
) - curtype
== 1
6568 && format
== OBJC_ENCODE_INLINE_DEFS
)
6570 /* Output format of struct for first level only. */
6571 tree fields
= TYPE_FIELDS (type
);
6573 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6575 obstack_1grow (&util_obstack
, left
);
6576 obstack_grow (&util_obstack
,
6577 IDENTIFIER_POINTER (name
),
6578 strlen (IDENTIFIER_POINTER (name
)));
6579 obstack_1grow (&util_obstack
, '=');
6583 obstack_1grow (&util_obstack
, left
);
6584 obstack_grow (&util_obstack
, "?=", 2);
6587 for ( ; fields
; fields
= TREE_CHAIN (fields
))
6588 encode_field_decl (fields
, curtype
, format
);
6590 obstack_1grow (&util_obstack
, right
);
6593 else if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6595 obstack_1grow (&util_obstack
, left
);
6596 obstack_grow (&util_obstack
,
6597 IDENTIFIER_POINTER (name
),
6598 strlen (IDENTIFIER_POINTER (name
)));
6599 obstack_1grow (&util_obstack
, right
);
6604 /* We have an untagged structure or a typedef. */
6605 obstack_1grow (&util_obstack
, left
);
6606 obstack_1grow (&util_obstack
, '?');
6607 obstack_1grow (&util_obstack
, right
);
6613 tree name
= TYPE_NAME (type
);
6614 tree fields
= TYPE_FIELDS (type
);
6616 if (format
== OBJC_ENCODE_INLINE_DEFS
6617 || generating_instance_variables
)
6619 obstack_1grow (&util_obstack
, left
);
6620 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6621 obstack_grow (&util_obstack
,
6622 IDENTIFIER_POINTER (name
),
6623 strlen (IDENTIFIER_POINTER (name
)));
6625 obstack_1grow (&util_obstack
, '?');
6627 obstack_1grow (&util_obstack
, '=');
6629 for (; fields
; fields
= TREE_CHAIN (fields
))
6631 if (generating_instance_variables
)
6633 tree fname
= DECL_NAME (fields
);
6635 obstack_1grow (&util_obstack
, '"');
6636 if (fname
&& TREE_CODE (fname
) == IDENTIFIER_NODE
)
6638 obstack_grow (&util_obstack
,
6639 IDENTIFIER_POINTER (fname
),
6640 strlen (IDENTIFIER_POINTER (fname
)));
6643 obstack_1grow (&util_obstack
, '"');
6646 encode_field_decl (fields
, curtype
, format
);
6649 obstack_1grow (&util_obstack
, right
);
6654 obstack_1grow (&util_obstack
, left
);
6655 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6656 obstack_grow (&util_obstack
,
6657 IDENTIFIER_POINTER (name
),
6658 strlen (IDENTIFIER_POINTER (name
)));
6660 /* We have an untagged structure or a typedef. */
6661 obstack_1grow (&util_obstack
, '?');
6663 obstack_1grow (&util_obstack
, right
);
6669 encode_aggregate (type
, curtype
, format
)
6674 enum tree_code code
= TREE_CODE (type
);
6680 encode_aggregate_within(type
, curtype
, format
, '{', '}');
6685 encode_aggregate_within(type
, curtype
, format
, '(', ')');
6690 obstack_1grow (&util_obstack
, 'i');
6698 /* Support bitfields. The current version of Objective-C does not support
6699 them. The string will consist of one or more "b:n"'s where n is an
6700 integer describing the width of the bitfield. Currently, classes in
6701 the kit implement a method "-(char *)describeBitfieldStruct:" that
6702 simulates this. If they do not implement this method, the archiver
6703 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6704 according to the GNU compiler. After looking at the "kit", it appears
6705 that all classes currently rely on this default behavior, rather than
6706 hand generating this string (which is tedious). */
6709 encode_bitfield (width
)
6713 sprintf (buffer
, "b%d", width
);
6714 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6717 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6720 encode_type (type
, curtype
, format
)
6725 enum tree_code code
= TREE_CODE (type
);
6727 if (code
== INTEGER_TYPE
)
6729 if (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type
)) == 0
6730 && TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type
)) == 0)
6732 /* Unsigned integer types. */
6734 if (TYPE_MODE (type
) == QImode
)
6735 obstack_1grow (&util_obstack
, 'C');
6736 else if (TYPE_MODE (type
) == HImode
)
6737 obstack_1grow (&util_obstack
, 'S');
6738 else if (TYPE_MODE (type
) == SImode
)
6740 if (type
== long_unsigned_type_node
)
6741 obstack_1grow (&util_obstack
, 'L');
6743 obstack_1grow (&util_obstack
, 'I');
6745 else if (TYPE_MODE (type
) == DImode
)
6746 obstack_1grow (&util_obstack
, 'Q');
6750 /* Signed integer types. */
6752 if (TYPE_MODE (type
) == QImode
)
6753 obstack_1grow (&util_obstack
, 'c');
6754 else if (TYPE_MODE (type
) == HImode
)
6755 obstack_1grow (&util_obstack
, 's');
6756 else if (TYPE_MODE (type
) == SImode
)
6758 if (type
== long_integer_type_node
)
6759 obstack_1grow (&util_obstack
, 'l');
6761 obstack_1grow (&util_obstack
, 'i');
6764 else if (TYPE_MODE (type
) == DImode
)
6765 obstack_1grow (&util_obstack
, 'q');
6769 else if (code
== REAL_TYPE
)
6771 /* Floating point types. */
6773 if (TYPE_MODE (type
) == SFmode
)
6774 obstack_1grow (&util_obstack
, 'f');
6775 else if (TYPE_MODE (type
) == DFmode
6776 || TYPE_MODE (type
) == TFmode
)
6777 obstack_1grow (&util_obstack
, 'd');
6780 else if (code
== VOID_TYPE
)
6781 obstack_1grow (&util_obstack
, 'v');
6783 else if (code
== ARRAY_TYPE
)
6784 encode_array (type
, curtype
, format
);
6786 else if (code
== POINTER_TYPE
)
6787 encode_pointer (type
, curtype
, format
);
6789 else if (code
== RECORD_TYPE
|| code
== UNION_TYPE
|| code
== ENUMERAL_TYPE
)
6790 encode_aggregate (type
, curtype
, format
);
6792 else if (code
== FUNCTION_TYPE
) /* '?' */
6793 obstack_1grow (&util_obstack
, '?');
6797 encode_complete_bitfield (int position
, tree type
, int size
)
6799 enum tree_code code
= TREE_CODE (type
);
6801 char charType
= '?';
6803 if (code
== INTEGER_TYPE
)
6805 if (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type
)) == 0
6806 && TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type
)) == 0)
6808 /* Unsigned integer types. */
6810 if (TYPE_MODE (type
) == QImode
)
6812 else if (TYPE_MODE (type
) == HImode
)
6814 else if (TYPE_MODE (type
) == SImode
)
6816 if (type
== long_unsigned_type_node
)
6821 else if (TYPE_MODE (type
) == DImode
)
6826 /* Signed integer types. */
6828 if (TYPE_MODE (type
) == QImode
)
6830 else if (TYPE_MODE (type
) == HImode
)
6832 else if (TYPE_MODE (type
) == SImode
)
6834 if (type
== long_integer_type_node
)
6840 else if (TYPE_MODE (type
) == DImode
)
6848 sprintf (buffer
, "b%d%c%d", position
, charType
, size
);
6849 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6853 encode_field_decl (field_decl
, curtype
, format
)
6860 type
= TREE_TYPE (field_decl
);
6862 /* If this field is obviously a bitfield, or is a bitfield that has been
6863 clobbered to look like a ordinary integer mode, go ahead and generate
6864 the bitfield typing information. */
6865 if (flag_next_runtime
)
6867 if (DECL_BIT_FIELD (field_decl
))
6868 encode_bitfield (TREE_INT_CST_LOW (DECL_SIZE (field_decl
)));
6870 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6874 if (DECL_BIT_FIELD (field_decl
))
6875 encode_complete_bitfield (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl
)),
6876 DECL_BIT_FIELD_TYPE (field_decl
),
6877 TREE_INT_CST_LOW (DECL_SIZE (field_decl
)));
6879 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6884 expr_last (complex_expr
)
6890 while ((next
= TREE_OPERAND (complex_expr
, 0)))
6891 complex_expr
= next
;
6893 return complex_expr
;
6896 /* The selector of the current method,
6897 or NULL if we aren't compiling a method. */
6900 maybe_objc_method_name (decl
)
6901 tree decl ATTRIBUTE_UNUSED
;
6904 return METHOD_SEL_NAME (method_context
);
6909 /* Transform a method definition into a function definition as follows:
6910 - synthesize the first two arguments, "self" and "_cmd". */
6913 start_method_def (method
)
6918 /* Required to implement _msgSuper. */
6919 method_context
= method
;
6920 UOBJC_SUPER_decl
= NULL_TREE
;
6922 /* Must be called BEFORE start_function. */
6925 /* Generate prototype declarations for arguments..."new-style". */
6927 if (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
)
6928 decl_specs
= build_tree_list (NULL_TREE
, uprivate_record
);
6930 /* Really a `struct objc_class *'. However, we allow people to
6931 assign to self, which changes its type midstream. */
6932 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
6934 push_parm_decl (build_tree_list
6935 (build_tree_list (decl_specs
,
6936 build1 (INDIRECT_REF
, NULL_TREE
, self_id
)),
6937 build_tree_list (unused_list
, NULL_TREE
)));
6939 #ifdef OBJC_INT_SELECTORS
6940 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_UNSIGNED
]);
6941 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_INT
], decl_specs
);
6942 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, ucmd_id
),
6943 build_tree_list (unused_list
, NULL_TREE
)));
6944 #else /* not OBJC_INT_SELECTORS */
6945 decl_specs
= build_tree_list (NULL_TREE
,
6946 xref_tag (RECORD_TYPE
,
6947 get_identifier (TAG_SELECTOR
)));
6948 push_parm_decl (build_tree_list
6949 (build_tree_list (decl_specs
,
6950 build1 (INDIRECT_REF
, NULL_TREE
, ucmd_id
)),
6951 build_tree_list (unused_list
, NULL_TREE
)));
6952 #endif /* not OBJC_INT_SELECTORS */
6954 /* Generate argument declarations if a keyword_decl. */
6955 if (METHOD_SEL_ARGS (method
))
6957 tree arglist
= METHOD_SEL_ARGS (method
);
6960 tree arg_spec
= TREE_PURPOSE (TREE_TYPE (arglist
));
6961 tree arg_decl
= TREE_VALUE (TREE_TYPE (arglist
));
6965 tree last_expr
= expr_last (arg_decl
);
6967 /* Unite the abstract decl with its name. */
6968 TREE_OPERAND (last_expr
, 0) = KEYWORD_ARG_NAME (arglist
);
6969 push_parm_decl (build_tree_list
6970 (build_tree_list (arg_spec
, arg_decl
),
6971 build_tree_list (NULL_TREE
, NULL_TREE
)));
6973 /* Unhook: restore the abstract declarator. */
6974 TREE_OPERAND (last_expr
, 0) = NULL_TREE
;
6978 push_parm_decl (build_tree_list
6979 (build_tree_list (arg_spec
,
6980 KEYWORD_ARG_NAME (arglist
)),
6981 build_tree_list (NULL_TREE
, NULL_TREE
)));
6983 arglist
= TREE_CHAIN (arglist
);
6988 if (METHOD_ADD_ARGS (method
) > (tree
)1)
6990 /* We have a variable length selector - in "prototype" format. */
6991 tree akey
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
6994 /* This must be done prior to calling pushdecl. pushdecl is
6995 going to change our chain on us. */
6996 tree nextkey
= TREE_CHAIN (akey
);
7004 warn_with_method (message
, mtype
, method
)
7005 const char *message
;
7009 if (count_error (1) == 0)
7012 report_error_function (DECL_SOURCE_FILE (method
));
7014 fprintf (stderr
, "%s:%d: warning: ",
7015 DECL_SOURCE_FILE (method
), DECL_SOURCE_LINE (method
));
7016 bzero (errbuf
, BUFSIZE
);
7017 fprintf (stderr
, "%s `%c%s'\n",
7018 message
, mtype
, gen_method_decl (method
, errbuf
));
7021 /* Return 1 if METHOD is consistent with PROTO. */
7024 comp_method_with_proto (method
, proto
)
7027 static tree function_type
= 0;
7029 /* Create a function_type node once. */
7031 function_type
= make_node (FUNCTION_TYPE
);
7033 /* Install argument types - normally set by build_function_type. */
7034 TYPE_ARG_TYPES (function_type
) = get_arg_type_list (proto
, METHOD_DEF
, 0);
7036 /* install return type */
7037 TREE_TYPE (function_type
) = groktypename (TREE_TYPE (proto
));
7039 return comptypes (TREE_TYPE (METHOD_DEFINITION (method
)), function_type
);
7042 /* Return 1 if PROTO1 is consistent with PROTO2. */
7045 comp_proto_with_proto (proto1
, proto2
)
7046 tree proto1
, proto2
;
7048 static tree function_type1
= 0, function_type2
= 0;
7050 /* Create a couple function_type node's once. */
7051 if (!function_type1
)
7053 function_type1
= make_node (FUNCTION_TYPE
);
7054 function_type2
= make_node (FUNCTION_TYPE
);
7057 /* Install argument types; normally set by build_function_type. */
7058 TYPE_ARG_TYPES (function_type1
) = get_arg_type_list (proto1
, METHOD_REF
, 0);
7059 TYPE_ARG_TYPES (function_type2
) = get_arg_type_list (proto2
, METHOD_REF
, 0);
7061 /* Install return type. */
7062 TREE_TYPE (function_type1
) = groktypename (TREE_TYPE (proto1
));
7063 TREE_TYPE (function_type2
) = groktypename (TREE_TYPE (proto2
));
7065 return comptypes (function_type1
, function_type2
);
7068 /* - Generate an identifier for the function. the format is "_n_cls",
7069 where 1 <= n <= nMethods, and cls is the name the implementation we
7071 - Install the return type from the method declaration.
7072 - If we have a prototype, check for type consistency. */
7075 really_start_method (method
, parmlist
)
7076 tree method
, parmlist
;
7078 tree sc_spec
, ret_spec
, ret_decl
, decl_specs
;
7079 tree method_decl
, method_id
;
7080 const char *sel_name
, *class_name
, *cat_name
;
7083 /* Synth the storage class & assemble the return type. */
7084 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
7085 ret_spec
= TREE_PURPOSE (TREE_TYPE (method
));
7086 decl_specs
= chainon (sc_spec
, ret_spec
);
7088 sel_name
= IDENTIFIER_POINTER (METHOD_SEL_NAME (method
));
7089 class_name
= IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
7090 cat_name
= ((TREE_CODE (implementation_context
)
7091 == CLASS_IMPLEMENTATION_TYPE
)
7093 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
7096 /* Make sure this is big enough for any plausible method label. */
7097 buf
= (char *) alloca (50 + strlen (sel_name
) + strlen (class_name
)
7098 + (cat_name
? strlen (cat_name
) : 0));
7100 OBJC_GEN_METHOD_LABEL (buf
, TREE_CODE (method
) == INSTANCE_METHOD_DECL
,
7101 class_name
, cat_name
, sel_name
, method_slot
);
7103 method_id
= get_identifier (buf
);
7105 method_decl
= build_nt (CALL_EXPR
, method_id
, parmlist
, NULL_TREE
);
7107 /* Check the declarator portion of the return type for the method. */
7108 if ((ret_decl
= TREE_VALUE (TREE_TYPE (method
))))
7110 /* Unite the complex decl (specified in the abstract decl) with the
7111 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7112 tree save_expr
= expr_last (ret_decl
);
7114 TREE_OPERAND (save_expr
, 0) = method_decl
;
7115 method_decl
= ret_decl
;
7117 /* Fool the parser into thinking it is starting a function. */
7118 start_function (decl_specs
, method_decl
, NULL_TREE
, NULL_TREE
);
7120 /* Unhook: this has the effect of restoring the abstract declarator. */
7121 TREE_OPERAND (save_expr
, 0) = NULL_TREE
;
7126 TREE_VALUE (TREE_TYPE (method
)) = method_decl
;
7128 /* Fool the parser into thinking it is starting a function. */
7129 start_function (decl_specs
, method_decl
, NULL_TREE
, NULL_TREE
);
7131 /* Unhook: this has the effect of restoring the abstract declarator. */
7132 TREE_VALUE (TREE_TYPE (method
)) = NULL_TREE
;
7135 METHOD_DEFINITION (method
) = current_function_decl
;
7137 if (implementation_template
!= implementation_context
)
7141 if (TREE_CODE (method
) == INSTANCE_METHOD_DECL
)
7142 proto
= lookup_instance_method_static (implementation_template
,
7143 METHOD_SEL_NAME (method
));
7145 proto
= lookup_class_method_static (implementation_template
,
7146 METHOD_SEL_NAME (method
));
7148 if (proto
&& ! comp_method_with_proto (method
, proto
))
7150 char type
= (TREE_CODE (method
) == INSTANCE_METHOD_DECL
? '-' : '+');
7152 warn_with_method ("conflicting types for", type
, method
);
7153 warn_with_method ("previous declaration of", type
, proto
);
7158 /* The following routine is always called...this "architecture" is to
7159 accommodate "old-style" variable length selectors.
7161 - a:a b:b // prototype ; id c; id d; // old-style. */
7164 continue_method_def ()
7168 if (METHOD_ADD_ARGS (method_context
) == (tree
)1)
7169 /* We have a `, ...' immediately following the selector. */
7170 parmlist
= get_parm_info (0);
7172 parmlist
= get_parm_info (1); /* place a `void_at_end' */
7174 /* Set self_decl from the first argument...this global is used by
7175 build_ivar_reference calling build_indirect_ref. */
7176 self_decl
= TREE_PURPOSE (parmlist
);
7179 really_start_method (method_context
, parmlist
);
7180 store_parm_decls ();
7183 /* Called by the parser, from the `pushlevel' production. */
7188 if (!UOBJC_SUPER_decl
)
7190 UOBJC_SUPER_decl
= start_decl (get_identifier (UTAG_SUPER
),
7191 build_tree_list (NULL_TREE
,
7192 objc_super_template
),
7193 0, NULL_TREE
, NULL_TREE
);
7195 finish_decl (UOBJC_SUPER_decl
, NULL_TREE
, NULL_TREE
);
7197 /* This prevents `unused variable' warnings when compiling with -Wall. */
7198 TREE_USED (UOBJC_SUPER_decl
) = 1;
7199 DECL_ARTIFICIAL (UOBJC_SUPER_decl
) = 1;
7203 /* _n_Method (id self, SEL sel, ...)
7205 struct objc_super _S;
7206 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7210 get_super_receiver ()
7214 tree super_expr
, super_expr_list
;
7216 /* Set receiver to self. */
7217 super_expr
= build_component_ref (UOBJC_SUPER_decl
, self_id
);
7218 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, self_decl
);
7219 super_expr_list
= build_tree_list (NULL_TREE
, super_expr
);
7221 /* Set class to begin searching. */
7222 super_expr
= build_component_ref (UOBJC_SUPER_decl
,
7223 get_identifier ("class"));
7225 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
7227 /* [_cls, __cls]Super are "pre-built" in
7228 synth_forward_declarations. */
7230 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
,
7231 ((TREE_CODE (method_context
)
7232 == INSTANCE_METHOD_DECL
)
7234 : uucls_super_ref
));
7238 /* We have a category. */
7240 tree super_name
= CLASS_SUPER_NAME (implementation_template
);
7245 error ("no super class declared in interface for `%s'",
7246 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
7247 return error_mark_node
;
7250 if (flag_next_runtime
)
7252 super_class
= get_class_reference (super_name
);
7253 if (TREE_CODE (method_context
) == CLASS_METHOD_DECL
)
7255 = build_component_ref (build_indirect_ref (super_class
, "->"),
7256 get_identifier ("isa"));
7260 add_class_reference (super_name
);
7261 super_class
= (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
7262 ? objc_get_class_decl
: objc_get_meta_class_decl
);
7263 assemble_external (super_class
);
7265 = build_function_call
7269 my_build_string (IDENTIFIER_LENGTH (super_name
) + 1,
7270 IDENTIFIER_POINTER (super_name
))));
7273 TREE_TYPE (super_class
) = TREE_TYPE (ucls_super_ref
);
7274 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, super_class
);
7277 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7279 super_expr
= build_unary_op (ADDR_EXPR
, UOBJC_SUPER_decl
, 0);
7280 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7282 return build_compound_expr (super_expr_list
);
7286 error ("[super ...] must appear in a method context");
7287 return error_mark_node
;
7292 encode_method_def (func_decl
)
7297 int max_parm_end
= 0;
7302 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
7303 obstack_object_size (&util_obstack
),
7304 OBJC_ENCODE_INLINE_DEFS
);
7307 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7308 parms
= TREE_CHAIN (parms
))
7310 int parm_end
= (forwarding_offset (parms
)
7311 + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms
)))
7314 if (!offset_is_register
&& parm_end
> max_parm_end
)
7315 max_parm_end
= parm_end
;
7318 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
7320 sprintf (buffer
, "%d", stack_size
);
7321 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7323 /* Argument types. */
7324 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7325 parms
= TREE_CHAIN (parms
))
7328 encode_type (TREE_TYPE (parms
),
7329 obstack_object_size (&util_obstack
),
7330 OBJC_ENCODE_INLINE_DEFS
);
7332 /* Compute offset. */
7333 sprintf (buffer
, "%d", forwarding_offset (parms
));
7335 /* Indicate register. */
7336 if (offset_is_register
)
7337 obstack_1grow (&util_obstack
, '+');
7339 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7342 obstack_1grow (&util_obstack
, 0);
7343 result
= get_identifier (obstack_finish (&util_obstack
));
7344 obstack_free (&util_obstack
, util_firstobj
);
7349 finish_method_def ()
7351 METHOD_ENCODING (method_context
) = encode_method_def (current_function_decl
);
7353 finish_function (0);
7355 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7356 since the optimizer may find "may be used before set" errors. */
7357 method_context
= NULL_TREE
;
7362 lang_report_error_function (decl
)
7367 fprintf (stderr
, "In method `%s'\n",
7368 IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context
)));
7378 is_complex_decl (type
)
7381 return (TREE_CODE (type
) == ARRAY_TYPE
7382 || TREE_CODE (type
) == FUNCTION_TYPE
7383 || (TREE_CODE (type
) == POINTER_TYPE
&& ! IS_ID (type
)));
7387 /* Code to convert a decl node into text for a declaration in C. */
7389 static char tmpbuf
[256];
7392 adorn_decl (decl
, str
)
7396 enum tree_code code
= TREE_CODE (decl
);
7398 if (code
== ARRAY_REF
)
7400 tree an_int_cst
= TREE_OPERAND (decl
, 1);
7402 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_CST
)
7403 sprintf (str
+ strlen (str
), "[%ld]",
7404 (long) TREE_INT_CST_LOW (an_int_cst
));
7409 else if (code
== ARRAY_TYPE
)
7411 tree an_int_cst
= TYPE_SIZE (decl
);
7412 tree array_of
= TREE_TYPE (decl
);
7414 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_TYPE
)
7415 sprintf (str
+ strlen (str
), "[%ld]",
7416 (long) (TREE_INT_CST_LOW (an_int_cst
)
7417 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
7422 else if (code
== CALL_EXPR
)
7424 tree chain
= TREE_PURPOSE (TREE_OPERAND (decl
, 1));
7429 gen_declaration (chain
, str
);
7430 chain
= TREE_CHAIN (chain
);
7437 else if (code
== FUNCTION_TYPE
)
7439 tree chain
= TYPE_ARG_TYPES (decl
);
7442 while (chain
&& TREE_VALUE (chain
) != void_type_node
)
7444 gen_declaration (TREE_VALUE (chain
), str
);
7445 chain
= TREE_CHAIN (chain
);
7446 if (chain
&& TREE_VALUE (chain
) != void_type_node
)
7452 else if (code
== INDIRECT_REF
)
7454 strcpy (tmpbuf
, "*");
7455 if (TREE_TYPE (decl
) && TREE_CODE (TREE_TYPE (decl
)) == TREE_LIST
)
7459 for (chain
= nreverse (copy_list (TREE_TYPE (decl
)));
7461 chain
= TREE_CHAIN (chain
))
7463 if (TREE_CODE (TREE_VALUE (chain
)) == IDENTIFIER_NODE
)
7465 strcat (tmpbuf
, " ");
7466 strcat (tmpbuf
, IDENTIFIER_POINTER (TREE_VALUE (chain
)));
7470 strcat (tmpbuf
, " ");
7472 strcat (tmpbuf
, str
);
7473 strcpy (str
, tmpbuf
);
7476 else if (code
== POINTER_TYPE
)
7478 strcpy (tmpbuf
, "*");
7479 if (TREE_READONLY (decl
) || TYPE_VOLATILE (decl
))
7481 if (TREE_READONLY (decl
))
7482 strcat (tmpbuf
, " const");
7483 if (TYPE_VOLATILE (decl
))
7484 strcat (tmpbuf
, " volatile");
7486 strcat (tmpbuf
, " ");
7488 strcat (tmpbuf
, str
);
7489 strcpy (str
, tmpbuf
);
7494 gen_declarator (decl
, buf
, name
)
7501 enum tree_code code
= TREE_CODE (decl
);
7511 op
= TREE_OPERAND (decl
, 0);
7513 /* We have a pointer to a function or array...(*)(), (*)[] */
7514 if ((code
== ARRAY_REF
|| code
== CALL_EXPR
)
7515 && op
&& TREE_CODE (op
) == INDIRECT_REF
)
7518 str
= gen_declarator (op
, buf
, name
);
7522 strcpy (tmpbuf
, "(");
7523 strcat (tmpbuf
, str
);
7524 strcat (tmpbuf
, ")");
7525 strcpy (str
, tmpbuf
);
7528 adorn_decl (decl
, str
);
7537 /* This clause is done iteratively rather than recursively. */
7540 op
= (is_complex_decl (TREE_TYPE (decl
))
7541 ? TREE_TYPE (decl
) : NULL_TREE
);
7543 adorn_decl (decl
, str
);
7545 /* We have a pointer to a function or array...(*)(), (*)[] */
7546 if (code
== POINTER_TYPE
7547 && op
&& (TREE_CODE (op
) == FUNCTION_TYPE
7548 || TREE_CODE (op
) == ARRAY_TYPE
))
7550 strcpy (tmpbuf
, "(");
7551 strcat (tmpbuf
, str
);
7552 strcat (tmpbuf
, ")");
7553 strcpy (str
, tmpbuf
);
7556 decl
= (is_complex_decl (TREE_TYPE (decl
))
7557 ? TREE_TYPE (decl
) : NULL_TREE
);
7560 while (decl
&& (code
= TREE_CODE (decl
)))
7565 case IDENTIFIER_NODE
:
7566 /* Will only happen if we are processing a "raw" expr-decl. */
7567 strcpy (buf
, IDENTIFIER_POINTER (decl
));
7578 /* We have an abstract declarator or a _DECL node. */
7586 gen_declspecs (declspecs
, buf
, raw
)
7595 for (chain
= nreverse (copy_list (declspecs
));
7596 chain
; chain
= TREE_CHAIN (chain
))
7598 tree aspec
= TREE_VALUE (chain
);
7600 if (TREE_CODE (aspec
) == IDENTIFIER_NODE
)
7601 strcat (buf
, IDENTIFIER_POINTER (aspec
));
7602 else if (TREE_CODE (aspec
) == RECORD_TYPE
)
7604 if (TYPE_NAME (aspec
))
7606 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7608 if (! TREE_STATIC_TEMPLATE (aspec
))
7609 strcat (buf
, "struct ");
7610 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7615 tree chain
= protocol_list
;
7622 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7623 chain
= TREE_CHAIN (chain
);
7632 strcat (buf
, "untagged struct");
7635 else if (TREE_CODE (aspec
) == UNION_TYPE
)
7637 if (TYPE_NAME (aspec
))
7639 if (! TREE_STATIC_TEMPLATE (aspec
))
7640 strcat (buf
, "union ");
7641 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7644 strcat (buf
, "untagged union");
7647 else if (TREE_CODE (aspec
) == ENUMERAL_TYPE
)
7649 if (TYPE_NAME (aspec
))
7651 if (! TREE_STATIC_TEMPLATE (aspec
))
7652 strcat (buf
, "enum ");
7653 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7656 strcat (buf
, "untagged enum");
7659 else if (TREE_CODE (aspec
) == TYPE_DECL
&& DECL_NAME (aspec
))
7660 strcat (buf
, IDENTIFIER_POINTER (DECL_NAME (aspec
)));
7662 else if (IS_ID (aspec
))
7664 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7669 tree chain
= protocol_list
;
7676 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7677 chain
= TREE_CHAIN (chain
);
7684 if (TREE_CHAIN (chain
))
7690 /* Type qualifiers. */
7691 if (TREE_READONLY (declspecs
))
7692 strcat (buf
, "const ");
7693 if (TYPE_VOLATILE (declspecs
))
7694 strcat (buf
, "volatile ");
7696 switch (TREE_CODE (declspecs
))
7698 /* Type specifiers. */
7701 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7703 /* Signed integer types. */
7705 if (declspecs
== short_integer_type_node
)
7706 strcat (buf
, "short int ");
7707 else if (declspecs
== integer_type_node
)
7708 strcat (buf
, "int ");
7709 else if (declspecs
== long_integer_type_node
)
7710 strcat (buf
, "long int ");
7711 else if (declspecs
== long_long_integer_type_node
)
7712 strcat (buf
, "long long int ");
7713 else if (declspecs
== signed_char_type_node
7714 || declspecs
== char_type_node
)
7715 strcat (buf
, "char ");
7717 /* Unsigned integer types. */
7719 else if (declspecs
== short_unsigned_type_node
)
7720 strcat (buf
, "unsigned short ");
7721 else if (declspecs
== unsigned_type_node
)
7722 strcat (buf
, "unsigned int ");
7723 else if (declspecs
== long_unsigned_type_node
)
7724 strcat (buf
, "unsigned long ");
7725 else if (declspecs
== long_long_unsigned_type_node
)
7726 strcat (buf
, "unsigned long long ");
7727 else if (declspecs
== unsigned_char_type_node
)
7728 strcat (buf
, "unsigned char ");
7732 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7734 if (declspecs
== float_type_node
)
7735 strcat (buf
, "float ");
7736 else if (declspecs
== double_type_node
)
7737 strcat (buf
, "double ");
7738 else if (declspecs
== long_double_type_node
)
7739 strcat (buf
, "long double ");
7743 if (TYPE_NAME (declspecs
)
7744 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7746 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7748 if (! TREE_STATIC_TEMPLATE (declspecs
))
7749 strcat (buf
, "struct ");
7750 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7754 tree chain
= protocol_list
;
7761 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7762 chain
= TREE_CHAIN (chain
);
7771 strcat (buf
, "untagged struct");
7777 if (TYPE_NAME (declspecs
)
7778 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7780 strcat (buf
, "union ");
7781 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7786 strcat (buf
, "untagged union ");
7790 if (TYPE_NAME (declspecs
)
7791 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7793 strcat (buf
, "enum ");
7794 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7799 strcat (buf
, "untagged enum ");
7803 strcat (buf
, "void ");
7808 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7813 tree chain
= protocol_list
;
7820 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7821 chain
= TREE_CHAIN (chain
);
7838 gen_declaration (atype_or_adecl
, buf
)
7839 tree atype_or_adecl
;
7844 if (TREE_CODE (atype_or_adecl
) == TREE_LIST
)
7846 tree declspecs
; /* "identifier_node", "record_type" */
7847 tree declarator
; /* "array_ref", "indirect_ref", "call_expr"... */
7849 /* We have a "raw", abstract declarator (typename). */
7850 declarator
= TREE_VALUE (atype_or_adecl
);
7851 declspecs
= TREE_PURPOSE (atype_or_adecl
);
7853 gen_declspecs (declspecs
, buf
, 1);
7857 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7864 tree declspecs
; /* "integer_type", "real_type", "record_type"... */
7865 tree declarator
; /* "array_type", "function_type", "pointer_type". */
7867 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7868 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7869 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7870 atype
= TREE_TYPE (atype_or_adecl
);
7872 /* Assume we have a *_type node. */
7873 atype
= atype_or_adecl
;
7875 if (is_complex_decl (atype
))
7879 /* Get the declaration specifier; it is at the end of the list. */
7880 declarator
= chain
= atype
;
7882 chain
= TREE_TYPE (chain
); /* not TREE_CHAIN (chain); */
7883 while (is_complex_decl (chain
));
7890 declarator
= NULL_TREE
;
7893 gen_declspecs (declspecs
, buf
, 0);
7895 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7896 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7897 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7899 const char *decl_name
=
7900 (DECL_NAME (atype_or_adecl
)
7901 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl
)) : "");
7906 strcat (buf
, gen_declarator (declarator
, declbuf
, decl_name
));
7909 else if (decl_name
[0])
7912 strcat (buf
, decl_name
);
7915 else if (declarator
)
7918 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7925 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7928 gen_method_decl (method
, buf
)
7934 if (RAW_TYPESPEC (method
) != objc_object_reference
)
7937 gen_declaration (TREE_TYPE (method
), buf
);
7941 chain
= METHOD_SEL_ARGS (method
);
7944 /* We have a chain of keyword_decls. */
7947 if (KEYWORD_KEY_NAME (chain
))
7948 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain
)));
7951 if (RAW_TYPESPEC (chain
) != objc_object_reference
)
7954 gen_declaration (TREE_TYPE (chain
), buf
);
7958 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain
)));
7959 if ((chain
= TREE_CHAIN (chain
)))
7964 if (METHOD_ADD_ARGS (method
) == (tree
)1)
7965 strcat (buf
, ", ...");
7966 else if (METHOD_ADD_ARGS (method
))
7968 /* We have a tree list node as generate by get_parm_info. */
7969 chain
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
7971 /* Know we have a chain of parm_decls. */
7975 gen_declaration (chain
, buf
);
7976 chain
= TREE_CHAIN (chain
);
7982 /* We have a unary selector. */
7983 strcat (buf
, IDENTIFIER_POINTER (METHOD_SEL_NAME (method
)));
7991 dump_interface (fp
, chain
)
7995 char *buf
= (char *)xmalloc (256);
7996 const char *my_name
= IDENTIFIER_POINTER (CLASS_NAME (chain
));
7997 tree ivar_decls
= CLASS_RAW_IVARS (chain
);
7998 tree nst_methods
= CLASS_NST_METHODS (chain
);
7999 tree cls_methods
= CLASS_CLS_METHODS (chain
);
8001 fprintf (fp
, "\n@interface %s", my_name
);
8003 if (CLASS_SUPER_NAME (chain
))
8005 const char *super_name
= IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain
));
8006 fprintf (fp
, " : %s\n", super_name
);
8013 fprintf (fp
, "{\n");
8017 fprintf (fp
, "\t%s;\n", gen_declaration (ivar_decls
, buf
));
8018 ivar_decls
= TREE_CHAIN (ivar_decls
);
8021 fprintf (fp
, "}\n");
8027 fprintf (fp
, "- %s;\n", gen_method_decl (nst_methods
, buf
));
8028 nst_methods
= TREE_CHAIN (nst_methods
);
8034 fprintf (fp
, "+ %s;\n", gen_method_decl (cls_methods
, buf
));
8035 cls_methods
= TREE_CHAIN (cls_methods
);
8037 fprintf (fp
, "\n@end");
8040 /* Demangle function for Objective-C */
8042 objc_demangle (mangled
)
8043 const char *mangled
;
8045 char *demangled
, *cp
;
8047 if (mangled
[0] == '_' &&
8048 (mangled
[1] == 'i' || mangled
[1] == 'c') &&
8051 cp
= demangled
= xmalloc(strlen(mangled
) + 2);
8052 if (mangled
[1] == 'i')
8053 *cp
++ = '-'; /* for instance method */
8055 *cp
++ = '+'; /* for class method */
8056 *cp
++ = '['; /* opening left brace */
8057 strcpy(cp
, mangled
+3); /* tack on the rest of the mangled name */
8058 while (*cp
&& *cp
== '_')
8059 cp
++; /* skip any initial underbars in class name */
8060 cp
= strchr(cp
, '_'); /* find first non-initial underbar */
8063 free(demangled
); /* not mangled name */
8066 if (cp
[1] == '_') /* easy case: no category name */
8068 *cp
++ = ' '; /* replace two '_' with one ' ' */
8069 strcpy(cp
, mangled
+ (cp
- demangled
) + 2);
8073 *cp
++ = '('; /* less easy case: category name */
8074 cp
= strchr(cp
, '_');
8077 free(demangled
); /* not mangled name */
8081 *cp
++ = ' '; /* overwriting 1st char of method name... */
8082 strcpy(cp
, mangled
+ (cp
- demangled
)); /* get it back */
8084 while (*cp
&& *cp
== '_')
8085 cp
++; /* skip any initial underbars in method name */
8088 *cp
= ':'; /* replace remaining '_' with ':' */
8089 *cp
++ = ']'; /* closing right brace */
8090 *cp
++ = 0; /* string terminator */
8094 return mangled
; /* not an objc mangled name */
8098 objc_printable_name (decl
, kind
)
8100 int kind ATTRIBUTE_UNUSED
;
8102 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl
)));
8108 /* Add the special tree codes of Objective C to the tables. */
8110 #define LAST_CODE LAST_AND_UNUSED_TREE_CODE
8112 gcc_obstack_init (&util_obstack
);
8113 util_firstobj
= (char *) obstack_finish (&util_obstack
);
8115 memcpy (tree_code_type
+ (int) LAST_CODE
,
8116 objc_tree_code_type
,
8117 (int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
);
8118 memcpy (tree_code_length
+ (int) LAST_CODE
,
8119 objc_tree_code_length
,
8120 (((int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
) * sizeof (int)));
8121 memcpy (tree_code_name
+ (int) LAST_CODE
,
8122 objc_tree_code_name
,
8123 (((int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
) * sizeof (char *)));
8125 errbuf
= (char *)xmalloc (BUFSIZE
);
8127 synth_module_prologue ();
8129 /* Change the default error function */
8130 decl_printable_name
= objc_printable_name
;
8136 struct imp_entry
*impent
;
8138 /* The internally generated initializers appear to have missing braces.
8139 Don't warn about this. */
8140 int save_warn_missing_braces
= warn_missing_braces
;
8141 warn_missing_braces
= 0;
8143 generate_forward_declaration_to_string_table ();
8145 #ifdef OBJC_PROLOGUE
8149 /* Process the static instances here because initialization of objc_symtab
8151 if (objc_static_instances
)
8152 generate_static_references ();
8154 if (implementation_context
|| class_names_chain
8155 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8156 generate_objc_symtab_decl ();
8158 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8160 implementation_context
= impent
->imp_context
;
8161 implementation_template
= impent
->imp_template
;
8163 UOBJC_CLASS_decl
= impent
->class_decl
;
8164 UOBJC_METACLASS_decl
= impent
->meta_decl
;
8166 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
8168 /* all of the following reference the string pool... */
8169 generate_ivar_lists ();
8170 generate_dispatch_tables ();
8171 generate_shared_structures ();
8175 generate_dispatch_tables ();
8176 generate_category (implementation_context
);
8180 /* If we are using an array of selectors, we must always
8181 finish up the array decl even if no selectors were used. */
8182 if (! flag_next_runtime
|| sel_ref_chain
)
8183 build_selector_translation_table ();
8186 generate_protocols ();
8188 if (implementation_context
|| class_names_chain
|| objc_static_instances
8189 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8191 /* Arrange for Objc data structures to be initialized at run time. */
8192 const char *init_name
= build_module_descriptor ();
8194 assemble_constructor (init_name
);
8197 /* Dump the class references. This forces the appropriate classes
8198 to be linked into the executable image, preserving unix archive
8199 semantics. This can be removed when we move to a more dynamically
8200 linked environment. */
8202 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
8204 handle_class_ref (chain
);
8205 if (TREE_PURPOSE (chain
))
8206 generate_classref_translation_entry (chain
);
8209 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8210 handle_impent (impent
);
8212 /* Dump the string table last. */
8214 generate_strings ();
8216 if (flag_gen_declaration
)
8218 add_class (implementation_context
);
8219 dump_interface (gen_declaration_file
, implementation_context
);
8227 /* Run through the selector hash tables and print a warning for any
8228 selector which has multiple methods. */
8230 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8231 for (hsh
= cls_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8234 tree meth
= hsh
->key
;
8235 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8239 warning ("potential selector conflict for method `%s'",
8240 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8241 warn_with_method ("found", type
, meth
);
8242 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8243 warn_with_method ("found", type
, loop
->value
);
8246 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8247 for (hsh
= nst_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8250 tree meth
= hsh
->key
;
8251 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8255 warning ("potential selector conflict for method `%s'",
8256 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8257 warn_with_method ("found", type
, meth
);
8258 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8259 warn_with_method ("found", type
, loop
->value
);
8263 warn_missing_braces
= save_warn_missing_braces
;
8266 /* Subroutines of finish_objc. */
8269 generate_classref_translation_entry (chain
)
8272 tree expr
, name
, decl_specs
, decl
, sc_spec
;
8275 type
= TREE_TYPE (TREE_PURPOSE (chain
));
8277 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
8278 expr
= build_c_cast (type
, expr
); /* cast! */
8280 name
= DECL_NAME (TREE_PURPOSE (chain
));
8282 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
8284 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8285 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
8287 /* The decl that is returned from start_decl is the one that we
8288 forward declared in build_class_reference. */
8289 decl
= start_decl (name
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
8290 finish_decl (decl
, expr
, NULL_TREE
);
8295 handle_class_ref (chain
)
8298 const char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
8299 if (! flag_next_runtime
)
8302 char *string
= (char *) alloca (strlen (name
) + 30);
8305 sprintf (string
, "%sobjc_class_name_%s",
8306 (flag_next_runtime
? "." : "__"), name
);
8308 /* Make a decl for this name, so we can use its address in a tree. */
8309 decl
= build_decl (VAR_DECL
, get_identifier (string
), char_type_node
);
8310 DECL_EXTERNAL (decl
) = 1;
8311 TREE_PUBLIC (decl
) = 1;
8314 rest_of_decl_compilation (decl
, 0, 0, 0);
8316 /* Make following constant read-only (why not)? */
8317 readonly_data_section ();
8319 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
8321 /* Align the section properly. */
8322 assemble_constant_align (exp
);
8324 /* Inform the assembler about this new external thing. */
8325 assemble_external (decl
);
8327 /* Output a constant to reference this address. */
8328 output_constant (exp
, int_size_in_bytes (string_type_node
));
8332 /* This overreliance on our assembler (i.e. lack of portability)
8333 should be dealt with at some point. The GNU strategy (above)
8334 won't work either, but it is a start. */
8335 char *string
= (char *) alloca (strlen (name
) + 30);
8336 sprintf (string
, ".reference .objc_class_name_%s", name
);
8337 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8342 handle_impent (impent
)
8343 struct imp_entry
*impent
;
8345 implementation_context
= impent
->imp_context
;
8346 implementation_template
= impent
->imp_template
;
8348 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
8350 const char *class_name
=
8351 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8352 char *string
= (char *) alloca (strlen (class_name
) + 30);
8354 if (flag_next_runtime
)
8356 /* Grossly unportable.
8357 People should know better than to assume
8358 such things about assembler syntax! */
8359 sprintf (string
, ".objc_class_name_%s=0", class_name
);
8360 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8362 sprintf (string
, ".globl .objc_class_name_%s", class_name
);
8363 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8368 sprintf (string
, "%sobjc_class_name_%s",
8369 (flag_next_runtime
? "." : "__"), class_name
);
8370 assemble_global (string
);
8371 assemble_label (string
);
8375 else if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
8377 const char *class_name
=
8378 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8379 const char *class_super_name
=
8380 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
8381 char *string
= (char *) alloca (strlen (class_name
)
8382 + strlen (class_super_name
) + 30);
8384 /* Do the same for categories. Even though no references to these
8385 symbols are generated automatically by the compiler, it gives
8386 you a handle to pull them into an archive by hand. */
8387 if (flag_next_runtime
)
8389 /* Grossly unportable. */
8390 sprintf (string
, ".objc_category_name_%s_%s=0",
8391 class_name
, class_super_name
);
8392 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8394 sprintf (string
, ".globl .objc_category_name_%s_%s",
8395 class_name
, class_super_name
);
8396 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8401 sprintf (string
, "%sobjc_category_name_%s_%s",
8402 (flag_next_runtime
? "." : "__"),
8403 class_name
, class_super_name
);
8404 assemble_global (string
);
8405 assemble_label (string
);
8416 char *buf
= (char *)xmalloc (256);
8418 { /* dump function prototypes */
8419 tree loop
= UOBJC_MODULES_decl
;
8421 fprintf (fp
, "\n\nfunction prototypes:\n");
8424 if (TREE_CODE (loop
) == FUNCTION_DECL
&& DECL_INITIAL (loop
))
8426 /* We have a function definition: generate prototype. */
8427 bzero (errbuf
, BUFSIZE
);
8428 gen_declaration (loop
, errbuf
);
8429 fprintf (fp
, "%s;\n", errbuf
);
8431 loop
= TREE_CHAIN (loop
);
8435 /* Dump global chains. */
8437 int i
, index
= 0, offset
= 0;
8440 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
8442 if (hashlist
= nst_method_hash_list
[i
])
8444 fprintf (fp
, "\n\nnst_method_hash_list[%d]:\n", i
);
8448 fprintf (fp
, "-%s;\n", gen_method_decl (hashlist
->key
, buf
));
8449 hashlist
= hashlist
->next
;
8455 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
8457 if (hashlist
= cls_method_hash_list
[i
])
8459 fprintf (fp
, "\n\ncls_method_hash_list[%d]:\n", i
);
8463 fprintf (fp
, "-%s;\n", gen_method_decl (hashlist
->key
, buf
));
8464 hashlist
= hashlist
->next
;
8470 fprintf (fp
, "\nsel_refdef_chain:\n");
8471 for (loop
= sel_refdef_chain
; loop
; loop
= TREE_CHAIN (loop
))
8473 fprintf (fp
, "(index: %4d offset: %4d) %s\n", index
, offset
,
8474 IDENTIFIER_POINTER (TREE_VALUE (loop
)));
8476 /* add one for the '\0' character */
8477 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (loop
)) + 1;
8480 fprintf (fp
, "\n (max_selector_index: %4d.\n", max_selector_index
);
8486 print_lang_statistics ()