1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 93-95, 97, 1998 Free Software Foundation, Inc.
3 Contributed by Steve Naroff.
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* Purpose: This module implements the Objective-C 4.0 language.
24 compatibility issues (with the Stepstone translator):
26 - does not recognize the following 3.3 constructs.
27 @requires, @classes, @messages, = (...)
28 - methods with variable arguments must conform to ANSI standard.
29 - tagged structure definitions that appear in BOTH the interface
30 and implementation are not allowed.
31 - public/private: all instance variables are public within the
32 context of the implementation...I consider this to be a bug in
34 - statically allocated objects are not supported. the user will
35 receive an error if this service is requested.
37 code generation `options':
39 - OBJC_INT_SELECTORS */
56 extern cpp_reader parse_in
;
57 extern cpp_options parse_options
;
60 /* This is the default way of generating a method name. */
61 /* I am not sure it is really correct.
62 Perhaps there's a danger that it will make name conflicts
63 if method names contain underscores. -- rms. */
64 #ifndef OBJC_GEN_METHOD_LABEL
65 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
68 sprintf ((BUF), "_%s_%s_%s_%s", \
69 ((IS_INST) ? "i" : "c"), \
71 ((CAT_NAME)? (CAT_NAME) : ""), \
73 for (temp = (BUF); *temp; temp++) \
74 if (*temp == ':') *temp = '_'; \
78 /* These need specifying. */
79 #ifndef OBJC_FORWARDING_STACK_OFFSET
80 #define OBJC_FORWARDING_STACK_OFFSET 0
83 #ifndef OBJC_FORWARDING_MIN_OFFSET
84 #define OBJC_FORWARDING_MIN_OFFSET 0
87 /* Define the special tree codes that we use. */
89 /* Table indexed by tree code giving a string containing a character
90 classifying the tree code. Possibilities are
91 t, d, s, c, r, <, 1 and 2. See objc-tree.def for details. */
93 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
95 char objc_tree_code_type
[] = {
97 #include "objc-tree.def"
101 /* Table indexed by tree code giving number of expression
102 operands beyond the fixed part of the node structure.
103 Not used for types or decls. */
105 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
107 int objc_tree_code_length
[] = {
109 #include "objc-tree.def"
113 /* Names of tree components.
114 Used for printing out the tree and error messages. */
115 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
117 char *objc_tree_code_name
[] = {
119 #include "objc-tree.def"
123 /* Set up for use of obstacks. */
127 #define obstack_chunk_alloc xmalloc
128 #define obstack_chunk_free free
130 /* This obstack is used to accumulate the encoding of a data type. */
131 static struct obstack util_obstack
;
132 /* This points to the beginning of obstack contents,
133 so we can free the whole contents. */
136 /* List of classes with list of their static instances. */
137 static tree objc_static_instances
= NULL_TREE
;
139 /* The declaration of the array administrating the static instances. */
140 static tree static_instances_decl
= NULL_TREE
;
142 /* for encode_method_def */
146 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
147 #define PROTOCOL_VERSION 2
149 #define OBJC_ENCODE_INLINE_DEFS 0
150 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
152 /*** Private Interface (procedures) ***/
154 /* Used by compile_file. */
156 static void init_objc
PROTO((void));
157 static void finish_objc
PROTO((void));
159 /* Code generation. */
161 static void synth_module_prologue
PROTO((void));
162 static tree build_constructor
PROTO((tree
, tree
));
163 static char *build_module_descriptor
PROTO((void));
164 static tree init_module_descriptor
PROTO((tree
));
165 static tree build_objc_method_call
PROTO((int, tree
, tree
,
167 static void generate_strings
PROTO((void));
168 static tree get_proto_encoding
PROTO((tree
));
169 static void build_selector_translation_table
PROTO((void));
170 static tree build_ivar_chain
PROTO((tree
, int));
172 static tree objc_add_static_instance
PROTO((tree
, tree
));
174 static tree build_ivar_template
PROTO((void));
175 static tree build_method_template
PROTO((void));
176 static tree build_private_template
PROTO((tree
));
177 static void build_class_template
PROTO((void));
178 static void build_selector_template
PROTO((void));
179 static void build_category_template
PROTO((void));
180 static tree build_super_template
PROTO((void));
181 static tree build_category_initializer
PROTO((tree
, tree
, tree
,
183 static tree build_protocol_initializer
PROTO((tree
, tree
, tree
,
186 static void synth_forward_declarations
PROTO((void));
187 static void generate_ivar_lists
PROTO((void));
188 static void generate_dispatch_tables
PROTO((void));
189 static void generate_shared_structures
PROTO((void));
190 static tree generate_protocol_list
PROTO((tree
));
191 static void generate_forward_declaration_to_string_table
PROTO((void));
192 static void build_protocol_reference
PROTO((tree
));
195 static tree init_selector
PROTO((int));
197 static tree build_keyword_selector
PROTO((tree
));
198 static tree synth_id_with_class_suffix
PROTO((char *, tree
));
200 static void generate_static_references
PROTO((void));
201 static int check_methods_accessible
PROTO((tree
, tree
,
203 static void encode_aggregate_within
PROTO((tree
, int, int,
206 /* We handle printing method names ourselves for ObjC */
207 extern char *(*decl_printable_name
) ();
209 /* Misc. bookkeeping */
211 typedef struct hashed_entry
*hash
;
212 typedef struct hashed_attribute
*attr
;
214 struct hashed_attribute
226 static void hash_init
PROTO((void));
227 static void hash_enter
PROTO((hash
*, tree
));
228 static hash hash_lookup
PROTO((hash
*, tree
));
229 static void hash_add_attr
PROTO((hash
, tree
));
230 static tree lookup_method
PROTO((tree
, tree
));
231 static tree lookup_instance_method_static
PROTO((tree
, tree
));
232 static tree lookup_class_method_static
PROTO((tree
, tree
));
233 static tree add_class
PROTO((tree
));
234 static void add_category
PROTO((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
PROTO((tree
,
244 enum string_section
));
245 static tree get_objc_string_decl
PROTO((tree
,
246 enum string_section
));
247 static tree build_objc_string_decl
PROTO((tree
,
248 enum string_section
));
249 static tree build_selector_reference_decl
PROTO((tree
));
251 /* Protocol additions. */
253 static tree add_protocol
PROTO((tree
));
254 static tree lookup_protocol
PROTO((tree
));
255 static tree lookup_and_install_protocols
PROTO((tree
));
259 static void encode_type_qualifiers
PROTO((tree
));
260 static void encode_pointer
PROTO((tree
, int, int));
261 static void encode_array
PROTO((tree
, int, int));
262 static void encode_aggregate
PROTO((tree
, int, int));
263 static void encode_bitfield
PROTO((int, int));
264 static void encode_type
PROTO((tree
, int, int));
265 static void encode_field_decl
PROTO((tree
, int, int));
267 static void really_start_method
PROTO((tree
, tree
));
268 static int comp_method_with_proto
PROTO((tree
, tree
));
269 static int comp_proto_with_proto
PROTO((tree
, tree
));
270 static tree get_arg_type_list
PROTO((tree
, int, int));
271 static tree expr_last
PROTO((tree
));
273 /* Utilities for debugging and error diagnostics. */
275 static void warn_with_method
PROTO((char *, int, tree
));
276 static void error_with_ivar
PROTO((char *, tree
, tree
));
277 static char *gen_method_decl
PROTO((tree
, char *));
278 static char *gen_declaration
PROTO((tree
, char *));
279 static char *gen_declarator
PROTO((tree
, char *, char *));
280 static int is_complex_decl
PROTO((tree
));
281 static void adorn_decl
PROTO((tree
, char *));
282 static void dump_interface
PROTO((FILE *, tree
));
284 /* Everything else. */
286 static void objc_fatal
PROTO((void))
288 static tree define_decl
PROTO((tree
, tree
));
289 static tree lookup_method_in_protocol_list
PROTO((tree
, tree
, int));
290 static tree lookup_protocol_in_reflist
PROTO((tree
, tree
));
291 static tree create_builtin_decl
PROTO((enum tree_code
,
293 static tree my_build_string
PROTO((int, char *));
294 static void build_objc_symtab_template
PROTO((void));
295 static tree init_def_list
PROTO((tree
));
296 static tree init_objc_symtab
PROTO((tree
));
297 static void forward_declare_categories
PROTO((void));
298 static void generate_objc_symtab_decl
PROTO((void));
299 static tree build_selector
PROTO((tree
));
301 static tree build_msg_pool_reference
PROTO((int));
303 static tree build_typed_selector_reference
PROTO((tree
, tree
));
304 static tree build_selector_reference
PROTO((tree
));
305 static tree build_class_reference_decl
PROTO((tree
));
306 static void add_class_reference
PROTO((tree
));
307 static tree objc_copy_list
PROTO((tree
, tree
*));
308 static tree build_protocol_template
PROTO((void));
309 static tree build_descriptor_table_initializer
PROTO((tree
, tree
));
310 static tree build_method_prototype_list_template
PROTO((tree
, int));
311 static tree build_method_prototype_template
PROTO((void));
312 static int forwarding_offset
PROTO((tree
));
313 static tree encode_method_prototype
PROTO((tree
, tree
));
314 static tree generate_descriptor_table
PROTO((tree
, char *, int, tree
, tree
));
315 static void generate_method_descriptors
PROTO((tree
));
316 static tree build_tmp_function_decl
PROTO((void));
317 static void hack_method_prototype
PROTO((tree
, tree
));
318 static void generate_protocol_references
PROTO((tree
));
319 static void generate_protocols
PROTO((void));
320 static void check_ivars
PROTO((tree
, tree
));
321 static tree build_ivar_list_template
PROTO((tree
, int));
322 static tree build_method_list_template
PROTO((tree
, int));
323 static tree build_ivar_list_initializer
PROTO((tree
, tree
));
324 static tree generate_ivars_list
PROTO((tree
, char *,
326 static tree build_dispatch_table_initializer
PROTO((tree
, tree
));
327 static tree generate_dispatch_table
PROTO((tree
, char *,
329 static tree build_shared_structure_initializer
PROTO((tree
, tree
, tree
, tree
,
330 tree
, int, tree
, tree
,
332 static void generate_category
PROTO((tree
));
333 static int is_objc_type_qualifier
PROTO((tree
));
334 static tree adjust_type_for_id_default
PROTO((tree
));
335 static tree check_duplicates
PROTO((hash
));
336 static tree receiver_is_class_object
PROTO((tree
));
337 static int check_methods
PROTO((tree
, tree
, int));
338 static int conforms_to_protocol
PROTO((tree
, tree
));
339 static void check_protocols
PROTO((tree
, char *, char *));
340 static tree encode_method_def
PROTO((tree
));
341 static void gen_declspecs
PROTO((tree
, char *, int));
342 static void generate_classref_translation_entry
PROTO((tree
));
343 static void handle_class_ref
PROTO((tree
));
345 /*** Private Interface (data) ***/
347 /* Reserved tag definitions. */
350 #define TAG_OBJECT "objc_object"
351 #define TAG_CLASS "objc_class"
352 #define TAG_SUPER "objc_super"
353 #define TAG_SELECTOR "objc_selector"
355 #define UTAG_CLASS "_objc_class"
356 #define UTAG_IVAR "_objc_ivar"
357 #define UTAG_IVAR_LIST "_objc_ivar_list"
358 #define UTAG_METHOD "_objc_method"
359 #define UTAG_METHOD_LIST "_objc_method_list"
360 #define UTAG_CATEGORY "_objc_category"
361 #define UTAG_MODULE "_objc_module"
362 #define UTAG_STATICS "_objc_statics"
363 #define UTAG_SYMTAB "_objc_symtab"
364 #define UTAG_SUPER "_objc_super"
365 #define UTAG_SELECTOR "_objc_selector"
367 #define UTAG_PROTOCOL "_objc_protocol"
368 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
369 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
370 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
372 #define STRING_OBJECT_CLASS_NAME "NXConstantString"
373 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
375 static char *TAG_GETCLASS
;
376 static char *TAG_GETMETACLASS
;
377 static char *TAG_MSGSEND
;
378 static char *TAG_MSGSENDSUPER
;
379 static char *TAG_EXECCLASS
;
381 /* Set by `continue_class' and checked by `is_public'. */
383 #define TREE_STATIC_TEMPLATE(record_type) (TREE_PUBLIC (record_type))
384 #define TYPED_OBJECT(type) \
385 (TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type))
387 /* Some commonly used instances of "identifier_node". */
389 static tree self_id
, ucmd_id
;
390 static tree unused_list
;
392 static tree self_decl
, umsg_decl
, umsg_super_decl
;
393 static tree objc_get_class_decl
, objc_get_meta_class_decl
;
395 static tree super_type
, selector_type
, id_type
, objc_class_type
;
396 static tree instance_type
, protocol_type
;
398 /* Type checking macros. */
400 #define IS_ID(TYPE) \
401 (TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (id_type))
402 #define IS_PROTOCOL_QUALIFIED_ID(TYPE) \
403 (IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE))
404 #define IS_SUPER(TYPE) \
405 (super_type && TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (super_type))
407 static tree class_chain
= NULL_TREE
;
408 static tree alias_chain
= NULL_TREE
;
409 static tree interface_chain
= NULL_TREE
;
410 static tree protocol_chain
= NULL_TREE
;
412 /* Chains to manage selectors that are referenced and defined in the
415 static tree cls_ref_chain
= NULL_TREE
; /* Classes referenced. */
416 static tree sel_ref_chain
= NULL_TREE
; /* Selectors referenced. */
418 /* Chains to manage uniquing of strings. */
420 static tree class_names_chain
= NULL_TREE
;
421 static tree meth_var_names_chain
= NULL_TREE
;
422 static tree meth_var_types_chain
= NULL_TREE
;
424 /* Hash tables to manage the global pool of method prototypes. */
426 static hash
*nst_method_hash_list
= 0;
427 static hash
*cls_method_hash_list
= 0;
429 /* Backend data declarations. */
431 static tree UOBJC_SYMBOLS_decl
;
432 static tree UOBJC_INSTANCE_VARIABLES_decl
, UOBJC_CLASS_VARIABLES_decl
;
433 static tree UOBJC_INSTANCE_METHODS_decl
, UOBJC_CLASS_METHODS_decl
;
434 static tree UOBJC_CLASS_decl
, UOBJC_METACLASS_decl
;
435 static tree UOBJC_SELECTOR_TABLE_decl
;
436 static tree UOBJC_MODULES_decl
;
437 static tree UOBJC_STRINGS_decl
;
439 /* The following are used when compiling a class implementation.
440 implementation_template will normally be an interface, however if
441 none exists this will be equal to implementation_context...it is
442 set in start_class. */
444 static tree implementation_context
= NULL_TREE
;
445 static tree implementation_template
= NULL_TREE
;
449 struct imp_entry
*next
;
452 tree class_decl
; /* _OBJC_CLASS_<my_name>; */
453 tree meta_decl
; /* _OBJC_METACLASS_<my_name>; */
456 static void handle_impent
PROTO((struct imp_entry
*));
458 static struct imp_entry
*imp_list
= 0;
459 static int imp_count
= 0; /* `@implementation' */
460 static int cat_count
= 0; /* `@category' */
462 static tree objc_class_template
, objc_category_template
, uprivate_record
;
463 static tree objc_protocol_template
, objc_selector_template
;
464 static tree ucls_super_ref
, uucls_super_ref
;
466 static tree objc_method_template
, objc_ivar_template
;
467 static tree objc_symtab_template
, objc_module_template
;
468 static tree objc_super_template
, objc_object_reference
;
470 static tree objc_object_id
, objc_class_id
, objc_id_id
;
471 static tree constant_string_id
;
472 static tree constant_string_type
;
473 static tree UOBJC_SUPER_decl
;
475 static tree method_context
= NULL_TREE
;
476 static int method_slot
= 0; /* Used by start_method_def, */
480 static char *errbuf
; /* Buffer for error diagnostics */
482 /* Data imported from tree.c. */
484 extern enum debug_info_type write_symbols
;
486 /* Data imported from toplev.c. */
488 extern char *dump_base_name
;
490 /* Generate code for GNU or NeXT runtime environment. */
492 #ifdef NEXT_OBJC_RUNTIME
493 int flag_next_runtime
= 1;
495 int flag_next_runtime
= 0;
498 int flag_typed_selectors
;
500 /* Open and close the file for outputting class declarations, if requested. */
502 int flag_gen_declaration
= 0;
504 FILE *gen_declaration_file
;
506 /* Warn if multiple methods are seen for the same selector, but with
507 different argument types. */
509 int warn_selector
= 0;
511 /* Warn if methods required by a protocol are not implemented in the
512 class adopting it. When turned off, methods inherited to that
513 class are also considered implemented */
515 int flag_warn_protocol
= 1;
517 /* Tells "encode_pointer/encode_aggregate" whether we are generating
518 type descriptors for instance variables (as opposed to methods).
519 Type descriptors for instance variables contain more information
520 than methods (for static typing and embedded structures). This
521 was added to support features being planned for dbkit2. */
523 static int generating_instance_variables
= 0;
525 /* Tells the compiler that this is a special run. Do not perform
526 any compiling, instead we are to test some platform dependent
527 features and output a C header file with appropriate definitions. */
529 static int print_struct_values
= 0;
531 /* Some platforms pass small structures through registers versus through
532 an invisible pointer. Determine at what size structure is the
533 transition point between the two possibilities. */
536 generate_struct_by_value_array ()
539 tree field_decl
, field_decl_chain
;
541 int aggregate_in_mem
[32];
544 /* Presumbaly no platform passes 32 byte structures in a register. */
545 for (i
= 1; i
< 32; i
++)
549 /* Create an unnamed struct that has `i' character components */
550 type
= start_struct (RECORD_TYPE
, NULL_TREE
);
552 strcpy (buffer
, "c1");
553 field_decl
= create_builtin_decl (FIELD_DECL
,
556 field_decl_chain
= field_decl
;
558 for (j
= 1; j
< i
; j
++)
560 sprintf (buffer
, "c%d", j
+ 1);
561 field_decl
= create_builtin_decl (FIELD_DECL
,
564 chainon (field_decl_chain
, field_decl
);
566 finish_struct (type
, field_decl_chain
, NULL_TREE
);
568 aggregate_in_mem
[i
] = aggregate_value_p (type
);
569 if (!aggregate_in_mem
[i
])
573 /* We found some structures that are returned in registers instead of memory
574 so output the necessary data. */
577 for (i
= 31; i
>= 0; i
--)
578 if (!aggregate_in_mem
[i
])
580 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i
);
582 /* The first member of the structure is always 0 because we don't handle
583 structures with 0 members */
584 printf ("static int struct_forward_array[] = {\n 0");
586 for (j
= 1; j
<= i
; j
++)
587 printf (", %d", aggregate_in_mem
[j
]);
602 cpp_reader_init (&parse_in
);
603 parse_in
.opts
= &parse_options
;
604 cpp_options_init (&parse_options
);
612 /* The beginning of the file is a new line; check for #.
613 With luck, we discover the real source file's name from that
614 and put it in input_filename. */
615 ungetc (check_newline (), finput
);
621 /* The line number can be -1 if we had -g3 and the input file
622 had a directive specifying line 0. But we want predefined
623 functions to have a line number of 0, not -1. */
627 /* If gen_declaration desired, open the output file. */
628 if (flag_gen_declaration
)
630 int dump_base_name_length
= strlen (dump_base_name
);
631 register char *dumpname
= (char *) xmalloc (dump_base_name_length
+ 7);
632 strcpy (dumpname
, dump_base_name
);
633 strcat (dumpname
, ".decl");
634 gen_declaration_file
= fopen (dumpname
, "w");
635 if (gen_declaration_file
== 0)
636 pfatal_with_name (dumpname
);
639 if (flag_next_runtime
)
641 TAG_GETCLASS
= "objc_getClass";
642 TAG_GETMETACLASS
= "objc_getMetaClass";
643 TAG_MSGSEND
= "objc_msgSend";
644 TAG_MSGSENDSUPER
= "objc_msgSendSuper";
645 TAG_EXECCLASS
= "__objc_execClass";
649 TAG_GETCLASS
= "objc_get_class";
650 TAG_GETMETACLASS
= "objc_get_meta_class";
651 TAG_MSGSEND
= "objc_msg_lookup";
652 TAG_MSGSENDSUPER
= "objc_msg_lookup_super";
653 TAG_EXECCLASS
= "__objc_exec_class";
654 flag_typed_selectors
= 1;
657 if (doing_objc_thang
)
660 if (print_struct_values
)
661 generate_struct_by_value_array ();
667 fatal ("Objective-C text in C source file");
673 if (doing_objc_thang
)
674 finish_objc (); /* Objective-C finalization */
676 if (gen_declaration_file
)
677 fclose (gen_declaration_file
);
692 lang_decode_option (argc
, argv
)
697 if (!strcmp (p
, "-lang-objc"))
698 doing_objc_thang
= 1;
699 else if (!strcmp (p
, "-gen-decls"))
700 flag_gen_declaration
= 1;
701 else if (!strcmp (p
, "-Wselector"))
703 else if (!strcmp (p
, "-Wno-selector"))
705 else if (!strcmp (p
, "-Wprotocol"))
706 flag_warn_protocol
= 1;
707 else if (!strcmp (p
, "-Wno-protocol"))
708 flag_warn_protocol
= 0;
709 else if (!strcmp (p
, "-fgnu-runtime"))
710 flag_next_runtime
= 0;
711 else if (!strcmp (p
, "-fno-next-runtime"))
712 flag_next_runtime
= 0;
713 else if (!strcmp (p
, "-fno-gnu-runtime"))
714 flag_next_runtime
= 1;
715 else if (!strcmp (p
, "-fnext-runtime"))
716 flag_next_runtime
= 1;
717 else if (!strcmp (p
, "-print-objc-runtime-info"))
718 print_struct_values
= 1;
720 return c_decode_option (argc
, argv
);
725 /* used by print-tree.c */
728 lang_print_xnode (file
, node
, indent
)
729 FILE *file ATTRIBUTE_UNUSED
;
730 tree node ATTRIBUTE_UNUSED
;
731 int indent ATTRIBUTE_UNUSED
;
737 define_decl (declarator
, declspecs
)
741 tree decl
= start_decl (declarator
, declspecs
, 0, NULL_TREE
, NULL_TREE
);
742 finish_decl (decl
, NULL_TREE
, NULL_TREE
);
746 /* Return 1 if LHS and RHS are compatible types for assignment or
747 various other operations. Return 0 if they are incompatible, and
748 return -1 if we choose to not decide. When the operation is
749 REFLEXIVE, check for compatibility in either direction.
751 For statically typed objects, an assignment of the form `a' = `b'
755 `a' and `b' are the same class type, or
756 `a' and `b' are of class types A and B such that B is a descendant of A. */
759 maybe_objc_comptypes (lhs
, rhs
, reflexive
)
763 if (doing_objc_thang
)
764 return objc_comptypes (lhs
, rhs
, reflexive
);
769 lookup_method_in_protocol_list (rproto_list
, sel_name
, class_meth
)
777 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
779 p
= TREE_VALUE (rproto
);
781 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
783 if ((fnd
= lookup_method (class_meth
784 ? PROTOCOL_CLS_METHODS (p
)
785 : PROTOCOL_NST_METHODS (p
), sel_name
)))
787 else if (PROTOCOL_LIST (p
))
788 fnd
= lookup_method_in_protocol_list (PROTOCOL_LIST (p
),
789 sel_name
, class_meth
);
793 ; /* An identifier...if we could not find a protocol. */
804 lookup_protocol_in_reflist (rproto_list
, lproto
)
810 /* Make sure the protocol is support by the object on the rhs. */
811 if (TREE_CODE (lproto
) == PROTOCOL_INTERFACE_TYPE
)
814 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
816 p
= TREE_VALUE (rproto
);
818 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
823 else if (PROTOCOL_LIST (p
))
824 fnd
= lookup_protocol_in_reflist (PROTOCOL_LIST (p
), lproto
);
833 ; /* An identifier...if we could not find a protocol. */
839 /* Return 1 if LHS and RHS are compatible types for assignment
840 or various other operations. Return 0 if they are incompatible,
841 and return -1 if we choose to not decide. When the operation
842 is REFLEXIVE, check for compatibility in either direction. */
845 objc_comptypes (lhs
, rhs
, reflexive
)
850 /* New clause for protocols. */
852 if (TREE_CODE (lhs
) == POINTER_TYPE
853 && TREE_CODE (TREE_TYPE (lhs
)) == RECORD_TYPE
854 && TREE_CODE (rhs
) == POINTER_TYPE
855 && TREE_CODE (TREE_TYPE (rhs
)) == RECORD_TYPE
)
857 int lhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (lhs
);
858 int rhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (rhs
);
862 tree lproto
, lproto_list
= TYPE_PROTOCOL_LIST (lhs
);
863 tree rproto
, rproto_list
;
868 rproto_list
= TYPE_PROTOCOL_LIST (rhs
);
870 /* Make sure the protocol is supported by the object
872 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
874 p
= TREE_VALUE (lproto
);
875 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
878 warning ("object does not conform to the `%s' protocol",
879 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
882 else if (TYPED_OBJECT (TREE_TYPE (rhs
)))
884 tree rname
= TYPE_NAME (TREE_TYPE (rhs
));
887 /* Make sure the protocol is supported by the object
889 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
891 p
= TREE_VALUE (lproto
);
893 rinter
= lookup_interface (rname
);
895 while (rinter
&& !rproto
)
899 rproto_list
= CLASS_PROTOCOL_LIST (rinter
);
900 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
902 /* Check for protocols adopted by categories. */
903 cat
= CLASS_CATEGORY_LIST (rinter
);
904 while (cat
&& !rproto
)
906 rproto_list
= CLASS_PROTOCOL_LIST (cat
);
907 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
909 cat
= CLASS_CATEGORY_LIST (cat
);
912 rinter
= lookup_interface (CLASS_SUPER_NAME (rinter
));
916 warning ("class `%s' does not implement the `%s' protocol",
917 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs
))),
918 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
922 /* May change...based on whether there was any mismatch */
925 else if (rhs_is_proto
)
926 /* Lhs is not a protocol...warn if it is statically typed */
927 return (TYPED_OBJECT (TREE_TYPE (lhs
)) != 0);
930 /* Defer to comptypes .*/
934 else if (TREE_CODE (lhs
) == RECORD_TYPE
&& TREE_CODE (rhs
) == RECORD_TYPE
)
935 ; /* Fall thru. This is the case we have been handling all along */
937 /* Defer to comptypes. */
940 /* `id' = `<class> *', `<class> *' = `id' */
942 if ((TYPE_NAME (lhs
) == objc_object_id
&& TYPED_OBJECT (rhs
))
943 || (TYPE_NAME (rhs
) == objc_object_id
&& TYPED_OBJECT (lhs
)))
946 /* `id' = `Class', `Class' = `id' */
948 else if ((TYPE_NAME (lhs
) == objc_object_id
949 && TYPE_NAME (rhs
) == objc_class_id
)
950 || (TYPE_NAME (lhs
) == objc_class_id
951 && TYPE_NAME (rhs
) == objc_object_id
))
954 /* `<class> *' = `<class> *' */
956 else if (TYPED_OBJECT (lhs
) && TYPED_OBJECT (rhs
))
958 tree lname
= TYPE_NAME (lhs
);
959 tree rname
= TYPE_NAME (rhs
);
965 /* If the left hand side is a super class of the right hand side,
967 for (inter
= lookup_interface (rname
); inter
;
968 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
969 if (lname
== CLASS_SUPER_NAME (inter
))
972 /* Allow the reverse when reflexive. */
974 for (inter
= lookup_interface (lname
); inter
;
975 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
976 if (rname
== CLASS_SUPER_NAME (inter
))
982 /* Defer to comptypes. */
986 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
989 objc_check_decl (decl
)
992 tree type
= TREE_TYPE (decl
);
994 if (TREE_CODE (type
) == RECORD_TYPE
995 && TREE_STATIC_TEMPLATE (type
)
996 && type
!= constant_string_type
)
998 error_with_decl (decl
, "`%s' cannot be statically allocated");
999 fatal ("statically allocated objects not supported");
1004 maybe_objc_check_decl (decl
)
1007 if (doing_objc_thang
)
1008 objc_check_decl (decl
);
1011 /* Implement static typing. At this point, we know we have an interface. */
1014 get_static_reference (interface
, protocols
)
1018 tree type
= xref_tag (RECORD_TYPE
, interface
);
1022 tree t
, m
= TYPE_MAIN_VARIANT (type
);
1024 push_obstacks_nochange ();
1025 end_temporary_allocation ();
1026 t
= copy_node (type
);
1027 TYPE_BINFO (t
) = make_tree_vec (2);
1030 /* Add this type to the chain of variants of TYPE. */
1031 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
1032 TYPE_NEXT_VARIANT (m
) = t
;
1034 /* Look up protocols and install in lang specific list. */
1035 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
1037 /* This forces a new pointer type to be created later
1038 (in build_pointer_type)...so that the new template
1039 we just created will actually be used...what a hack! */
1040 if (TYPE_POINTER_TO (t
))
1041 TYPE_POINTER_TO (t
) = 0;
1050 get_object_reference (protocols
)
1053 tree type_decl
= lookup_name (objc_id_id
);
1056 if (type_decl
&& TREE_CODE (type_decl
) == TYPE_DECL
)
1058 type
= TREE_TYPE (type_decl
);
1059 if (TYPE_MAIN_VARIANT (type
) != id_type
)
1060 warning ("Unexpected type for `id' (%s)",
1061 gen_declaration (type
, errbuf
));
1064 fatal ("Undefined type `id', please import <objc/objc.h>");
1066 /* This clause creates a new pointer type that is qualified with
1067 the protocol specification...this info is used later to do more
1068 elaborate type checking. */
1072 tree t
, m
= TYPE_MAIN_VARIANT (type
);
1074 push_obstacks_nochange ();
1075 end_temporary_allocation ();
1076 t
= copy_node (type
);
1077 TYPE_BINFO (t
) = make_tree_vec (2);
1080 /* Add this type to the chain of variants of TYPE. */
1081 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
1082 TYPE_NEXT_VARIANT (m
) = t
;
1084 /* Look up protocols...and install in lang specific list */
1085 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
1087 /* This forces a new pointer type to be created later
1088 (in build_pointer_type)...so that the new template
1089 we just created will actually be used...what a hack! */
1090 if (TYPE_POINTER_TO (t
))
1091 TYPE_POINTER_TO (t
) = NULL
;
1099 lookup_and_install_protocols (protocols
)
1104 tree return_value
= protocols
;
1106 for (proto
= protocols
; proto
; proto
= TREE_CHAIN (proto
))
1108 tree ident
= TREE_VALUE (proto
);
1109 tree p
= lookup_protocol (ident
);
1113 error ("Cannot find protocol declaration for `%s'",
1114 IDENTIFIER_POINTER (ident
));
1116 TREE_CHAIN (prev
) = TREE_CHAIN (proto
);
1118 return_value
= TREE_CHAIN (proto
);
1122 /* Replace identifier with actual protocol node. */
1123 TREE_VALUE (proto
) = p
;
1128 return return_value
;
1131 /* Create and push a decl for a built-in external variable or field NAME.
1133 TYPE is its data type. */
1136 create_builtin_decl (code
, type
, name
)
1137 enum tree_code code
;
1141 tree decl
= build_decl (code
, get_identifier (name
), type
);
1143 if (code
== VAR_DECL
)
1145 TREE_STATIC (decl
) = 1;
1146 make_decl_rtl (decl
, 0, 1);
1150 DECL_ARTIFICIAL (decl
) = 1;
1154 /* Purpose: "play" parser, creating/installing representations
1155 of the declarations that are required by Objective-C.
1159 type_spec--------->sc_spec
1160 (tree_list) (tree_list)
1163 identifier_node identifier_node */
1166 synth_module_prologue ()
1171 /* Defined in `objc.h' */
1172 objc_object_id
= get_identifier (TAG_OBJECT
);
1174 objc_object_reference
= xref_tag (RECORD_TYPE
, objc_object_id
);
1176 id_type
= build_pointer_type (objc_object_reference
);
1178 objc_id_id
= get_identifier (TYPE_ID
);
1179 objc_class_id
= get_identifier (TAG_CLASS
);
1181 objc_class_type
= build_pointer_type (xref_tag (RECORD_TYPE
, objc_class_id
));
1182 protocol_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
1183 get_identifier (PROTOCOL_OBJECT_CLASS_NAME
)));
1185 /* Declare type of selector-objects that represent an operation name. */
1187 #ifdef OBJC_INT_SELECTORS
1188 /* `unsigned int' */
1189 selector_type
= unsigned_type_node
;
1191 /* `struct objc_selector *' */
1193 = build_pointer_type (xref_tag (RECORD_TYPE
,
1194 get_identifier (TAG_SELECTOR
)));
1195 #endif /* not OBJC_INT_SELECTORS */
1197 /* Forward declare type, or else the prototype for msgSendSuper will
1200 super_p
= build_pointer_type (xref_tag (RECORD_TYPE
,
1201 get_identifier (TAG_SUPER
)));
1204 /* id objc_msgSend (id, SEL, ...); */
1207 = build_function_type (id_type
,
1208 tree_cons (NULL_TREE
, id_type
,
1209 tree_cons (NULL_TREE
, selector_type
,
1212 if (! flag_next_runtime
)
1214 umsg_decl
= build_decl (FUNCTION_DECL
,
1215 get_identifier (TAG_MSGSEND
), temp_type
);
1216 DECL_EXTERNAL (umsg_decl
) = 1;
1217 TREE_PUBLIC (umsg_decl
) = 1;
1218 DECL_INLINE (umsg_decl
) = 1;
1219 DECL_ARTIFICIAL (umsg_decl
) = 1;
1221 if (flag_traditional
&& TAG_MSGSEND
[0] != '_')
1222 DECL_BUILT_IN_NONANSI (umsg_decl
) = 1;
1224 make_decl_rtl (umsg_decl
, NULL_PTR
, 1);
1225 pushdecl (umsg_decl
);
1228 umsg_decl
= builtin_function (TAG_MSGSEND
, temp_type
, NOT_BUILT_IN
, 0);
1230 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1233 = build_function_type (id_type
,
1234 tree_cons (NULL_TREE
, super_p
,
1235 tree_cons (NULL_TREE
, selector_type
,
1238 umsg_super_decl
= builtin_function (TAG_MSGSENDSUPER
,
1239 temp_type
, NOT_BUILT_IN
, 0);
1241 /* id objc_getClass (const char *); */
1243 temp_type
= build_function_type (id_type
,
1244 tree_cons (NULL_TREE
,
1245 const_string_type_node
,
1246 tree_cons (NULL_TREE
, void_type_node
,
1250 = builtin_function (TAG_GETCLASS
, temp_type
, NOT_BUILT_IN
, 0);
1252 /* id objc_getMetaClass (const char *); */
1254 objc_get_meta_class_decl
1255 = builtin_function (TAG_GETMETACLASS
, temp_type
, NOT_BUILT_IN
, 0);
1257 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1259 if (! flag_next_runtime
)
1261 if (flag_typed_selectors
)
1263 /* Suppress outputting debug symbols, because
1264 dbxout_init hasn'r been called yet. */
1265 enum debug_info_type save_write_symbols
= write_symbols
;
1266 write_symbols
= NO_DEBUG
;
1268 build_selector_template ();
1269 temp_type
= build_array_type (objc_selector_template
, NULL_TREE
);
1271 write_symbols
= save_write_symbols
;
1274 temp_type
= build_array_type (selector_type
, NULL_TREE
);
1276 layout_type (temp_type
);
1277 UOBJC_SELECTOR_TABLE_decl
1278 = create_builtin_decl (VAR_DECL
, temp_type
,
1279 "_OBJC_SELECTOR_TABLE");
1281 /* Avoid warning when not sending messages. */
1282 TREE_USED (UOBJC_SELECTOR_TABLE_decl
) = 1;
1285 generate_forward_declaration_to_string_table ();
1287 /* Forward declare constant_string_id and constant_string_type. */
1288 constant_string_id
= get_identifier (STRING_OBJECT_CLASS_NAME
);
1289 constant_string_type
= xref_tag (RECORD_TYPE
, constant_string_id
);
1292 /* Custom build_string which sets TREE_TYPE! */
1295 my_build_string (len
, str
)
1300 tree a_string
= build_string (len
, str
);
1302 /* Some code from combine_strings, which is local to c-parse.y. */
1303 if (TREE_TYPE (a_string
) == int_array_type_node
)
1306 TREE_TYPE (a_string
)
1307 = build_array_type (wide_flag
? integer_type_node
: char_type_node
,
1308 build_index_type (build_int_2 (len
- 1, 0)));
1310 TREE_CONSTANT (a_string
) = 1; /* Puts string in the readonly segment */
1311 TREE_STATIC (a_string
) = 1;
1316 /* Return a newly constructed OBJC_STRING_CST node whose value is
1317 the LEN characters at STR.
1318 The TREE_TYPE is not initialized. */
1321 build_objc_string (len
, str
)
1325 tree s
= build_string (len
, str
);
1327 TREE_SET_CODE (s
, OBJC_STRING_CST
);
1331 /* Given a chain of OBJC_STRING_CST's, build a static instance of
1332 NXConstanString which points at the concatenation of those strings.
1333 We place the string object in the __string_objects section of the
1334 __OBJC segment. The Objective-C runtime will initialize the isa
1335 pointers of the string objects to point at the NXConstandString class
1339 build_objc_string_object (strings
)
1342 tree string
, initlist
, constructor
;
1345 if (!doing_objc_thang
)
1348 if (lookup_interface (constant_string_id
) == NULL_TREE
)
1350 error ("Cannot find interface declaration for `%s'",
1351 IDENTIFIER_POINTER (constant_string_id
));
1352 return error_mark_node
;
1355 add_class_reference (constant_string_id
);
1357 /* Combine_strings will work for OBJC_STRING_CST's too. */
1358 string
= combine_strings (strings
);
1359 TREE_SET_CODE (string
, STRING_CST
);
1360 length
= TREE_STRING_LENGTH (string
) - 1;
1362 if (! flag_next_runtime
)
1364 push_obstacks_nochange ();
1365 end_temporary_allocation ();
1366 if (! TREE_PERMANENT (strings
))
1367 string
= my_build_string (length
+ 1,
1368 TREE_STRING_POINTER (string
));
1371 /* & ((NXConstantString) {0, string, length}) */
1373 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1375 = tree_cons (NULL_TREE
, copy_node (build_unary_op (ADDR_EXPR
, string
, 1)),
1377 initlist
= tree_cons (NULL_TREE
, build_int_2 (length
, 0), initlist
);
1378 constructor
= build_constructor (constant_string_type
, nreverse (initlist
));
1380 if (!flag_next_runtime
)
1383 = objc_add_static_instance (constructor
, constant_string_type
);
1387 return (build_unary_op (ADDR_EXPR
, constructor
, 1));
1390 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1393 objc_add_static_instance (constructor
, class_decl
)
1394 tree constructor
, class_decl
;
1396 static int num_static_inst
;
1400 push_obstacks_nochange ();
1401 end_temporary_allocation ();
1403 /* Find the list of static instances for the CLASS_DECL. Create one if
1405 for (chain
= &objc_static_instances
;
1406 *chain
&& TREE_VALUE (*chain
) != class_decl
;
1407 chain
= &TREE_CHAIN (*chain
));
1410 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
1411 add_objc_string (TYPE_NAME (class_decl
), class_names
);
1414 sprintf (buf
, "_OBJC_INSTANCE_%d", num_static_inst
++);
1415 decl
= build_decl (VAR_DECL
, get_identifier (buf
), class_decl
);
1416 DECL_COMMON (decl
) = 1;
1417 TREE_STATIC (decl
) = 1;
1418 DECL_ARTIFICIAL (decl
) = 1;
1419 pushdecl_top_level (decl
);
1420 rest_of_decl_compilation (decl
, 0, 1, 0);
1422 /* Do this here so it gets output later instead of possibly
1423 inside something else we are writing. */
1424 DECL_INITIAL (decl
) = constructor
;
1426 /* Add the DECL to the head of this CLASS' list. */
1427 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
1433 /* Build a static constant CONSTRUCTOR
1434 with type TYPE and elements ELTS. */
1437 build_constructor (type
, elts
)
1440 tree constructor
= build (CONSTRUCTOR
, type
, NULL_TREE
, elts
);
1442 TREE_CONSTANT (constructor
) = 1;
1443 TREE_STATIC (constructor
) = 1;
1444 TREE_READONLY (constructor
) = 1;
1449 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1451 /* Predefine the following data type:
1459 void *defs[cls_def_cnt + cat_def_cnt];
1463 build_objc_symtab_template ()
1465 tree field_decl
, field_decl_chain
, index
;
1467 objc_symtab_template
1468 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SYMTAB
));
1470 /* long sel_ref_cnt; */
1472 field_decl
= create_builtin_decl (FIELD_DECL
,
1473 long_integer_type_node
,
1475 field_decl_chain
= field_decl
;
1479 field_decl
= create_builtin_decl (FIELD_DECL
,
1480 build_pointer_type (selector_type
),
1482 chainon (field_decl_chain
, field_decl
);
1484 /* short cls_def_cnt; */
1486 field_decl
= create_builtin_decl (FIELD_DECL
,
1487 short_integer_type_node
,
1489 chainon (field_decl_chain
, field_decl
);
1491 /* short cat_def_cnt; */
1493 field_decl
= create_builtin_decl (FIELD_DECL
,
1494 short_integer_type_node
,
1496 chainon (field_decl_chain
, field_decl
);
1498 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1500 if (!flag_next_runtime
)
1501 index
= build_index_type (build_int_2 (imp_count
+ cat_count
, 0));
1503 index
= build_index_type (build_int_2 (imp_count
+ cat_count
- 1,
1504 imp_count
== 0 && cat_count
== 0
1506 field_decl
= create_builtin_decl (FIELD_DECL
,
1507 build_array_type (ptr_type_node
, index
),
1509 chainon (field_decl_chain
, field_decl
);
1511 finish_struct (objc_symtab_template
, field_decl_chain
, NULL_TREE
);
1514 /* Create the initial value for the `defs' field of _objc_symtab.
1515 This is a CONSTRUCTOR. */
1518 init_def_list (type
)
1521 tree expr
, initlist
= NULL_TREE
;
1522 struct imp_entry
*impent
;
1525 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1527 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
1529 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1530 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1535 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1537 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1539 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1540 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1544 if (!flag_next_runtime
)
1546 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1549 if (static_instances_decl
)
1550 expr
= build_unary_op (ADDR_EXPR
, static_instances_decl
, 0);
1552 expr
= build_int_2 (0, 0);
1554 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1557 return build_constructor (type
, nreverse (initlist
));
1560 /* Construct the initial value for all of _objc_symtab. */
1563 init_objc_symtab (type
)
1568 /* sel_ref_cnt = { ..., 5, ... } */
1570 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1572 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1574 if (flag_next_runtime
|| ! sel_ref_chain
)
1575 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1577 initlist
= tree_cons (NULL_TREE
,
1578 build_unary_op (ADDR_EXPR
,
1579 UOBJC_SELECTOR_TABLE_decl
, 1),
1582 /* cls_def_cnt = { ..., 5, ... } */
1584 initlist
= tree_cons (NULL_TREE
, build_int_2 (imp_count
, 0), initlist
);
1586 /* cat_def_cnt = { ..., 5, ... } */
1588 initlist
= tree_cons (NULL_TREE
, build_int_2 (cat_count
, 0), initlist
);
1590 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1592 if (imp_count
|| cat_count
|| static_instances_decl
)
1595 tree field
= TYPE_FIELDS (type
);
1596 field
= TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field
))));
1598 initlist
= tree_cons (NULL_TREE
, init_def_list (TREE_TYPE (field
)),
1602 return build_constructor (type
, nreverse (initlist
));
1605 /* Push forward-declarations of all the categories
1606 so that init_def_list can use them in a CONSTRUCTOR. */
1609 forward_declare_categories ()
1611 struct imp_entry
*impent
;
1612 tree sav
= implementation_context
;
1614 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1616 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1618 /* Set an invisible arg to synth_id_with_class_suffix. */
1619 implementation_context
= impent
->imp_context
;
1621 = create_builtin_decl (VAR_DECL
, objc_category_template
,
1622 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", implementation_context
)));
1625 implementation_context
= sav
;
1628 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1629 and initialized appropriately. */
1632 generate_objc_symtab_decl ()
1636 if (!objc_category_template
)
1637 build_category_template ();
1639 /* forward declare categories */
1641 forward_declare_categories ();
1643 if (!objc_symtab_template
)
1644 build_objc_symtab_template ();
1646 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
1648 UOBJC_SYMBOLS_decl
= start_decl (get_identifier ("_OBJC_SYMBOLS"),
1649 tree_cons (NULL_TREE
,
1650 objc_symtab_template
, sc_spec
),
1652 NULL_TREE
, NULL_TREE
);
1654 TREE_USED (UOBJC_SYMBOLS_decl
) = 1;
1655 DECL_IGNORED_P (UOBJC_SYMBOLS_decl
) = 1;
1656 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl
) = 1;
1657 finish_decl (UOBJC_SYMBOLS_decl
,
1658 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)),
1663 init_module_descriptor (type
)
1666 tree initlist
, expr
;
1668 /* version = { 1, ... } */
1670 expr
= build_int_2 (OBJC_VERSION
, 0);
1671 initlist
= build_tree_list (NULL_TREE
, expr
);
1673 /* size = { ..., sizeof (struct objc_module), ... } */
1675 expr
= size_in_bytes (objc_module_template
);
1676 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1678 /* name = { ..., "foo.m", ... } */
1680 expr
= add_objc_string (get_identifier (input_filename
), class_names
);
1681 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1683 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1685 if (UOBJC_SYMBOLS_decl
)
1686 expr
= build_unary_op (ADDR_EXPR
, UOBJC_SYMBOLS_decl
, 0);
1688 expr
= build_int_2 (0, 0);
1689 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1691 return build_constructor (type
, nreverse (initlist
));
1694 /* Write out the data structures to describe Objective C classes defined.
1695 If appropriate, compile and output a setup function to initialize them.
1696 Return a string which is the name of a function to call to initialize
1697 the Objective C data structures for this file (and perhaps for other files
1700 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1703 build_module_descriptor ()
1705 tree decl_specs
, field_decl
, field_decl_chain
;
1707 objc_module_template
1708 = start_struct (RECORD_TYPE
, get_identifier (UTAG_MODULE
));
1712 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1713 field_decl
= get_identifier ("version");
1715 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1716 field_decl_chain
= field_decl
;
1720 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1721 field_decl
= get_identifier ("size");
1723 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1724 chainon (field_decl_chain
, field_decl
);
1728 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
1729 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
1731 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1732 chainon (field_decl_chain
, field_decl
);
1734 /* struct objc_symtab *symtab; */
1736 decl_specs
= get_identifier (UTAG_SYMTAB
);
1737 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
1738 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("symtab"));
1740 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1741 chainon (field_decl_chain
, field_decl
);
1743 finish_struct (objc_module_template
, field_decl_chain
, NULL_TREE
);
1745 /* Create an instance of "objc_module". */
1747 decl_specs
= tree_cons (NULL_TREE
, objc_module_template
,
1748 build_tree_list (NULL_TREE
,
1749 ridpointers
[(int) RID_STATIC
]));
1751 UOBJC_MODULES_decl
= start_decl (get_identifier ("_OBJC_MODULES"),
1752 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
1754 DECL_ARTIFICIAL (UOBJC_MODULES_decl
) = 1;
1755 DECL_IGNORED_P (UOBJC_MODULES_decl
) = 1;
1756 finish_decl (UOBJC_MODULES_decl
,
1757 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl
)),
1760 /* Mark the decl to avoid "defined but not used" warning. */
1761 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl
) = 1;
1763 /* Generate a constructor call for the module descriptor.
1764 This code was generated by reading the grammar rules
1765 of c-parse.in; Therefore, it may not be the most efficient
1766 way of generating the requisite code. */
1768 if (flag_next_runtime
)
1772 tree parms
, function_decl
, decelerator
, void_list_node
;
1774 tree init_function_name
= get_file_function_name ('I');
1776 /* Declare void __objc_execClass (void *); */
1778 void_list_node
= build_tree_list (NULL_TREE
, void_type_node
);
1780 = build_function_type (void_type_node
,
1781 tree_cons (NULL_TREE
, ptr_type_node
,
1783 function_decl
= build_decl (FUNCTION_DECL
,
1784 get_identifier (TAG_EXECCLASS
),
1786 DECL_EXTERNAL (function_decl
) = 1;
1787 DECL_ARTIFICIAL (function_decl
) = 1;
1788 TREE_PUBLIC (function_decl
) = 1;
1790 pushdecl (function_decl
);
1791 rest_of_decl_compilation (function_decl
, 0, 0, 0);
1794 = build_tree_list (NULL_TREE
,
1795 build_unary_op (ADDR_EXPR
, UOBJC_MODULES_decl
, 0));
1796 decelerator
= build_function_call (function_decl
, parms
);
1798 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1800 start_function (void_list_node
,
1801 build_parse_node (CALL_EXPR
, init_function_name
,
1802 /* This has the format of the output
1803 of get_parm_info. */
1804 tree_cons (NULL_TREE
, NULL_TREE
,
1807 NULL_TREE
, NULL_TREE
, 0);
1808 #if 0 /* This should be turned back on later
1809 for the systems where collect is not needed. */
1810 /* Make these functions nonglobal
1811 so each file can use the same name. */
1812 TREE_PUBLIC (current_function_decl
) = 0;
1814 TREE_USED (current_function_decl
) = 1;
1815 store_parm_decls ();
1817 assemble_external (function_decl
);
1818 c_expand_expr_stmt (decelerator
);
1820 TREE_PUBLIC (current_function_decl
) = 1;
1822 function_decl
= current_function_decl
;
1823 finish_function (0);
1825 /* Return the name of the constructor function. */
1826 return XSTR (XEXP (DECL_RTL (function_decl
), 0), 0);
1830 /* extern const char _OBJC_STRINGS[]; */
1833 generate_forward_declaration_to_string_table ()
1835 tree sc_spec
, decl_specs
, expr_decl
;
1837 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_EXTERN
], NULL_TREE
);
1838 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1841 = build_nt (ARRAY_REF
, get_identifier ("_OBJC_STRINGS"), NULL_TREE
);
1843 UOBJC_STRINGS_decl
= define_decl (expr_decl
, decl_specs
);
1846 /* Return the DECL of the string IDENT in the SECTION. */
1849 get_objc_string_decl (ident
, section
)
1851 enum string_section section
;
1855 if (section
== class_names
)
1856 chain
= class_names_chain
;
1857 else if (section
== meth_var_names
)
1858 chain
= meth_var_names_chain
;
1859 else if (section
== meth_var_types
)
1860 chain
= meth_var_types_chain
;
1864 for (; chain
!= 0; chain
= TREE_VALUE (chain
))
1865 if (TREE_VALUE (chain
) == ident
)
1866 return (TREE_PURPOSE (chain
));
1872 /* Output references to all statically allocated objects. Return the DECL
1873 for the array built. */
1876 generate_static_references ()
1878 tree decls
= NULL_TREE
, ident
, decl_spec
, expr_decl
, expr
= NULL_TREE
;
1879 tree class_name
, class, decl
, initlist
;
1880 tree cl_chain
, in_chain
, type
;
1881 int num_inst
, num_class
;
1884 if (flag_next_runtime
)
1887 for (cl_chain
= objc_static_instances
, num_class
= 0;
1888 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
1890 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
1891 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
1893 sprintf (buf
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
1894 ident
= get_identifier (buf
);
1896 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1897 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1898 build_tree_list (NULL_TREE
,
1899 ridpointers
[(int) RID_STATIC
]));
1900 decl
= start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
, NULL_TREE
);
1901 DECL_CONTEXT (decl
) = 0;
1902 DECL_ARTIFICIAL (decl
) = 1;
1904 /* Output {class_name, ...}. */
1905 class = TREE_VALUE (cl_chain
);
1906 class_name
= get_objc_string_decl (TYPE_NAME (class), class_names
);
1907 initlist
= build_tree_list (NULL_TREE
,
1908 build_unary_op (ADDR_EXPR
, class_name
, 1));
1910 /* Output {..., instance, ...}. */
1911 for (in_chain
= TREE_PURPOSE (cl_chain
);
1912 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
1914 expr
= build_unary_op (ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
1915 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1918 /* Output {..., NULL}. */
1919 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1921 expr
= build_constructor (TREE_TYPE (decl
), nreverse (initlist
));
1922 finish_decl (decl
, expr
, NULL_TREE
);
1923 TREE_USED (decl
) = 1;
1925 type
= build_array_type (build_pointer_type (void_type_node
), 0);
1926 decl
= build_decl (VAR_DECL
, ident
, type
);
1927 make_decl_rtl (decl
, 0, 1);
1928 TREE_USED (decl
) = 1;
1930 = tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, decl
, 1), decls
);
1933 decls
= tree_cons (NULL_TREE
, build_int_2 (0, 0), decls
);
1934 ident
= get_identifier ("_OBJC_STATIC_INSTANCES");
1935 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1936 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1937 build_tree_list (NULL_TREE
,
1938 ridpointers
[(int) RID_STATIC
]));
1939 static_instances_decl
1940 = start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
, NULL_TREE
);
1941 TREE_USED (static_instances_decl
) = 1;
1942 DECL_CONTEXT (static_instances_decl
) = 0;
1943 DECL_ARTIFICIAL (static_instances_decl
) = 1;
1944 end_temporary_allocation ();
1945 expr
= build_constructor (TREE_TYPE (static_instances_decl
),
1947 finish_decl (static_instances_decl
, expr
, NULL_TREE
);
1950 /* Output all strings. */
1955 tree sc_spec
, decl_specs
, expr_decl
;
1956 tree chain
, string_expr
;
1959 for (chain
= class_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1961 string
= TREE_VALUE (chain
);
1962 decl
= TREE_PURPOSE (chain
);
1964 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1965 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1966 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1967 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
1968 end_temporary_allocation ();
1969 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1970 IDENTIFIER_POINTER (string
));
1971 finish_decl (decl
, string_expr
, NULL_TREE
);
1974 for (chain
= meth_var_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1976 string
= TREE_VALUE (chain
);
1977 decl
= TREE_PURPOSE (chain
);
1979 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1980 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1981 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1982 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
1983 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1984 IDENTIFIER_POINTER (string
));
1985 finish_decl (decl
, string_expr
, NULL_TREE
);
1988 for (chain
= meth_var_types_chain
; chain
; chain
= TREE_CHAIN (chain
))
1990 string
= TREE_VALUE (chain
);
1991 decl
= TREE_PURPOSE (chain
);
1993 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1994 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1995 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1996 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
1997 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1998 IDENTIFIER_POINTER (string
));
1999 finish_decl (decl
, string_expr
, NULL_TREE
);
2004 build_selector_reference_decl (name
)
2011 sprintf (buf
, "_OBJC_SELECTOR_REFERENCES_%d", idx
++);
2013 push_obstacks_nochange ();
2014 end_temporary_allocation ();
2016 ident
= get_identifier (buf
);
2018 decl
= build_decl (VAR_DECL
, ident
, selector_type
);
2019 DECL_EXTERNAL (decl
) = 1;
2020 TREE_PUBLIC (decl
) = 1;
2021 TREE_USED (decl
) = 1;
2022 TREE_READONLY (decl
) = 1;
2023 DECL_ARTIFICIAL (decl
) = 1;
2024 DECL_CONTEXT (decl
) = 0;
2026 make_decl_rtl (decl
, 0, 1);
2027 pushdecl_top_level (decl
);
2034 /* Just a handy wrapper for add_objc_string. */
2037 build_selector (ident
)
2040 tree expr
= add_objc_string (ident
, meth_var_names
);
2041 if (flag_typed_selectors
)
2044 return build_c_cast (selector_type
, expr
); /* cast! */
2047 /* Synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>]
2048 The cast stops the compiler from issuing the following message:
2049 grok.m: warning: initialization of non-const * pointer from const *
2050 grok.m: warning: initialization between incompatible pointer types. */
2054 build_msg_pool_reference (offset
)
2057 tree expr
= build_int_2 (offset
, 0);
2060 expr
= build_array_ref (UOBJC_STRINGS_decl
, expr
);
2061 expr
= build_unary_op (ADDR_EXPR
, expr
, 0);
2063 cast
= build_tree_list (build_tree_list (NULL_TREE
,
2064 ridpointers
[(int) RID_CHAR
]),
2065 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
2066 TREE_TYPE (expr
) = groktypename (cast
);
2071 init_selector (offset
)
2074 tree expr
= build_msg_pool_reference (offset
);
2075 TREE_TYPE (expr
) = selector_type
;
2081 build_selector_translation_table ()
2083 tree sc_spec
, decl_specs
;
2084 tree chain
, initlist
= NULL_TREE
;
2086 tree decl
= NULL_TREE
, var_decl
, name
;
2088 /* The corresponding pop_obstacks is in finish_decl,
2089 called at the end of this function. */
2090 if (! flag_next_runtime
)
2091 push_obstacks_nochange ();
2093 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
2097 expr
= build_selector (TREE_VALUE (chain
));
2099 if (flag_next_runtime
)
2101 name
= DECL_NAME (TREE_PURPOSE (chain
));
2103 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
2105 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2106 decl_specs
= tree_cons (NULL_TREE
, selector_type
, sc_spec
);
2110 /* The `decl' that is returned from start_decl is the one that we
2111 forward declared in `build_selector_reference' */
2112 decl
= start_decl (var_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2115 /* add one for the '\0' character */
2116 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (chain
)) + 1;
2118 if (flag_next_runtime
)
2119 finish_decl (decl
, expr
, NULL_TREE
);
2122 if (flag_typed_selectors
)
2124 tree eltlist
= NULL_TREE
;
2125 tree encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
2126 eltlist
= tree_cons (NULL_TREE
, expr
, NULL_TREE
);
2127 eltlist
= tree_cons (NULL_TREE
, encoding
, eltlist
);
2128 expr
= build_constructor (objc_selector_template
,
2129 nreverse (eltlist
));
2131 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2136 if (! flag_next_runtime
)
2138 /* Cause the variable and its initial value to be actually output. */
2139 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl
) = 0;
2140 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl
) = 1;
2141 /* NULL terminate the list and fix the decl for output. */
2142 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
2143 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl
) = (tree
) 1;
2144 initlist
= build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
2145 nreverse (initlist
));
2146 finish_decl (UOBJC_SELECTOR_TABLE_decl
, initlist
, NULL_TREE
);
2147 current_function_decl
= NULL_TREE
;
2152 get_proto_encoding (proto
)
2160 if (! METHOD_ENCODING (proto
))
2162 tmp_decl
= build_tmp_function_decl ();
2163 hack_method_prototype (proto
, tmp_decl
);
2164 encoding
= encode_method_prototype (proto
, tmp_decl
);
2165 METHOD_ENCODING (proto
) = encoding
;
2168 encoding
= METHOD_ENCODING (proto
);
2170 return add_objc_string (encoding
, meth_var_types
);
2173 return build_int_2 (0, 0);
2176 /* sel_ref_chain is a list whose "value" fields will be instances of
2177 identifier_node that represent the selector. */
2180 build_typed_selector_reference (ident
, proto
)
2183 tree
*chain
= &sel_ref_chain
;
2189 if (TREE_PURPOSE (*chain
) == ident
&& TREE_VALUE (*chain
) == proto
)
2190 goto return_at_index
;
2193 chain
= &TREE_CHAIN (*chain
);
2196 *chain
= perm_tree_cons (proto
, ident
, NULL_TREE
);
2199 expr
= build_unary_op (ADDR_EXPR
,
2200 build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2201 build_int_2 (index
, 0)),
2203 return build_c_cast (selector_type
, expr
);
2207 build_selector_reference (ident
)
2210 tree
*chain
= &sel_ref_chain
;
2216 if (TREE_VALUE (*chain
) == ident
)
2217 return (flag_next_runtime
2218 ? TREE_PURPOSE (*chain
)
2219 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2220 build_int_2 (index
, 0)));
2223 chain
= &TREE_CHAIN (*chain
);
2226 expr
= build_selector_reference_decl (ident
);
2228 *chain
= perm_tree_cons (expr
, ident
, NULL_TREE
);
2230 return (flag_next_runtime
2232 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2233 build_int_2 (index
, 0)));
2237 build_class_reference_decl (name
)
2244 sprintf (buf
, "_OBJC_CLASS_REFERENCES_%d", idx
++);
2246 push_obstacks_nochange ();
2247 end_temporary_allocation ();
2249 ident
= get_identifier (buf
);
2251 decl
= build_decl (VAR_DECL
, ident
, objc_class_type
);
2252 DECL_EXTERNAL (decl
) = 1;
2253 TREE_PUBLIC (decl
) = 1;
2254 TREE_USED (decl
) = 1;
2255 TREE_READONLY (decl
) = 1;
2256 DECL_CONTEXT (decl
) = 0;
2257 DECL_ARTIFICIAL (decl
) = 1;
2259 make_decl_rtl (decl
, 0, 1);
2260 pushdecl_top_level (decl
);
2267 /* Create a class reference, but don't create a variable to reference
2271 add_class_reference (ident
)
2276 if ((chain
= cls_ref_chain
))
2281 if (ident
== TREE_VALUE (chain
))
2285 chain
= TREE_CHAIN (chain
);
2289 /* Append to the end of the list */
2290 TREE_CHAIN (tail
) = perm_tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2293 cls_ref_chain
= perm_tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2296 /* Get a class reference, creating it if necessary. Also create the
2297 reference variable. */
2300 get_class_reference (ident
)
2303 if (flag_next_runtime
)
2308 for (chain
= &cls_ref_chain
; *chain
; chain
= &TREE_CHAIN (*chain
))
2309 if (TREE_VALUE (*chain
) == ident
)
2311 if (! TREE_PURPOSE (*chain
))
2312 TREE_PURPOSE (*chain
) = build_class_reference_decl (ident
);
2314 return TREE_PURPOSE (*chain
);
2317 decl
= build_class_reference_decl (ident
);
2318 *chain
= perm_tree_cons (decl
, ident
, NULL_TREE
);
2325 add_class_reference (ident
);
2327 params
= build_tree_list (NULL_TREE
,
2328 my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
2329 IDENTIFIER_POINTER (ident
)));
2331 assemble_external (objc_get_class_decl
);
2332 return build_function_call (objc_get_class_decl
, params
);
2336 /* SEL_REFDEF_CHAIN is a list whose "value" fields will be instances
2337 of identifier_node that represent the selector. It returns the
2338 offset of the selector from the beginning of the _OBJC_STRINGS
2339 pool. This offset is typically used by init_selector during code
2342 For each string section we have a chain which maps identifier nodes
2343 to decls for the strings. */
2346 add_objc_string (ident
, section
)
2348 enum string_section section
;
2352 if (section
== class_names
)
2353 chain
= &class_names_chain
;
2354 else if (section
== meth_var_names
)
2355 chain
= &meth_var_names_chain
;
2356 else if (section
== meth_var_types
)
2357 chain
= &meth_var_types_chain
;
2363 if (TREE_VALUE (*chain
) == ident
)
2364 return build_unary_op (ADDR_EXPR
, TREE_PURPOSE (*chain
), 1);
2366 chain
= &TREE_CHAIN (*chain
);
2369 decl
= build_objc_string_decl (ident
, section
);
2371 *chain
= perm_tree_cons (decl
, ident
, NULL_TREE
);
2373 return build_unary_op (ADDR_EXPR
, decl
, 1);
2377 build_objc_string_decl (name
, section
)
2379 enum string_section section
;
2383 static int class_names_idx
= 0;
2384 static int meth_var_names_idx
= 0;
2385 static int meth_var_types_idx
= 0;
2387 if (section
== class_names
)
2388 sprintf (buf
, "_OBJC_CLASS_NAME_%d", class_names_idx
++);
2389 else if (section
== meth_var_names
)
2390 sprintf (buf
, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx
++);
2391 else if (section
== meth_var_types
)
2392 sprintf (buf
, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx
++);
2394 push_obstacks_nochange ();
2395 end_temporary_allocation ();
2396 ident
= get_identifier (buf
);
2398 decl
= build_decl (VAR_DECL
, ident
, build_array_type (char_type_node
, 0));
2399 DECL_EXTERNAL (decl
) = 1;
2400 TREE_PUBLIC (decl
) = 1;
2401 TREE_USED (decl
) = 1;
2402 TREE_READONLY (decl
) = 1;
2403 TREE_CONSTANT (decl
) = 1;
2404 DECL_CONTEXT (decl
) = 0;
2405 DECL_ARTIFICIAL (decl
) = 1;
2407 make_decl_rtl (decl
, 0, 1);
2408 pushdecl_top_level (decl
);
2417 objc_declare_alias (alias_ident
, class_ident
)
2421 if (!doing_objc_thang
)
2424 if (is_class_name (class_ident
) != class_ident
)
2425 warning ("Cannot find class `%s'", IDENTIFIER_POINTER (class_ident
));
2426 else if (is_class_name (alias_ident
))
2427 warning ("Class `%s' already exists", IDENTIFIER_POINTER (alias_ident
));
2429 alias_chain
= tree_cons (class_ident
, alias_ident
, alias_chain
);
2433 objc_declare_class (ident_list
)
2438 if (!doing_objc_thang
)
2441 for (list
= ident_list
; list
; list
= TREE_CHAIN (list
))
2443 tree ident
= TREE_VALUE (list
);
2446 if ((decl
= lookup_name (ident
)))
2448 error ("`%s' redeclared as different kind of symbol",
2449 IDENTIFIER_POINTER (ident
));
2450 error_with_decl (decl
, "previous declaration of `%s'");
2453 if (! is_class_name (ident
))
2455 tree record
= xref_tag (RECORD_TYPE
, ident
);
2456 TREE_STATIC_TEMPLATE (record
) = 1;
2457 class_chain
= tree_cons (NULL_TREE
, ident
, class_chain
);
2463 is_class_name (ident
)
2468 if (lookup_interface (ident
))
2471 for (chain
= class_chain
; chain
; chain
= TREE_CHAIN (chain
))
2473 if (ident
== TREE_VALUE (chain
))
2477 for (chain
= alias_chain
; chain
; chain
= TREE_CHAIN (chain
))
2479 if (ident
== TREE_VALUE (chain
))
2480 return TREE_PURPOSE (chain
);
2487 lookup_interface (ident
)
2492 for (chain
= interface_chain
; chain
; chain
= TREE_CHAIN (chain
))
2494 if (ident
== CLASS_NAME (chain
))
2501 objc_copy_list (list
, head
)
2505 tree newlist
= NULL_TREE
, tail
= NULL_TREE
;
2509 tail
= copy_node (list
);
2511 /* The following statement fixes a bug when inheriting instance
2512 variables that are declared to be bitfields. finish_struct
2513 expects to find the width of the bitfield in DECL_INITIAL,
2514 which it nulls out after processing the decl of the super
2515 class...rather than change the way finish_struct works (which
2516 is risky), I create the situation it expects...s.naroff
2519 if (DECL_BIT_FIELD (tail
) && DECL_INITIAL (tail
) == 0)
2520 DECL_INITIAL (tail
) = build_int_2 (DECL_FIELD_SIZE (tail
), 0);
2522 newlist
= chainon (newlist
, tail
);
2523 list
= TREE_CHAIN (list
);
2530 /* Used by: build_private_template, get_class_ivars, and
2531 continue_class. COPY is 1 when called from @defs. In this case
2532 copy all fields. Otherwise don't copy leaf ivars since we rely on
2533 them being side-effected exactly once by finish_struct. */
2536 build_ivar_chain (interface
, copy
)
2540 tree my_name
, super_name
, ivar_chain
;
2542 my_name
= CLASS_NAME (interface
);
2543 super_name
= CLASS_SUPER_NAME (interface
);
2545 /* Possibly copy leaf ivars. */
2547 objc_copy_list (CLASS_IVARS (interface
), &ivar_chain
);
2549 ivar_chain
= CLASS_IVARS (interface
);
2554 tree super_interface
= lookup_interface (super_name
);
2556 if (!super_interface
)
2558 /* fatal did not work with 2 args...should fix */
2559 error ("Cannot find interface declaration for `%s', superclass of `%s'",
2560 IDENTIFIER_POINTER (super_name
),
2561 IDENTIFIER_POINTER (my_name
));
2562 exit (FATAL_EXIT_CODE
);
2565 if (super_interface
== interface
)
2567 fatal ("Circular inheritance in interface declaration for `%s'",
2568 IDENTIFIER_POINTER (super_name
));
2571 interface
= super_interface
;
2572 my_name
= CLASS_NAME (interface
);
2573 super_name
= CLASS_SUPER_NAME (interface
);
2575 op1
= CLASS_IVARS (interface
);
2578 tree head
, tail
= objc_copy_list (op1
, &head
);
2580 /* Prepend super class ivars...make a copy of the list, we
2581 do not want to alter the original. */
2582 TREE_CHAIN (tail
) = ivar_chain
;
2589 /* struct <classname> {
2590 struct objc_class *isa;
2595 build_private_template (class)
2600 if (CLASS_STATIC_TEMPLATE (class))
2602 uprivate_record
= CLASS_STATIC_TEMPLATE (class);
2603 ivar_context
= TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2607 uprivate_record
= start_struct (RECORD_TYPE
, CLASS_NAME (class));
2609 ivar_context
= build_ivar_chain (class, 0);
2611 finish_struct (uprivate_record
, ivar_context
, NULL_TREE
);
2613 CLASS_STATIC_TEMPLATE (class) = uprivate_record
;
2615 /* mark this record as class template - for class type checking */
2616 TREE_STATIC_TEMPLATE (uprivate_record
) = 1;
2620 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
2622 build1 (INDIRECT_REF
, NULL_TREE
,
2625 return ivar_context
;
2628 /* Begin code generation for protocols... */
2630 /* struct objc_protocol {
2631 char *protocol_name;
2632 struct objc_protocol **protocol_list;
2633 struct objc_method_desc *instance_methods;
2634 struct objc_method_desc *class_methods;
2638 build_protocol_template ()
2640 tree decl_specs
, field_decl
, field_decl_chain
;
2643 template = start_struct (RECORD_TYPE
, get_identifier (UTAG_PROTOCOL
));
2645 /* struct objc_class *isa; */
2647 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2648 get_identifier (UTAG_CLASS
)));
2649 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
2651 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2652 field_decl_chain
= field_decl
;
2654 /* char *protocol_name; */
2656 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
2658 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_name"));
2660 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2661 chainon (field_decl_chain
, field_decl
);
2663 /* struct objc_protocol **protocol_list; */
2665 decl_specs
= build_tree_list (NULL_TREE
, template);
2667 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
2668 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
2670 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2671 chainon (field_decl_chain
, field_decl
);
2673 /* struct objc_method_list *instance_methods; */
2676 = build_tree_list (NULL_TREE
,
2677 xref_tag (RECORD_TYPE
,
2678 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2680 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
2682 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2683 chainon (field_decl_chain
, field_decl
);
2685 /* struct objc_method_list *class_methods; */
2688 = build_tree_list (NULL_TREE
,
2689 xref_tag (RECORD_TYPE
,
2690 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2692 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
2694 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2695 chainon (field_decl_chain
, field_decl
);
2697 return finish_struct (template, field_decl_chain
, NULL_TREE
);
2701 build_descriptor_table_initializer (type
, entries
)
2705 tree initlist
= NULL_TREE
;
2709 tree eltlist
= NULL_TREE
;
2712 = tree_cons (NULL_TREE
,
2713 build_selector (METHOD_SEL_NAME (entries
)), NULL_TREE
);
2715 = tree_cons (NULL_TREE
,
2716 add_objc_string (METHOD_ENCODING (entries
),
2721 = tree_cons (NULL_TREE
,
2722 build_constructor (type
, nreverse (eltlist
)), initlist
);
2724 entries
= TREE_CHAIN (entries
);
2728 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
2731 /* struct objc_method_prototype_list {
2733 struct objc_method_prototype {
2740 build_method_prototype_list_template (list_type
, size
)
2744 tree objc_ivar_list_record
;
2745 tree decl_specs
, field_decl
, field_decl_chain
;
2747 /* Generate an unnamed struct definition. */
2749 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
2751 /* int method_count; */
2753 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
2754 field_decl
= get_identifier ("method_count");
2757 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2758 field_decl_chain
= field_decl
;
2760 /* struct objc_method method_list[]; */
2762 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
2763 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
2764 build_int_2 (size
, 0));
2767 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2768 chainon (field_decl_chain
, field_decl
);
2770 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
2772 return objc_ivar_list_record
;
2776 build_method_prototype_template ()
2779 tree decl_specs
, field_decl
, field_decl_chain
;
2782 = start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD_PROTOTYPE
));
2784 #ifdef OBJC_INT_SELECTORS
2785 /* unsigned int _cmd; */
2787 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_UNSIGNED
], NULL_TREE
);
2788 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_INT
], decl_specs
);
2789 field_decl
= get_identifier ("_cmd");
2790 #else /* OBJC_INT_SELECTORS */
2791 /* struct objc_selector *_cmd; */
2792 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
2793 get_identifier (TAG_SELECTOR
)), NULL_TREE
);
2794 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
2795 #endif /* OBJC_INT_SELECTORS */
2798 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2799 field_decl_chain
= field_decl
;
2801 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
2803 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_types"));
2805 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2806 chainon (field_decl_chain
, field_decl
);
2808 finish_struct (proto_record
, field_decl_chain
, NULL_TREE
);
2810 return proto_record
;
2813 /* True if last call to forwarding_offset yielded a register offset. */
2814 static int offset_is_register
;
2817 forwarding_offset (parm
)
2820 int offset_in_bytes
;
2822 if (GET_CODE (DECL_INCOMING_RTL (parm
)) == MEM
)
2824 rtx addr
= XEXP (DECL_INCOMING_RTL (parm
), 0);
2826 /* ??? Here we assume that the parm address is indexed
2827 off the frame pointer or arg pointer.
2828 If that is not true, we produce meaningless results,
2829 but do not crash. */
2830 if (GET_CODE (addr
) == PLUS
2831 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
2832 offset_in_bytes
= INTVAL (XEXP (addr
, 1));
2834 offset_in_bytes
= 0;
2836 offset_in_bytes
+= OBJC_FORWARDING_STACK_OFFSET
;
2837 offset_is_register
= 0;
2839 else if (GET_CODE (DECL_INCOMING_RTL (parm
)) == REG
)
2841 int regno
= REGNO (DECL_INCOMING_RTL (parm
));
2842 offset_in_bytes
= apply_args_register_offset (regno
);
2843 offset_is_register
= 1;
2848 /* This is the case where the parm is passed as an int or double
2849 and it is converted to a char, short or float and stored back
2850 in the parmlist. In this case, describe the parm
2851 with the variable's declared type, and adjust the address
2852 if the least significant bytes (which we are using) are not
2854 if (BYTES_BIG_ENDIAN
&& TREE_TYPE (parm
) != DECL_ARG_TYPE (parm
))
2855 offset_in_bytes
+= (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm
)))
2856 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm
))));
2858 return offset_in_bytes
;
2862 encode_method_prototype (method_decl
, func_decl
)
2869 int max_parm_end
= 0;
2873 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2874 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl
)));
2877 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
2878 obstack_object_size (&util_obstack
),
2879 OBJC_ENCODE_INLINE_DEFS
);
2882 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
2883 parms
= TREE_CHAIN (parms
))
2885 int parm_end
= (forwarding_offset (parms
)
2886 + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms
)))
2889 if (!offset_is_register
&& max_parm_end
< parm_end
)
2890 max_parm_end
= parm_end
;
2893 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
2895 sprintf (buf
, "%d", stack_size
);
2896 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2898 user_args
= METHOD_SEL_ARGS (method_decl
);
2900 /* Argument types. */
2901 for (parms
= DECL_ARGUMENTS (func_decl
), i
= 0; parms
;
2902 parms
= TREE_CHAIN (parms
), i
++)
2904 /* Process argument qualifiers for user supplied arguments. */
2907 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args
)));
2908 user_args
= TREE_CHAIN (user_args
);
2912 encode_type (TREE_TYPE (parms
),
2913 obstack_object_size (&util_obstack
),
2914 OBJC_ENCODE_INLINE_DEFS
);
2916 /* Compute offset. */
2917 sprintf (buf
, "%d", forwarding_offset (parms
));
2919 /* Indicate register. */
2920 if (offset_is_register
)
2921 obstack_1grow (&util_obstack
, '+');
2923 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2926 obstack_1grow (&util_obstack
, '\0');
2927 result
= get_identifier (obstack_finish (&util_obstack
));
2928 obstack_free (&util_obstack
, util_firstobj
);
2933 generate_descriptor_table (type
, name
, size
, list
, proto
)
2940 tree sc_spec
, decl_specs
, decl
, initlist
;
2942 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2943 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
2945 decl
= start_decl (synth_id_with_class_suffix (name
, proto
),
2946 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2948 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
2949 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
2951 finish_decl (decl
, build_constructor (type
, nreverse (initlist
)),
2958 generate_method_descriptors (protocol
) /* generate_dispatch_tables */
2961 static tree objc_method_prototype_template
;
2962 tree initlist
, chain
, method_list_template
;
2963 tree cast
, variable_length_type
;
2966 if (!objc_method_prototype_template
)
2967 objc_method_prototype_template
= build_method_prototype_template ();
2969 cast
= build_tree_list (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2970 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
))),
2972 variable_length_type
= groktypename (cast
);
2974 chain
= PROTOCOL_CLS_METHODS (protocol
);
2977 size
= list_length (chain
);
2979 method_list_template
2980 = build_method_prototype_list_template (objc_method_prototype_template
,
2984 = build_descriptor_table_initializer (objc_method_prototype_template
,
2987 UOBJC_CLASS_METHODS_decl
2988 = generate_descriptor_table (method_list_template
,
2989 "_OBJC_PROTOCOL_CLASS_METHODS",
2990 size
, initlist
, protocol
);
2991 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
2994 UOBJC_CLASS_METHODS_decl
= 0;
2996 chain
= PROTOCOL_NST_METHODS (protocol
);
2999 size
= list_length (chain
);
3001 method_list_template
3002 = build_method_prototype_list_template (objc_method_prototype_template
,
3005 = build_descriptor_table_initializer (objc_method_prototype_template
,
3008 UOBJC_INSTANCE_METHODS_decl
3009 = generate_descriptor_table (method_list_template
,
3010 "_OBJC_PROTOCOL_INSTANCE_METHODS",
3011 size
, initlist
, protocol
);
3012 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
3015 UOBJC_INSTANCE_METHODS_decl
= 0;
3019 build_tmp_function_decl ()
3021 tree decl_specs
, expr_decl
, parms
;
3025 /* struct objc_object *objc_xxx (id, SEL, ...); */
3027 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3028 push_parm_decl (build_tree_list
3029 (build_tree_list (decl_specs
,
3030 build1 (INDIRECT_REF
, NULL_TREE
,
3032 build_tree_list (NULL_TREE
, NULL_TREE
)));
3034 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3035 get_identifier (TAG_SELECTOR
)));
3036 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
);
3038 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, expr_decl
),
3039 build_tree_list (NULL_TREE
, NULL_TREE
)));
3040 parms
= get_parm_info (0);
3043 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3044 sprintf (buffer
, "__objc_tmp_%x", xxx
++);
3045 expr_decl
= build_nt (CALL_EXPR
, get_identifier (buffer
), parms
, NULL_TREE
);
3046 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
3048 return define_decl (expr_decl
, decl_specs
);
3052 hack_method_prototype (nst_methods
, tmp_decl
)
3059 /* Hack to avoid problem with static typing of self arg. */
3060 TREE_SET_CODE (nst_methods
, CLASS_METHOD_DECL
);
3061 start_method_def (nst_methods
);
3062 TREE_SET_CODE (nst_methods
, INSTANCE_METHOD_DECL
);
3064 if (METHOD_ADD_ARGS (nst_methods
) == (tree
) 1)
3065 parms
= get_parm_info (0); /* we have a `, ...' */
3067 parms
= get_parm_info (1); /* place a `void_at_end' */
3069 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
3071 /* Usually called from store_parm_decls -> init_function_start. */
3073 DECL_ARGUMENTS (tmp_decl
) = TREE_PURPOSE (parms
);
3074 current_function_decl
= tmp_decl
;
3077 /* Code taken from start_function. */
3078 tree restype
= TREE_TYPE (TREE_TYPE (tmp_decl
));
3079 /* Promote the value to int before returning it. */
3080 if (TREE_CODE (restype
) == INTEGER_TYPE
3081 && TYPE_PRECISION (restype
) < TYPE_PRECISION (integer_type_node
))
3082 restype
= integer_type_node
;
3083 DECL_RESULT (tmp_decl
) = build_decl (RESULT_DECL
, 0, restype
);
3086 for (parm
= DECL_ARGUMENTS (tmp_decl
); parm
; parm
= TREE_CHAIN (parm
))
3087 DECL_CONTEXT (parm
) = tmp_decl
;
3089 init_function_start (tmp_decl
, "objc-act", 0);
3091 /* Typically called from expand_function_start for function definitions. */
3092 assign_parms (tmp_decl
, 0);
3094 /* install return type */
3095 TREE_TYPE (TREE_TYPE (tmp_decl
)) = groktypename (TREE_TYPE (nst_methods
));
3100 generate_protocol_references (plist
)
3105 /* Forward declare protocols referenced. */
3106 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
3108 tree proto
= TREE_VALUE (lproto
);
3110 if (TREE_CODE (proto
) == PROTOCOL_INTERFACE_TYPE
3111 && PROTOCOL_NAME (proto
))
3113 if (! PROTOCOL_FORWARD_DECL (proto
))
3114 build_protocol_reference (proto
);
3116 if (PROTOCOL_LIST (proto
))
3117 generate_protocol_references (PROTOCOL_LIST (proto
));
3123 generate_protocols ()
3125 tree p
, tmp_decl
, encoding
;
3126 tree sc_spec
, decl_specs
, decl
;
3127 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
3128 tree cast_type2
= 0;
3130 tmp_decl
= build_tmp_function_decl ();
3132 if (! objc_protocol_template
)
3133 objc_protocol_template
= build_protocol_template ();
3135 /* If a protocol was directly referenced, pull in indirect references. */
3136 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3137 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
3138 generate_protocol_references (PROTOCOL_LIST (p
));
3140 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3142 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
3143 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
3145 /* If protocol wasn't referenced, don't generate any code. */
3146 if (! PROTOCOL_FORWARD_DECL (p
))
3149 /* Make sure we link in the Protocol class. */
3150 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
3154 if (! METHOD_ENCODING (nst_methods
))
3156 hack_method_prototype (nst_methods
, tmp_decl
);
3157 encoding
= encode_method_prototype (nst_methods
, tmp_decl
);
3158 METHOD_ENCODING (nst_methods
) = encoding
;
3160 nst_methods
= TREE_CHAIN (nst_methods
);
3165 if (! METHOD_ENCODING (cls_methods
))
3167 hack_method_prototype (cls_methods
, tmp_decl
);
3168 encoding
= encode_method_prototype (cls_methods
, tmp_decl
);
3169 METHOD_ENCODING (cls_methods
) = encoding
;
3172 cls_methods
= TREE_CHAIN (cls_methods
);
3174 generate_method_descriptors (p
);
3176 if (PROTOCOL_LIST (p
))
3177 refs_decl
= generate_protocol_list (p
);
3181 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3183 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
],
3185 decl_specs
= tree_cons (NULL_TREE
, objc_protocol_template
, sc_spec
);
3187 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
),
3188 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
3190 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
3197 (build_tree_list (build_tree_list (NULL_TREE
,
3198 objc_protocol_template
),
3199 build1 (INDIRECT_REF
, NULL_TREE
,
3200 build1 (INDIRECT_REF
, NULL_TREE
,
3203 refs_expr
= build_unary_op (ADDR_EXPR
, refs_decl
, 0);
3204 TREE_TYPE (refs_expr
) = cast_type2
;
3207 refs_expr
= build_int_2 (0, 0);
3209 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3210 by generate_method_descriptors, which is called above. */
3211 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
3212 protocol_name_expr
, refs_expr
,
3213 UOBJC_INSTANCE_METHODS_decl
,
3214 UOBJC_CLASS_METHODS_decl
);
3215 finish_decl (decl
, initlist
, NULL_TREE
);
3217 /* Mark the decl as used to avoid "defined but not used" warning. */
3218 TREE_USED (decl
) = 1;
3223 build_protocol_initializer (type
, protocol_name
, protocol_list
,
3224 instance_methods
, class_methods
)
3228 tree instance_methods
;
3231 tree initlist
= NULL_TREE
, expr
;
3232 static tree cast_type
= 0;
3238 (build_tree_list (NULL_TREE
,
3239 xref_tag (RECORD_TYPE
,
3240 get_identifier (UTAG_CLASS
))),
3241 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
3243 /* Filling the "isa" in with one allows the runtime system to
3244 detect that the version change...should remove before final release. */
3246 expr
= build_int_2 (PROTOCOL_VERSION
, 0);
3247 TREE_TYPE (expr
) = cast_type
;
3248 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3249 initlist
= tree_cons (NULL_TREE
, protocol_name
, initlist
);
3250 initlist
= tree_cons (NULL_TREE
, protocol_list
, initlist
);
3252 if (!instance_methods
)
3253 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3256 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
3257 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3261 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3264 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
3265 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3268 return build_constructor (type
, nreverse (initlist
));
3271 /* struct objc_category {
3272 char *category_name;
3274 struct objc_method_list *instance_methods;
3275 struct objc_method_list *class_methods;
3276 struct objc_protocol_list *protocols;
3280 build_category_template ()
3282 tree decl_specs
, field_decl
, field_decl_chain
;
3284 objc_category_template
= start_struct (RECORD_TYPE
,
3285 get_identifier (UTAG_CATEGORY
));
3286 /* char *category_name; */
3288 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3290 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("category_name"));
3292 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3293 field_decl_chain
= field_decl
;
3295 /* char *class_name; */
3297 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3298 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_name"));
3300 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3301 chainon (field_decl_chain
, field_decl
);
3303 /* struct objc_method_list *instance_methods; */
3305 decl_specs
= build_tree_list (NULL_TREE
,
3306 xref_tag (RECORD_TYPE
,
3307 get_identifier (UTAG_METHOD_LIST
)));
3309 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
3311 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3312 chainon (field_decl_chain
, field_decl
);
3314 /* struct objc_method_list *class_methods; */
3316 decl_specs
= build_tree_list (NULL_TREE
,
3317 xref_tag (RECORD_TYPE
,
3318 get_identifier (UTAG_METHOD_LIST
)));
3320 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
3322 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3323 chainon (field_decl_chain
, field_decl
);
3325 /* struct objc_protocol **protocol_list; */
3327 decl_specs
= build_tree_list (NULL_TREE
,
3328 xref_tag (RECORD_TYPE
,
3329 get_identifier (UTAG_PROTOCOL
)));
3331 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3332 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3334 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3335 chainon (field_decl_chain
, field_decl
);
3337 finish_struct (objc_category_template
, field_decl_chain
, NULL_TREE
);
3340 /* struct objc_selector {
3346 build_selector_template ()
3349 tree decl_specs
, field_decl
, field_decl_chain
;
3351 objc_selector_template
3352 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SELECTOR
));
3356 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3357 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3359 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3360 field_decl_chain
= field_decl
;
3362 /* char *sel_type; */
3364 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3365 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_type"));
3367 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3368 chainon (field_decl_chain
, field_decl
);
3370 finish_struct (objc_selector_template
, field_decl_chain
, NULL_TREE
);
3373 /* struct objc_class {
3374 struct objc_class *isa;
3375 struct objc_class *super_class;
3380 struct objc_ivar_list *ivars;
3381 struct objc_method_list *methods;
3382 if (flag_next_runtime)
3383 struct objc_cache *cache;
3385 struct sarray *dtable;
3386 struct objc_class *subclass_list;
3387 struct objc_class *sibling_class;
3389 struct objc_protocol_list *protocols;
3390 void *gc_object_type;
3394 build_class_template ()
3396 tree decl_specs
, field_decl
, field_decl_chain
;
3399 = start_struct (RECORD_TYPE
, get_identifier (UTAG_CLASS
));
3401 /* struct objc_class *isa; */
3403 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3404 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
3406 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3407 field_decl_chain
= field_decl
;
3409 /* struct objc_class *super_class; */
3411 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3413 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("super_class"));
3415 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3416 chainon (field_decl_chain
, field_decl
);
3420 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3421 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
3423 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3424 chainon (field_decl_chain
, field_decl
);
3428 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3429 field_decl
= get_identifier ("version");
3431 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3432 chainon (field_decl_chain
, field_decl
);
3436 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3437 field_decl
= get_identifier ("info");
3439 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3440 chainon (field_decl_chain
, field_decl
);
3442 /* long instance_size; */
3444 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3445 field_decl
= get_identifier ("instance_size");
3447 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3448 chainon (field_decl_chain
, field_decl
);
3450 /* struct objc_ivar_list *ivars; */
3452 decl_specs
= build_tree_list (NULL_TREE
,
3453 xref_tag (RECORD_TYPE
,
3454 get_identifier (UTAG_IVAR_LIST
)));
3455 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivars"));
3457 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3458 chainon (field_decl_chain
, field_decl
);
3460 /* struct objc_method_list *methods; */
3462 decl_specs
= build_tree_list (NULL_TREE
,
3463 xref_tag (RECORD_TYPE
,
3464 get_identifier (UTAG_METHOD_LIST
)));
3465 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("methods"));
3467 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3468 chainon (field_decl_chain
, field_decl
);
3470 if (flag_next_runtime
)
3472 /* struct objc_cache *cache; */
3474 decl_specs
= build_tree_list (NULL_TREE
,
3475 xref_tag (RECORD_TYPE
,
3476 get_identifier ("objc_cache")));
3477 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("cache"));
3478 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3479 decl_specs
, NULL_TREE
);
3480 chainon (field_decl_chain
, field_decl
);
3484 /* struct sarray *dtable; */
3486 decl_specs
= build_tree_list (NULL_TREE
,
3487 xref_tag (RECORD_TYPE
,
3488 get_identifier ("sarray")));
3489 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("dtable"));
3490 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3491 decl_specs
, NULL_TREE
);
3492 chainon (field_decl_chain
, field_decl
);
3494 /* struct objc_class *subclass_list; */
3496 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3498 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("subclass_list"));
3499 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3500 decl_specs
, NULL_TREE
);
3501 chainon (field_decl_chain
, field_decl
);
3503 /* struct objc_class *sibling_class; */
3505 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3507 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sibling_class"));
3508 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3509 decl_specs
, NULL_TREE
);
3510 chainon (field_decl_chain
, field_decl
);
3513 /* struct objc_protocol **protocol_list; */
3515 decl_specs
= build_tree_list (NULL_TREE
,
3516 xref_tag (RECORD_TYPE
,
3517 get_identifier (UTAG_PROTOCOL
)));
3519 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3521 = build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3522 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3523 decl_specs
, NULL_TREE
);
3524 chainon (field_decl_chain
, field_decl
);
3528 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3529 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3531 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3532 chainon (field_decl_chain
, field_decl
);
3534 /* void *gc_object_type; */
3536 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3537 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("gc_object_type"));
3539 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3540 chainon (field_decl_chain
, field_decl
);
3542 finish_struct (objc_class_template
, field_decl_chain
, NULL_TREE
);
3545 /* Generate appropriate forward declarations for an implementation. */
3548 synth_forward_declarations ()
3550 tree sc_spec
, decl_specs
, an_id
;
3552 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3554 an_id
= synth_id_with_class_suffix ("_OBJC_CLASS", implementation_context
);
3556 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
3557 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
3558 UOBJC_CLASS_decl
= define_decl (an_id
, decl_specs
);
3559 TREE_USED (UOBJC_CLASS_decl
) = 1;
3560 DECL_ARTIFICIAL (UOBJC_CLASS_decl
) = 1;
3562 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3564 an_id
= synth_id_with_class_suffix ("_OBJC_METACLASS",
3565 implementation_context
);
3567 UOBJC_METACLASS_decl
= define_decl (an_id
, decl_specs
);
3568 TREE_USED (UOBJC_METACLASS_decl
) = 1;
3569 DECL_ARTIFICIAL(UOBJC_METACLASS_decl
) = 1;
3571 /* Pre-build the following entities - for speed/convenience. */
3573 an_id
= get_identifier ("super_class");
3574 ucls_super_ref
= build_component_ref (UOBJC_CLASS_decl
, an_id
);
3575 uucls_super_ref
= build_component_ref (UOBJC_METACLASS_decl
, an_id
);
3579 error_with_ivar (message
, decl
, rawdecl
)
3586 report_error_function (DECL_SOURCE_FILE (decl
));
3588 fprintf (stderr
, "%s:%d: ",
3589 DECL_SOURCE_FILE (decl
), DECL_SOURCE_LINE (decl
));
3590 bzero (errbuf
, BUFSIZE
);
3591 fprintf (stderr
, "%s `%s'\n", message
, gen_declaration (rawdecl
, errbuf
));
3594 #define USERTYPE(t) \
3595 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3596 || TREE_CODE (t) == ENUMERAL_TYPE)
3599 check_ivars (inter
, imp
)
3603 tree intdecls
= CLASS_IVARS (inter
);
3604 tree impdecls
= CLASS_IVARS (imp
);
3605 tree rawintdecls
= CLASS_RAW_IVARS (inter
);
3606 tree rawimpdecls
= CLASS_RAW_IVARS (imp
);
3612 if (intdecls
== 0 && impdecls
== 0)
3614 if (intdecls
== 0 || impdecls
== 0)
3616 error ("inconsistent instance variable specification");
3620 t1
= TREE_TYPE (intdecls
); t2
= TREE_TYPE (impdecls
);
3622 if (!comptypes (t1
, t2
))
3624 if (DECL_NAME (intdecls
) == DECL_NAME (impdecls
))
3626 error_with_ivar ("conflicting instance variable type",
3627 impdecls
, rawimpdecls
);
3628 error_with_ivar ("previous declaration of",
3629 intdecls
, rawintdecls
);
3631 else /* both the type and the name don't match */
3633 error ("inconsistent instance variable specification");
3638 else if (DECL_NAME (intdecls
) != DECL_NAME (impdecls
))
3640 error_with_ivar ("conflicting instance variable name",
3641 impdecls
, rawimpdecls
);
3642 error_with_ivar ("previous declaration of",
3643 intdecls
, rawintdecls
);
3646 intdecls
= TREE_CHAIN (intdecls
);
3647 impdecls
= TREE_CHAIN (impdecls
);
3648 rawintdecls
= TREE_CHAIN (rawintdecls
);
3649 rawimpdecls
= TREE_CHAIN (rawimpdecls
);
3653 /* Set super_type to the data type node for struct objc_super *,
3654 first defining struct objc_super itself.
3655 This needs to be done just once per compilation. */
3658 build_super_template ()
3660 tree record
, decl_specs
, field_decl
, field_decl_chain
;
3662 record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_SUPER
));
3664 /* struct objc_object *self; */
3666 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3667 field_decl
= get_identifier ("self");
3668 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3669 field_decl
= grokfield (input_filename
, lineno
,
3670 field_decl
, decl_specs
, NULL_TREE
);
3671 field_decl_chain
= field_decl
;
3673 /* struct objc_class *class; */
3675 decl_specs
= get_identifier (UTAG_CLASS
);
3676 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
3677 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class"));
3679 field_decl
= grokfield (input_filename
, lineno
,
3680 field_decl
, decl_specs
, NULL_TREE
);
3681 chainon (field_decl_chain
, field_decl
);
3683 finish_struct (record
, field_decl_chain
, NULL_TREE
);
3685 /* `struct objc_super *' */
3686 super_type
= groktypename (build_tree_list (build_tree_list (NULL_TREE
,
3688 build1 (INDIRECT_REF
,
3689 NULL_TREE
, NULL_TREE
)));
3693 /* struct objc_ivar {
3700 build_ivar_template ()
3702 tree objc_ivar_id
, objc_ivar_record
;
3703 tree decl_specs
, field_decl
, field_decl_chain
;
3705 objc_ivar_id
= get_identifier (UTAG_IVAR
);
3706 objc_ivar_record
= start_struct (RECORD_TYPE
, objc_ivar_id
);
3708 /* char *ivar_name; */
3710 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3711 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_name"));
3713 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3714 decl_specs
, NULL_TREE
);
3715 field_decl_chain
= field_decl
;
3717 /* char *ivar_type; */
3719 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3720 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_type"));
3722 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3723 decl_specs
, NULL_TREE
);
3724 chainon (field_decl_chain
, field_decl
);
3726 /* int ivar_offset; */
3728 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3729 field_decl
= get_identifier ("ivar_offset");
3731 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3732 decl_specs
, NULL_TREE
);
3733 chainon (field_decl_chain
, field_decl
);
3735 finish_struct (objc_ivar_record
, field_decl_chain
, NULL_TREE
);
3737 return objc_ivar_record
;
3742 struct objc_ivar ivar_list[ivar_count];
3746 build_ivar_list_template (list_type
, size
)
3750 tree objc_ivar_list_record
;
3751 tree decl_specs
, field_decl
, field_decl_chain
;
3753 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3755 /* int ivar_count; */
3757 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3758 field_decl
= get_identifier ("ivar_count");
3760 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3761 decl_specs
, NULL_TREE
);
3762 field_decl_chain
= field_decl
;
3764 /* struct objc_ivar ivar_list[]; */
3766 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3767 field_decl
= build_nt (ARRAY_REF
, get_identifier ("ivar_list"),
3768 build_int_2 (size
, 0));
3770 field_decl
= grokfield (input_filename
, lineno
,
3771 field_decl
, decl_specs
, NULL_TREE
);
3772 chainon (field_decl_chain
, field_decl
);
3774 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3776 return objc_ivar_list_record
;
3782 struct objc_method method_list[method_count];
3786 build_method_list_template (list_type
, size
)
3790 tree objc_ivar_list_record
;
3791 tree decl_specs
, field_decl
, field_decl_chain
;
3793 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3795 /* int method_next; */
3800 xref_tag (RECORD_TYPE
,
3801 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
3803 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_next"));
3804 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3805 decl_specs
, NULL_TREE
);
3806 field_decl_chain
= field_decl
;
3808 /* int method_count; */
3810 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3811 field_decl
= get_identifier ("method_count");
3813 field_decl
= grokfield (input_filename
, lineno
,
3814 field_decl
, decl_specs
, NULL_TREE
);
3815 chainon (field_decl_chain
, field_decl
);
3817 /* struct objc_method method_list[]; */
3819 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3820 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
3821 build_int_2 (size
, 0));
3823 field_decl
= grokfield (input_filename
, lineno
,
3824 field_decl
, decl_specs
, NULL_TREE
);
3825 chainon (field_decl_chain
, field_decl
);
3827 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3829 return objc_ivar_list_record
;
3833 build_ivar_list_initializer (type
, field_decl
)
3837 tree initlist
= NULL_TREE
;
3841 tree ivar
= NULL_TREE
;
3844 if (DECL_NAME (field_decl
))
3845 ivar
= tree_cons (NULL_TREE
,
3846 add_objc_string (DECL_NAME (field_decl
),
3850 /* Unnamed bit-field ivar (yuck). */
3851 ivar
= tree_cons (NULL_TREE
, build_int_2 (0, 0), ivar
);
3854 encode_field_decl (field_decl
,
3855 obstack_object_size (&util_obstack
),
3856 OBJC_ENCODE_DONT_INLINE_DEFS
);
3858 /* Null terminate string. */
3859 obstack_1grow (&util_obstack
, 0);
3863 add_objc_string (get_identifier (obstack_finish (&util_obstack
)),
3866 obstack_free (&util_obstack
, util_firstobj
);
3872 build_int_2 ((TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl
))
3877 initlist
= tree_cons (NULL_TREE
,
3878 build_constructor (type
, nreverse (ivar
)),
3881 field_decl
= TREE_CHAIN (field_decl
);
3885 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3889 generate_ivars_list (type
, name
, size
, list
)
3895 tree sc_spec
, decl_specs
, decl
, initlist
;
3897 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3898 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
3900 decl
= start_decl (synth_id_with_class_suffix (name
, implementation_context
),
3901 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
3903 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
3904 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3907 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3914 generate_ivar_lists ()
3916 tree initlist
, ivar_list_template
, chain
;
3917 tree cast
, variable_length_type
;
3920 generating_instance_variables
= 1;
3922 if (!objc_ivar_template
)
3923 objc_ivar_template
= build_ivar_template ();
3927 (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3928 get_identifier (UTAG_IVAR_LIST
))),
3930 variable_length_type
= groktypename (cast
);
3932 /* Only generate class variables for the root of the inheritance
3933 hierarchy since these will be the same for every class. */
3935 if (CLASS_SUPER_NAME (implementation_template
) == NULL_TREE
3936 && (chain
= TYPE_FIELDS (objc_class_template
)))
3938 size
= list_length (chain
);
3940 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3941 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3943 UOBJC_CLASS_VARIABLES_decl
3944 = generate_ivars_list (ivar_list_template
, "_OBJC_CLASS_VARIABLES",
3946 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl
) = variable_length_type
;
3949 UOBJC_CLASS_VARIABLES_decl
= 0;
3951 chain
= CLASS_IVARS (implementation_template
);
3954 size
= list_length (chain
);
3955 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3956 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3958 UOBJC_INSTANCE_VARIABLES_decl
3959 = generate_ivars_list (ivar_list_template
, "_OBJC_INSTANCE_VARIABLES",
3961 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl
) = variable_length_type
;
3964 UOBJC_INSTANCE_VARIABLES_decl
= 0;
3966 generating_instance_variables
= 0;
3970 build_dispatch_table_initializer (type
, entries
)
3974 tree initlist
= NULL_TREE
;
3978 tree elemlist
= NULL_TREE
;
3980 elemlist
= tree_cons (NULL_TREE
,
3981 build_selector (METHOD_SEL_NAME (entries
)),
3984 elemlist
= tree_cons (NULL_TREE
,
3985 add_objc_string (METHOD_ENCODING (entries
),
3989 elemlist
= tree_cons (NULL_TREE
,
3990 build_unary_op (ADDR_EXPR
,
3991 METHOD_DEFINITION (entries
), 1),
3994 initlist
= tree_cons (NULL_TREE
,
3995 build_constructor (type
, nreverse (elemlist
)),
3998 entries
= TREE_CHAIN (entries
);
4002 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
4005 /* To accomplish method prototyping without generating all kinds of
4006 inane warnings, the definition of the dispatch table entries were
4009 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
4011 struct objc_method { SEL _cmd; ...; void *_imp; }; */
4014 build_method_template ()
4017 tree decl_specs
, field_decl
, field_decl_chain
;
4019 _SLT_record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD
));
4021 #ifdef OBJC_INT_SELECTORS
4022 /* unsigned int _cmd; */
4023 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_UNSIGNED
],
4025 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_INT
], decl_specs
);
4026 field_decl
= get_identifier ("_cmd");
4027 #else /* not OBJC_INT_SELECTORS */
4028 /* struct objc_selector *_cmd; */
4029 decl_specs
= tree_cons (NULL_TREE
,
4030 xref_tag (RECORD_TYPE
,
4031 get_identifier (TAG_SELECTOR
)),
4033 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
4034 #endif /* not OBJC_INT_SELECTORS */
4036 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
4037 decl_specs
, NULL_TREE
);
4038 field_decl_chain
= field_decl
;
4040 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
4041 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
,
4042 get_identifier ("method_types"));
4043 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
4044 decl_specs
, NULL_TREE
);
4045 chainon (field_decl_chain
, field_decl
);
4049 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_VOID
], NULL_TREE
);
4050 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_imp"));
4051 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
4052 decl_specs
, NULL_TREE
);
4053 chainon (field_decl_chain
, field_decl
);
4055 finish_struct (_SLT_record
, field_decl_chain
, NULL_TREE
);
4062 generate_dispatch_table (type
, name
, size
, list
)
4068 tree sc_spec
, decl_specs
, decl
, initlist
;
4070 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4071 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
4073 decl
= start_decl (synth_id_with_class_suffix (name
, implementation_context
),
4074 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
4076 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
4077 initlist
= tree_cons (NULL_TREE
, build_int_2 (size
, 0), initlist
);
4078 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
4081 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
4088 generate_dispatch_tables ()
4090 tree initlist
, chain
, method_list_template
;
4091 tree cast
, variable_length_type
;
4094 if (!objc_method_template
)
4095 objc_method_template
= build_method_template ();
4099 (build_tree_list (NULL_TREE
,
4100 xref_tag (RECORD_TYPE
,
4101 get_identifier (UTAG_METHOD_LIST
))),
4104 variable_length_type
= groktypename (cast
);
4106 chain
= CLASS_CLS_METHODS (implementation_context
);
4109 size
= list_length (chain
);
4111 method_list_template
4112 = build_method_list_template (objc_method_template
, size
);
4114 = build_dispatch_table_initializer (objc_method_template
, chain
);
4116 UOBJC_CLASS_METHODS_decl
4117 = generate_dispatch_table (method_list_template
,
4118 ((TREE_CODE (implementation_context
)
4119 == CLASS_IMPLEMENTATION_TYPE
)
4120 ? "_OBJC_CLASS_METHODS"
4121 : "_OBJC_CATEGORY_CLASS_METHODS"),
4123 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
4126 UOBJC_CLASS_METHODS_decl
= 0;
4128 chain
= CLASS_NST_METHODS (implementation_context
);
4131 size
= list_length (chain
);
4133 method_list_template
4134 = build_method_list_template (objc_method_template
, size
);
4136 = build_dispatch_table_initializer (objc_method_template
, chain
);
4138 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
4139 UOBJC_INSTANCE_METHODS_decl
4140 = generate_dispatch_table (method_list_template
,
4141 "_OBJC_INSTANCE_METHODS",
4144 /* We have a category. */
4145 UOBJC_INSTANCE_METHODS_decl
4146 = generate_dispatch_table (method_list_template
,
4147 "_OBJC_CATEGORY_INSTANCE_METHODS",
4149 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
4152 UOBJC_INSTANCE_METHODS_decl
= 0;
4156 generate_protocol_list (i_or_p
)
4159 static tree cast_type
= 0;
4160 tree initlist
, decl_specs
, sc_spec
;
4161 tree refs_decl
, expr_decl
, lproto
, e
, plist
;
4164 if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
4165 || TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4166 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
4167 else if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4168 plist
= PROTOCOL_LIST (i_or_p
);
4176 (build_tree_list (NULL_TREE
,
4177 xref_tag (RECORD_TYPE
,
4178 get_identifier (UTAG_PROTOCOL
))),
4179 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
4182 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4183 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
4184 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
4187 /* Build initializer. */
4188 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), NULL_TREE
);
4190 e
= build_int_2 (size
, 0);
4191 TREE_TYPE (e
) = cast_type
;
4192 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4194 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4196 tree pval
= TREE_VALUE (lproto
);
4198 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
4199 && PROTOCOL_FORWARD_DECL (pval
))
4201 e
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (pval
), 0);
4202 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4206 /* static struct objc_protocol *refs[n]; */
4208 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4209 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
4210 get_identifier (UTAG_PROTOCOL
)),
4213 if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4214 expr_decl
= build_nt (ARRAY_REF
,
4215 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4217 build_int_2 (size
+ 2, 0));
4218 else if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
)
4219 expr_decl
= build_nt (ARRAY_REF
,
4220 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4222 build_int_2 (size
+ 2, 0));
4223 else if (TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4225 = build_nt (ARRAY_REF
,
4226 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4228 build_int_2 (size
+ 2, 0));
4232 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
4234 refs_decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
4236 finish_decl (refs_decl
, build_constructor (TREE_TYPE (refs_decl
),
4237 nreverse (initlist
)),
4244 build_category_initializer (type
, cat_name
, class_name
,
4245 instance_methods
, class_methods
, protocol_list
)
4249 tree instance_methods
;
4253 tree initlist
= NULL_TREE
, expr
;
4255 initlist
= tree_cons (NULL_TREE
, cat_name
, initlist
);
4256 initlist
= tree_cons (NULL_TREE
, class_name
, initlist
);
4258 if (!instance_methods
)
4259 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4262 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
4263 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4266 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4269 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
4270 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4273 /* protocol_list = */
4275 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4278 static tree cast_type2
;
4284 (build_tree_list (NULL_TREE
,
4285 xref_tag (RECORD_TYPE
,
4286 get_identifier (UTAG_PROTOCOL
))),
4287 build1 (INDIRECT_REF
, NULL_TREE
,
4288 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4290 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4291 TREE_TYPE (expr
) = cast_type2
;
4292 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4295 return build_constructor (type
, nreverse (initlist
));
4298 /* struct objc_class {
4299 struct objc_class *isa;
4300 struct objc_class *super_class;
4305 struct objc_ivar_list *ivars;
4306 struct objc_method_list *methods;
4307 if (flag_next_runtime)
4308 struct objc_cache *cache;
4310 struct sarray *dtable;
4311 struct objc_class *subclass_list;
4312 struct objc_class *sibling_class;
4314 struct objc_protocol_list *protocols;
4315 void *gc_object_type;
4319 build_shared_structure_initializer (type
, isa
, super
, name
, size
, status
,
4320 dispatch_table
, ivar_list
, protocol_list
)
4327 tree dispatch_table
;
4331 tree initlist
= NULL_TREE
, expr
;
4334 initlist
= tree_cons (NULL_TREE
, isa
, initlist
);
4337 initlist
= tree_cons (NULL_TREE
, super
, initlist
);
4340 initlist
= tree_cons (NULL_TREE
, default_conversion (name
), initlist
);
4343 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4346 initlist
= tree_cons (NULL_TREE
, build_int_2 (status
, 0), initlist
);
4348 /* instance_size = */
4349 initlist
= tree_cons (NULL_TREE
, size
, initlist
);
4351 /* objc_ivar_list = */
4353 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4356 expr
= build_unary_op (ADDR_EXPR
, ivar_list
, 0);
4357 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4360 /* objc_method_list = */
4361 if (!dispatch_table
)
4362 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4365 expr
= build_unary_op (ADDR_EXPR
, dispatch_table
, 0);
4366 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4369 if (flag_next_runtime
)
4370 /* method_cache = */
4371 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4375 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4377 /* subclass_list = */
4378 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4380 /* sibling_class = */
4381 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4384 /* protocol_list = */
4385 if (! protocol_list
)
4386 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4389 static tree cast_type2
;
4395 (build_tree_list (NULL_TREE
,
4396 xref_tag (RECORD_TYPE
,
4397 get_identifier (UTAG_PROTOCOL
))),
4398 build1 (INDIRECT_REF
, NULL_TREE
,
4399 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4401 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4402 TREE_TYPE (expr
) = cast_type2
;
4403 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4406 /* gc_object_type = NULL */
4407 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4409 return build_constructor (type
, nreverse (initlist
));
4412 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4415 generate_category (cat
)
4418 tree sc_spec
, decl_specs
, decl
;
4419 tree initlist
, cat_name_expr
, class_name_expr
;
4420 tree protocol_decl
, category
;
4422 add_class_reference (CLASS_NAME (cat
));
4423 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
4425 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
4427 category
= CLASS_CATEGORY_LIST (implementation_template
);
4429 /* find the category interface from the class it is associated with */
4432 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
4434 category
= CLASS_CATEGORY_LIST (category
);
4437 if (category
&& CLASS_PROTOCOL_LIST (category
))
4439 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
4440 protocol_decl
= generate_protocol_list (category
);
4445 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4446 decl_specs
= tree_cons (NULL_TREE
, objc_category_template
, sc_spec
);
4448 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4449 implementation_context
),
4450 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
4452 initlist
= build_category_initializer (TREE_TYPE (decl
),
4453 cat_name_expr
, class_name_expr
,
4454 UOBJC_INSTANCE_METHODS_decl
,
4455 UOBJC_CLASS_METHODS_decl
,
4458 TREE_USED (decl
) = 1;
4459 finish_decl (decl
, initlist
, NULL_TREE
);
4462 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4463 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4466 generate_shared_structures ()
4468 tree sc_spec
, decl_specs
, decl
;
4469 tree name_expr
, super_expr
, root_expr
;
4470 tree my_root_id
= NULL_TREE
, my_super_id
= NULL_TREE
;
4471 tree cast_type
, initlist
, protocol_decl
;
4473 my_super_id
= CLASS_SUPER_NAME (implementation_template
);
4476 add_class_reference (my_super_id
);
4478 /* Compute "my_root_id" - this is required for code generation.
4479 the "isa" for all meta class structures points to the root of
4480 the inheritance hierarchy (e.g. "__Object")... */
4481 my_root_id
= my_super_id
;
4484 tree my_root_int
= lookup_interface (my_root_id
);
4486 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
4487 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
4494 /* No super class. */
4495 my_root_id
= CLASS_NAME (implementation_template
);
4498 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
4499 objc_class_template
),
4500 build1 (INDIRECT_REF
,
4501 NULL_TREE
, NULL_TREE
)));
4503 name_expr
= add_objc_string (CLASS_NAME (implementation_template
),
4506 /* Install class `isa' and `super' pointers at runtime. */
4509 super_expr
= add_objc_string (my_super_id
, class_names
);
4510 super_expr
= build_c_cast (cast_type
, super_expr
); /* cast! */
4513 super_expr
= build_int_2 (0, 0);
4515 root_expr
= add_objc_string (my_root_id
, class_names
);
4516 root_expr
= build_c_cast (cast_type
, root_expr
); /* cast! */
4518 if (CLASS_PROTOCOL_LIST (implementation_template
))
4520 generate_protocol_references
4521 (CLASS_PROTOCOL_LIST (implementation_template
));
4522 protocol_decl
= generate_protocol_list (implementation_template
);
4527 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4529 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
4530 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
4532 decl
= start_decl (DECL_NAME (UOBJC_METACLASS_decl
), decl_specs
, 1,
4533 NULL_TREE
, NULL_TREE
);
4536 = build_shared_structure_initializer
4538 root_expr
, super_expr
, name_expr
,
4539 build_int_2 ((TREE_INT_CST_LOW (TYPE_SIZE (objc_class_template
))
4543 UOBJC_CLASS_METHODS_decl
,
4544 UOBJC_CLASS_VARIABLES_decl
,
4547 finish_decl (decl
, initlist
, NULL_TREE
);
4549 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4551 decl
= start_decl (DECL_NAME (UOBJC_CLASS_decl
), decl_specs
, 1,
4552 NULL_TREE
, NULL_TREE
);
4555 = build_shared_structure_initializer
4557 build_unary_op (ADDR_EXPR
, UOBJC_METACLASS_decl
, 0),
4558 super_expr
, name_expr
,
4561 (TYPE_SIZE (CLASS_STATIC_TEMPLATE (implementation_template
)))
4565 UOBJC_INSTANCE_METHODS_decl
,
4566 UOBJC_INSTANCE_VARIABLES_decl
,
4569 finish_decl (decl
, initlist
, NULL_TREE
);
4573 synth_id_with_class_suffix (preamble
, ctxt
)
4578 if (TREE_CODE (ctxt
) == CLASS_IMPLEMENTATION_TYPE
4579 || TREE_CODE (ctxt
) == CLASS_INTERFACE_TYPE
)
4582 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
4583 string
= (char *) alloca (strlen (preamble
) + strlen (class_name
) + 3);
4584 sprintf (string
, "%s_%s", preamble
,
4585 IDENTIFIER_POINTER (CLASS_NAME (ctxt
)));
4587 else if (TREE_CODE (ctxt
) == CATEGORY_IMPLEMENTATION_TYPE
4588 || TREE_CODE (ctxt
) == CATEGORY_INTERFACE_TYPE
)
4590 /* We have a category. */
4592 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
4593 char *class_super_name
4594 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
));
4595 string
= (char *) alloca (strlen (preamble
)
4596 + strlen (class_name
)
4597 + strlen (class_super_name
)
4599 sprintf (string
, "%s_%s_%s", preamble
, class_name
, class_super_name
);
4601 else if (TREE_CODE (ctxt
) == PROTOCOL_INTERFACE_TYPE
)
4603 char *protocol_name
= IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt
));
4605 = (char *) alloca (strlen (preamble
) + strlen (protocol_name
) + 3);
4606 sprintf (string
, "%s_%s", preamble
, protocol_name
);
4611 return get_identifier (string
);
4615 is_objc_type_qualifier (node
)
4618 return (TREE_CODE (node
) == IDENTIFIER_NODE
4619 && (node
== ridpointers
[(int) RID_CONST
]
4620 || node
== ridpointers
[(int) RID_VOLATILE
]
4621 || node
== ridpointers
[(int) RID_IN
]
4622 || node
== ridpointers
[(int) RID_OUT
]
4623 || node
== ridpointers
[(int) RID_INOUT
]
4624 || node
== ridpointers
[(int) RID_BYCOPY
]
4625 || node
== ridpointers
[(int) RID_BYREF
]
4626 || node
== ridpointers
[(int) RID_ONEWAY
]));
4629 /* If type is empty or only type qualifiers are present, add default
4630 type of id (otherwise grokdeclarator will default to int). */
4633 adjust_type_for_id_default (type
)
4636 tree declspecs
, chain
;
4639 return build_tree_list (build_tree_list (NULL_TREE
, objc_object_reference
),
4640 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4642 declspecs
= TREE_PURPOSE (type
);
4644 /* Determine if a typespec is present. */
4645 for (chain
= declspecs
;
4647 chain
= TREE_CHAIN (chain
))
4649 if (!is_objc_type_qualifier (TREE_VALUE (chain
)))
4653 return build_tree_list (tree_cons (NULL_TREE
, objc_object_reference
,
4655 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4660 selector ':' '(' typename ')' identifier
4663 Transform an Objective-C keyword argument into
4664 the C equivalent parameter declarator.
4666 In: key_name, an "identifier_node" (optional).
4667 arg_type, a "tree_list" (optional).
4668 arg_name, an "identifier_node".
4670 Note: It would be really nice to strongly type the preceding
4671 arguments in the function prototype; however, then I
4672 could not use the "accessor" macros defined in "tree.h".
4674 Out: an instance of "keyword_decl". */
4677 build_keyword_decl (key_name
, arg_type
, arg_name
)
4684 /* If no type is specified, default to "id". */
4685 arg_type
= adjust_type_for_id_default (arg_type
);
4687 keyword_decl
= make_node (KEYWORD_DECL
);
4689 TREE_TYPE (keyword_decl
) = arg_type
;
4690 KEYWORD_ARG_NAME (keyword_decl
) = arg_name
;
4691 KEYWORD_KEY_NAME (keyword_decl
) = key_name
;
4693 return keyword_decl
;
4696 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4699 build_keyword_selector (selector
)
4703 tree key_chain
, key_name
;
4706 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4708 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4709 key_name
= KEYWORD_KEY_NAME (key_chain
);
4710 else if (TREE_CODE (selector
) == TREE_LIST
)
4711 key_name
= TREE_PURPOSE (key_chain
);
4716 len
+= IDENTIFIER_LENGTH (key_name
) + 1;
4718 /* Just a ':' arg. */
4722 buf
= (char *)alloca (len
+ 1);
4723 bzero (buf
, len
+ 1);
4725 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4727 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4728 key_name
= KEYWORD_KEY_NAME (key_chain
);
4729 else if (TREE_CODE (selector
) == TREE_LIST
)
4730 key_name
= TREE_PURPOSE (key_chain
);
4735 strcat (buf
, IDENTIFIER_POINTER (key_name
));
4739 return get_identifier (buf
);
4742 /* Used for declarations and definitions. */
4745 build_method_decl (code
, ret_type
, selector
, add_args
)
4746 enum tree_code code
;
4753 /* If no type is specified, default to "id". */
4754 ret_type
= adjust_type_for_id_default (ret_type
);
4756 method_decl
= make_node (code
);
4757 TREE_TYPE (method_decl
) = ret_type
;
4759 /* If we have a keyword selector, create an identifier_node that
4760 represents the full selector name (`:' included)... */
4761 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4763 METHOD_SEL_NAME (method_decl
) = build_keyword_selector (selector
);
4764 METHOD_SEL_ARGS (method_decl
) = selector
;
4765 METHOD_ADD_ARGS (method_decl
) = add_args
;
4769 METHOD_SEL_NAME (method_decl
) = selector
;
4770 METHOD_SEL_ARGS (method_decl
) = NULL_TREE
;
4771 METHOD_ADD_ARGS (method_decl
) = NULL_TREE
;
4777 #define METHOD_DEF 0
4778 #define METHOD_REF 1
4780 /* Used by `build_message_expr' and `comp_method_types'. Return an
4781 argument list for method METH. CONTEXT is either METHOD_DEF or
4782 METHOD_REF, saying whether we are trying to define a method or call
4783 one. SUPERFLAG says this is for a send to super; this makes a
4784 difference for the NeXT calling sequence in which the lookup and
4785 the method call are done together. */
4788 get_arg_type_list (meth
, context
, superflag
)
4795 /* Receiver type. */
4796 if (flag_next_runtime
&& superflag
)
4797 arglist
= build_tree_list (NULL_TREE
, super_type
);
4798 else if (context
== METHOD_DEF
)
4799 arglist
= build_tree_list (NULL_TREE
, TREE_TYPE (self_decl
));
4801 arglist
= build_tree_list (NULL_TREE
, id_type
);
4803 /* Selector type - will eventually change to `int'. */
4804 chainon (arglist
, build_tree_list (NULL_TREE
, selector_type
));
4806 /* Build a list of argument types. */
4807 for (akey
= METHOD_SEL_ARGS (meth
); akey
; akey
= TREE_CHAIN (akey
))
4809 tree arg_decl
= groktypename_in_parm_context (TREE_TYPE (akey
));
4810 chainon (arglist
, build_tree_list (NULL_TREE
, TREE_TYPE (arg_decl
)));
4813 if (METHOD_ADD_ARGS (meth
) == (tree
)1)
4814 /* We have a `, ...' immediately following the selector,
4815 finalize the arglist...simulate get_parm_info (0). */
4817 else if (METHOD_ADD_ARGS (meth
))
4819 /* we have a variable length selector */
4820 tree add_arg_list
= TREE_CHAIN (METHOD_ADD_ARGS (meth
));
4821 chainon (arglist
, add_arg_list
);
4824 /* finalize the arglist...simulate get_parm_info (1) */
4825 chainon (arglist
, build_tree_list (NULL_TREE
, void_type_node
));
4831 check_duplicates (hsh
)
4834 tree meth
= NULL_TREE
;
4842 /* We have two methods with the same name and different types. */
4844 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
) ? '-' : '+';
4846 warning ("multiple declarations for method `%s'",
4847 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
4849 warn_with_method ("using", type
, meth
);
4850 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
4851 warn_with_method ("also found", type
, loop
->value
);
4857 /* If RECEIVER is a class reference, return the identifier node for the
4858 referenced class. RECEIVER is created by get_class_reference, so we
4859 check the exact form created depending on which runtimes are used. */
4862 receiver_is_class_object (receiver
)
4865 tree chain
, exp
, arg
;
4866 if (flag_next_runtime
)
4868 /* The receiver is a variable created by build_class_reference_decl. */
4869 if (TREE_CODE (receiver
) == VAR_DECL
4870 && TREE_TYPE (receiver
) == objc_class_type
)
4871 /* Look up the identifier. */
4872 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
4873 if (TREE_PURPOSE (chain
) == receiver
)
4874 return TREE_VALUE (chain
);
4878 /* The receiver is a function call that returns an id. Check if
4879 it is a call to objc_getClass, if so, pick up the class name. */
4880 if ((exp
= TREE_OPERAND (receiver
, 0))
4881 && TREE_CODE (exp
) == ADDR_EXPR
4882 && (exp
= TREE_OPERAND (exp
, 0))
4883 && TREE_CODE (exp
) == FUNCTION_DECL
4884 && exp
== objc_get_class_decl
4885 /* we have a call to objc_getClass! */
4886 && (arg
= TREE_OPERAND (receiver
, 1))
4887 && TREE_CODE (arg
) == TREE_LIST
4888 && (arg
= TREE_VALUE (arg
)))
4891 if (TREE_CODE (arg
) == ADDR_EXPR
4892 && (arg
= TREE_OPERAND (arg
, 0))
4893 && TREE_CODE (arg
) == STRING_CST
)
4894 /* Finally, we have the class name. */
4895 return get_identifier (TREE_STRING_POINTER (arg
));
4901 /* If we are currently building a message expr, this holds
4902 the identifier of the selector of the message. This is
4903 used when printing warnings about argument mismatches. */
4905 static tree building_objc_message_expr
= 0;
4908 maybe_building_objc_message_expr ()
4910 return building_objc_message_expr
;
4913 /* Construct an expression for sending a message.
4914 MESS has the object to send to in TREE_PURPOSE
4915 and the argument list (including selector) in TREE_VALUE.
4917 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4918 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4921 build_message_expr (mess
)
4924 tree receiver
= TREE_PURPOSE (mess
);
4925 tree selector
, self_object
;
4926 tree rtype
, sel_name
;
4927 tree args
= TREE_VALUE (mess
);
4928 tree method_params
= NULL_TREE
;
4929 tree method_prototype
= NULL_TREE
;
4931 int statically_typed
= 0, statically_allocated
= 0;
4932 tree class_ident
= 0;
4934 /* 1 if this is sending to the superclass. */
4937 if (!doing_objc_thang
)
4940 if (TREE_CODE (receiver
) == ERROR_MARK
)
4941 return error_mark_node
;
4943 /* Determine receiver type. */
4944 rtype
= TREE_TYPE (receiver
);
4945 super
= IS_SUPER (rtype
);
4949 if (TREE_STATIC_TEMPLATE (rtype
))
4950 statically_allocated
= 1;
4951 else if (TREE_CODE (rtype
) == POINTER_TYPE
4952 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype
)))
4953 statically_typed
= 1;
4954 else if ((flag_next_runtime
4955 || (TREE_CODE (receiver
) == CALL_EXPR
&& IS_ID (rtype
)))
4956 && (class_ident
= receiver_is_class_object (receiver
)))
4958 else if (! IS_ID (rtype
)
4959 /* Allow any type that matches objc_class_type. */
4960 && ! comptypes (rtype
, objc_class_type
))
4962 bzero (errbuf
, BUFSIZE
);
4963 warning ("invalid receiver type `%s'",
4964 gen_declaration (rtype
, errbuf
));
4967 if (statically_allocated
)
4968 receiver
= build_unary_op (ADDR_EXPR
, receiver
, 0);
4970 /* Don't evaluate the receiver twice. */
4971 receiver
= save_expr (receiver
);
4972 self_object
= receiver
;
4975 /* If sending to `super', use current self as the object. */
4976 self_object
= self_decl
;
4978 /* Obtain the full selector name. */
4980 if (TREE_CODE (args
) == IDENTIFIER_NODE
)
4981 /* A unary selector. */
4983 else if (TREE_CODE (args
) == TREE_LIST
)
4984 sel_name
= build_keyword_selector (args
);
4988 /* Build the parameter list to give to the method. */
4990 method_params
= NULL_TREE
;
4991 if (TREE_CODE (args
) == TREE_LIST
)
4993 tree chain
= args
, prev
= NULL_TREE
;
4995 /* We have a keyword selector--check for comma expressions. */
4998 tree element
= TREE_VALUE (chain
);
5000 /* We have a comma expression, must collapse... */
5001 if (TREE_CODE (element
) == TREE_LIST
)
5004 TREE_CHAIN (prev
) = element
;
5009 chain
= TREE_CHAIN (chain
);
5011 method_params
= args
;
5014 /* Determine operation return type. */
5016 if (IS_SUPER (rtype
))
5020 if (CLASS_SUPER_NAME (implementation_template
))
5023 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
5025 if (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
)
5026 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5028 method_prototype
= lookup_class_method_static (iface
, sel_name
);
5030 if (iface
&& !method_prototype
)
5031 warning ("`%s' does not respond to `%s'",
5032 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template
)),
5033 IDENTIFIER_POINTER (sel_name
));
5037 error ("no super class declared in interface for `%s'",
5038 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
5039 return error_mark_node
;
5043 else if (statically_allocated
)
5045 tree ctype
= TREE_TYPE (rtype
);
5046 tree iface
= lookup_interface (TYPE_NAME (rtype
));
5049 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5051 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
5053 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
5056 if (!method_prototype
)
5057 warning ("`%s' does not respond to `%s'",
5058 IDENTIFIER_POINTER (TYPE_NAME (rtype
)),
5059 IDENTIFIER_POINTER (sel_name
));
5061 else if (statically_typed
)
5063 tree ctype
= TREE_TYPE (rtype
);
5065 /* `self' is now statically_typed. All methods should be visible
5066 within the context of the implementation. */
5067 if (implementation_context
5068 && CLASS_NAME (implementation_context
) == TYPE_NAME (ctype
))
5071 = lookup_instance_method_static (implementation_template
,
5074 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
5076 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
5079 if (! method_prototype
5080 && implementation_template
!= implementation_context
)
5081 /* The method is not published in the interface. Check
5084 = lookup_method (CLASS_NST_METHODS (implementation_context
),
5091 if ((iface
= lookup_interface (TYPE_NAME (ctype
))))
5092 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5094 if (! method_prototype
)
5096 tree protocol_list
= TYPE_PROTOCOL_LIST (ctype
);
5099 = lookup_method_in_protocol_list (protocol_list
,
5104 if (!method_prototype
)
5105 warning ("`%s' does not respond to `%s'",
5106 IDENTIFIER_POINTER (TYPE_NAME (ctype
)),
5107 IDENTIFIER_POINTER (sel_name
));
5109 else if (class_ident
)
5111 if (implementation_context
5112 && CLASS_NAME (implementation_context
) == class_ident
)
5115 = lookup_class_method_static (implementation_template
, sel_name
);
5117 if (!method_prototype
5118 && implementation_template
!= implementation_context
)
5119 /* The method is not published in the interface. Check
5122 = lookup_method (CLASS_CLS_METHODS (implementation_context
),
5129 if ((iface
= lookup_interface (class_ident
)))
5130 method_prototype
= lookup_class_method_static (iface
, sel_name
);
5133 if (!method_prototype
)
5135 warning ("cannot find class (factory) method.");
5136 warning ("return type for `%s' defaults to id",
5137 IDENTIFIER_POINTER (sel_name
));
5140 else if (IS_PROTOCOL_QUALIFIED_ID (rtype
))
5142 /* An anonymous object that has been qualified with a protocol. */
5144 tree protocol_list
= TYPE_PROTOCOL_LIST (rtype
);
5146 method_prototype
= lookup_method_in_protocol_list (protocol_list
,
5149 if (!method_prototype
)
5153 warning ("method `%s' not implemented by protocol.",
5154 IDENTIFIER_POINTER (sel_name
));
5156 /* Try and find the method signature in the global pools. */
5158 if (!(hsh
= hash_lookup (nst_method_hash_list
, sel_name
)))
5159 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5161 if (!(method_prototype
= check_duplicates (hsh
)))
5162 warning ("return type defaults to id");
5169 /* We think we have an instance...loophole: extern id Object; */
5170 hsh
= hash_lookup (nst_method_hash_list
, sel_name
);
5172 /* For various loopholes, like sending messages to self in a
5174 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5176 method_prototype
= check_duplicates (hsh
);
5177 if (!method_prototype
)
5179 warning ("cannot find method.");
5180 warning ("return type for `%s' defaults to id",
5181 IDENTIFIER_POINTER (sel_name
));
5185 /* Save the selector name for printing error messages. */
5186 building_objc_message_expr
= sel_name
;
5188 /* Build the parameters list for looking up the method.
5189 These are the object itself and the selector. */
5191 if (flag_typed_selectors
)
5192 selector
= build_typed_selector_reference (sel_name
, method_prototype
);
5194 selector
= build_selector_reference (sel_name
);
5196 retval
= build_objc_method_call (super
, method_prototype
,
5197 receiver
, self_object
,
5198 selector
, method_params
);
5200 building_objc_message_expr
= 0;
5205 /* Build a tree expression to send OBJECT the operation SELECTOR,
5206 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5207 assuming the method has prototype METHOD_PROTOTYPE.
5208 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5209 Use METHOD_PARAMS as list of args to pass to the method.
5210 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5213 build_objc_method_call (super_flag
, method_prototype
, lookup_object
, object
,
5214 selector
, method_params
)
5216 tree method_prototype
, lookup_object
, object
, selector
, method_params
;
5218 tree sender
= (super_flag
? umsg_super_decl
: umsg_decl
);
5219 tree rcv_p
= (super_flag
5220 ? build_pointer_type (xref_tag (RECORD_TYPE
,
5221 get_identifier (TAG_SUPER
)))
5224 if (flag_next_runtime
)
5226 if (! method_prototype
)
5228 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5229 tree_cons (NULL_TREE
, selector
,
5231 assemble_external (sender
);
5232 return build_function_call (sender
, method_params
);
5236 /* This is a real kludge, but it is used only for the Next.
5237 Clobber the data type of SENDER temporarily to accept
5238 all the arguments for this operation, and to return
5239 whatever this operation returns. */
5240 tree arglist
= NULL_TREE
;
5243 /* Save the proper contents of SENDER's data type. */
5244 tree savarg
= TYPE_ARG_TYPES (TREE_TYPE (sender
));
5245 tree savret
= TREE_TYPE (TREE_TYPE (sender
));
5247 /* Install this method's argument types. */
5248 arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5250 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = arglist
;
5252 /* Install this method's return type. */
5253 TREE_TYPE (TREE_TYPE (sender
))
5254 = groktypename (TREE_TYPE (method_prototype
));
5256 /* Call SENDER with all the parameters. This will do type
5257 checking using the arg types for this method. */
5258 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5259 tree_cons (NULL_TREE
, selector
,
5261 assemble_external (sender
);
5262 retval
= build_function_call (sender
, method_params
);
5264 /* Restore SENDER's return/argument types. */
5265 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = savarg
;
5266 TREE_TYPE (TREE_TYPE (sender
)) = savret
;
5272 /* This is the portable way.
5273 First call the lookup function to get a pointer to the method,
5274 then cast the pointer, then call it with the method arguments. */
5277 /* Avoid trouble since we may evaluate each of these twice. */
5278 object
= save_expr (object
);
5279 selector
= save_expr (selector
);
5281 lookup_object
= build_c_cast (rcv_p
, lookup_object
);
5283 assemble_external (sender
);
5285 = build_function_call (sender
,
5286 tree_cons (NULL_TREE
, lookup_object
,
5287 tree_cons (NULL_TREE
, selector
,
5290 /* If we have a method prototype, construct the data type this
5291 method needs, and cast what we got from SENDER into a pointer
5293 if (method_prototype
)
5295 tree arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5297 tree valtype
= groktypename (TREE_TYPE (method_prototype
));
5298 tree fake_function_type
= build_function_type (valtype
, arglist
);
5299 TREE_TYPE (method
) = build_pointer_type (fake_function_type
);
5303 = build_pointer_type (build_function_type (ptr_type_node
, NULL_TREE
));
5305 /* Pass the object to the method. */
5306 assemble_external (method
);
5307 return build_function_call (method
,
5308 tree_cons (NULL_TREE
, object
,
5309 tree_cons (NULL_TREE
, selector
,
5315 build_protocol_reference (p
)
5318 tree decl
, ident
, ptype
;
5320 push_obstacks_nochange ();
5321 end_temporary_allocation ();
5323 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5325 ident
= synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
);
5327 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
5328 objc_protocol_template
),
5331 if (IDENTIFIER_GLOBAL_VALUE (ident
))
5332 decl
= IDENTIFIER_GLOBAL_VALUE (ident
); /* Set by pushdecl. */
5335 decl
= build_decl (VAR_DECL
, ident
, ptype
);
5336 DECL_EXTERNAL (decl
) = 1;
5337 TREE_PUBLIC (decl
) = 1;
5338 TREE_USED (decl
) = 1;
5339 DECL_ARTIFICIAL (decl
) = 1;
5341 make_decl_rtl (decl
, 0, 1);
5342 pushdecl_top_level (decl
);
5345 PROTOCOL_FORWARD_DECL (p
) = decl
;
5350 build_protocol_expr (protoname
)
5356 if (!doing_objc_thang
)
5359 p
= lookup_protocol (protoname
);
5363 error ("Cannot find protocol declaration for `%s'",
5364 IDENTIFIER_POINTER (protoname
));
5365 return error_mark_node
;
5368 if (!PROTOCOL_FORWARD_DECL (p
))
5369 build_protocol_reference (p
);
5371 expr
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
5373 TREE_TYPE (expr
) = protocol_type
;
5379 build_selector_expr (selnamelist
)
5384 if (!doing_objc_thang
)
5387 /* Obtain the full selector name. */
5388 if (TREE_CODE (selnamelist
) == IDENTIFIER_NODE
)
5389 /* A unary selector. */
5390 selname
= selnamelist
;
5391 else if (TREE_CODE (selnamelist
) == TREE_LIST
)
5392 selname
= build_keyword_selector (selnamelist
);
5396 if (flag_typed_selectors
)
5397 return build_typed_selector_reference (selname
, 0);
5399 return build_selector_reference (selname
);
5403 build_encode_expr (type
)
5409 if (!doing_objc_thang
)
5412 encode_type (type
, obstack_object_size (&util_obstack
),
5413 OBJC_ENCODE_INLINE_DEFS
);
5414 obstack_1grow (&util_obstack
, 0); /* null terminate string */
5415 string
= obstack_finish (&util_obstack
);
5417 /* Synthesize a string that represents the encoded struct/union. */
5418 result
= my_build_string (strlen (string
) + 1, string
);
5419 obstack_free (&util_obstack
, util_firstobj
);
5424 build_ivar_reference (id
)
5427 if (TREE_CODE (method_context
) == CLASS_METHOD_DECL
)
5429 /* Historically, a class method that produced objects (factory
5430 method) would assign `self' to the instance that it
5431 allocated. This would effectively turn the class method into
5432 an instance method. Following this assignment, the instance
5433 variables could be accessed. That practice, while safe,
5434 violates the simple rule that a class method should not refer
5435 to an instance variable. It's better to catch the cases
5436 where this is done unknowingly than to support the above
5438 warning ("instance variable `%s' accessed in class method",
5439 IDENTIFIER_POINTER (id
));
5440 TREE_TYPE (self_decl
) = instance_type
; /* cast */
5443 return build_component_ref (build_indirect_ref (self_decl
, "->"), id
);
5446 #define HASH_ALLOC_LIST_SIZE 170
5447 #define ATTR_ALLOC_LIST_SIZE 170
5448 #define SIZEHASHTABLE 257
5451 #define HASHFUNCTION(key) ((HOST_WIDE_INT) key & 0x7fffffff)
5456 nst_method_hash_list
= (hash
*)xmalloc (SIZEHASHTABLE
* sizeof (hash
));
5457 cls_method_hash_list
= (hash
*)xmalloc (SIZEHASHTABLE
* sizeof (hash
));
5459 if (!nst_method_hash_list
|| !cls_method_hash_list
)
5460 perror ("unable to allocate space in objc-tree.c");
5465 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
5467 nst_method_hash_list
[i
] = 0;
5468 cls_method_hash_list
[i
] = 0;
5474 hash_enter (hashlist
, method
)
5478 static hash hash_alloc_list
= 0;
5479 static int hash_alloc_index
= 0;
5481 int slot
= HASHFUNCTION (METHOD_SEL_NAME (method
)) % SIZEHASHTABLE
;
5483 if (! hash_alloc_list
|| hash_alloc_index
>= HASH_ALLOC_LIST_SIZE
)
5485 hash_alloc_index
= 0;
5486 hash_alloc_list
= (hash
) xmalloc (sizeof (struct hashed_entry
)
5487 * HASH_ALLOC_LIST_SIZE
);
5488 if (! hash_alloc_list
)
5489 perror ("unable to allocate in objc-tree.c");
5491 obj
= &hash_alloc_list
[hash_alloc_index
++];
5493 obj
->next
= hashlist
[slot
];
5496 hashlist
[slot
] = obj
; /* append to front */
5500 hash_lookup (hashlist
, sel_name
)
5506 target
= hashlist
[HASHFUNCTION (sel_name
) % SIZEHASHTABLE
];
5510 if (sel_name
== METHOD_SEL_NAME (target
->key
))
5513 target
= target
->next
;
5519 hash_add_attr (entry
, value
)
5523 static attr attr_alloc_list
= 0;
5524 static int attr_alloc_index
= 0;
5527 if (! attr_alloc_list
|| attr_alloc_index
>= ATTR_ALLOC_LIST_SIZE
)
5529 attr_alloc_index
= 0;
5530 attr_alloc_list
= (attr
) xmalloc (sizeof (struct hashed_attribute
)
5531 * ATTR_ALLOC_LIST_SIZE
);
5532 if (! attr_alloc_list
)
5533 perror ("unable to allocate in objc-tree.c");
5535 obj
= &attr_alloc_list
[attr_alloc_index
++];
5536 obj
->next
= entry
->list
;
5539 entry
->list
= obj
; /* append to front */
5543 lookup_method (mchain
, method
)
5549 if (TREE_CODE (method
) == IDENTIFIER_NODE
)
5552 key
= METHOD_SEL_NAME (method
);
5556 if (METHOD_SEL_NAME (mchain
) == key
)
5558 mchain
= TREE_CHAIN (mchain
);
5564 lookup_instance_method_static (interface
, ident
)
5568 tree inter
= interface
;
5569 tree chain
= CLASS_NST_METHODS (inter
);
5570 tree meth
= NULL_TREE
;
5574 if ((meth
= lookup_method (chain
, ident
)))
5577 if (CLASS_CATEGORY_LIST (inter
))
5579 tree category
= CLASS_CATEGORY_LIST (inter
);
5580 chain
= CLASS_NST_METHODS (category
);
5584 if ((meth
= lookup_method (chain
, ident
)))
5587 /* Check for instance methods in protocols in categories. */
5588 if (CLASS_PROTOCOL_LIST (category
))
5590 if ((meth
= (lookup_method_in_protocol_list
5591 (CLASS_PROTOCOL_LIST (category
), ident
, 0))))
5595 if ((category
= CLASS_CATEGORY_LIST (category
)))
5596 chain
= CLASS_NST_METHODS (category
);
5601 if (CLASS_PROTOCOL_LIST (inter
))
5603 if ((meth
= (lookup_method_in_protocol_list
5604 (CLASS_PROTOCOL_LIST (inter
), ident
, 0))))
5608 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5609 chain
= CLASS_NST_METHODS (inter
);
5617 lookup_class_method_static (interface
, ident
)
5621 tree inter
= interface
;
5622 tree chain
= CLASS_CLS_METHODS (inter
);
5623 tree meth
= NULL_TREE
;
5624 tree root_inter
= NULL_TREE
;
5628 if ((meth
= lookup_method (chain
, ident
)))
5631 if (CLASS_CATEGORY_LIST (inter
))
5633 tree category
= CLASS_CATEGORY_LIST (inter
);
5634 chain
= CLASS_CLS_METHODS (category
);
5638 if ((meth
= lookup_method (chain
, ident
)))
5641 /* Check for class methods in protocols in categories. */
5642 if (CLASS_PROTOCOL_LIST (category
))
5644 if ((meth
= (lookup_method_in_protocol_list
5645 (CLASS_PROTOCOL_LIST (category
), ident
, 1))))
5649 if ((category
= CLASS_CATEGORY_LIST (category
)))
5650 chain
= CLASS_CLS_METHODS (category
);
5655 /* Check for class methods in protocols. */
5656 if (CLASS_PROTOCOL_LIST (inter
))
5658 if ((meth
= (lookup_method_in_protocol_list
5659 (CLASS_PROTOCOL_LIST (inter
), ident
, 1))))
5664 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5665 chain
= CLASS_CLS_METHODS (inter
);
5669 /* Simulate wrap around. */
5670 return lookup_instance_method_static (root_inter
, ident
);
5674 add_class_method (class, method
)
5681 /* We will have allocated the method parameter declarations on the
5682 maybepermanent_obstack. Need to make sure they stick around! */
5685 if (!(mth
= lookup_method (CLASS_CLS_METHODS (class), method
)))
5687 /* put method on list in reverse order */
5688 TREE_CHAIN (method
) = CLASS_CLS_METHODS (class);
5689 CLASS_CLS_METHODS (class) = method
;
5693 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5694 error ("duplicate definition of class method `%s'.",
5695 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5698 /* Check types; if different, complain. */
5699 if (!comp_proto_with_proto (method
, mth
))
5700 error ("duplicate declaration of class method `%s'.",
5701 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5705 if (!(hsh
= hash_lookup (cls_method_hash_list
, METHOD_SEL_NAME (method
))))
5707 /* Install on a global chain. */
5708 hash_enter (cls_method_hash_list
, method
);
5712 /* Check types; if different, add to a list. */
5713 if (!comp_proto_with_proto (method
, hsh
->key
))
5714 hash_add_attr (hsh
, method
);
5720 add_instance_method (class, method
)
5727 /* We will have allocated the method parameter declarations on the
5728 maybepermanent_obstack. Need to make sure they stick around! */
5731 if (!(mth
= lookup_method (CLASS_NST_METHODS (class), method
)))
5733 /* Put method on list in reverse order. */
5734 TREE_CHAIN (method
) = CLASS_NST_METHODS (class);
5735 CLASS_NST_METHODS (class) = method
;
5739 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5740 error ("duplicate definition of instance method `%s'.",
5741 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5744 /* Check types; if different, complain. */
5745 if (!comp_proto_with_proto (method
, mth
))
5746 error ("duplicate declaration of instance method `%s'.",
5747 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5751 if (!(hsh
= hash_lookup (nst_method_hash_list
, METHOD_SEL_NAME (method
))))
5753 /* Install on a global chain. */
5754 hash_enter (nst_method_hash_list
, method
);
5758 /* Check types; if different, add to a list. */
5759 if (!comp_proto_with_proto (method
, hsh
->key
))
5760 hash_add_attr (hsh
, method
);
5769 /* Put interfaces on list in reverse order. */
5770 TREE_CHAIN (class) = interface_chain
;
5771 interface_chain
= class;
5772 return interface_chain
;
5776 add_category (class, category
)
5780 /* Put categories on list in reverse order. */
5781 tree cat
= CLASS_CATEGORY_LIST (class);
5785 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
5786 warning ("duplicate interface declaration for category `%s(%s)'",
5787 IDENTIFIER_POINTER (CLASS_NAME (class)),
5788 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category
)));
5789 cat
= CLASS_CATEGORY_LIST (cat
);
5792 CLASS_CATEGORY_LIST (category
) = CLASS_CATEGORY_LIST (class);
5793 CLASS_CATEGORY_LIST (class) = category
;
5796 /* Called after parsing each instance variable declaration. Necessary to
5797 preserve typedefs and implement public/private...
5799 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5802 add_instance_variable (class, public, declarator
, declspecs
, width
)
5809 tree field_decl
, raw_decl
;
5811 raw_decl
= build_tree_list (declspecs
, declarator
);
5813 if (CLASS_RAW_IVARS (class))
5814 chainon (CLASS_RAW_IVARS (class), raw_decl
);
5816 CLASS_RAW_IVARS (class) = raw_decl
;
5818 field_decl
= grokfield (input_filename
, lineno
,
5819 declarator
, declspecs
, width
);
5821 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5825 TREE_PUBLIC (field_decl
) = 0;
5826 TREE_PRIVATE (field_decl
) = 0;
5827 TREE_PROTECTED (field_decl
) = 1;
5831 TREE_PUBLIC (field_decl
) = 1;
5832 TREE_PRIVATE (field_decl
) = 0;
5833 TREE_PROTECTED (field_decl
) = 0;
5837 TREE_PUBLIC (field_decl
) = 0;
5838 TREE_PRIVATE (field_decl
) = 1;
5839 TREE_PROTECTED (field_decl
) = 0;
5844 if (CLASS_IVARS (class))
5845 chainon (CLASS_IVARS (class), field_decl
);
5847 CLASS_IVARS (class) = field_decl
;
5853 is_ivar (decl_chain
, ident
)
5857 for ( ; decl_chain
; decl_chain
= TREE_CHAIN (decl_chain
))
5858 if (DECL_NAME (decl_chain
) == ident
)
5863 /* True if the ivar is private and we are not in its implementation. */
5869 if (TREE_PRIVATE (decl
)
5870 && ! is_ivar (CLASS_IVARS (implementation_template
), DECL_NAME (decl
)))
5872 error ("instance variable `%s' is declared private",
5873 IDENTIFIER_POINTER (DECL_NAME (decl
)));
5880 /* We have an instance variable reference;, check to see if it is public. */
5883 is_public (expr
, identifier
)
5887 tree basetype
= TREE_TYPE (expr
);
5888 enum tree_code code
= TREE_CODE (basetype
);
5891 if (code
== RECORD_TYPE
)
5893 if (TREE_STATIC_TEMPLATE (basetype
))
5895 if (!lookup_interface (TYPE_NAME (basetype
)))
5897 error ("Cannot find interface declaration for `%s'",
5898 IDENTIFIER_POINTER (TYPE_NAME (basetype
)));
5902 if ((decl
= is_ivar (TYPE_FIELDS (basetype
), identifier
)))
5904 if (TREE_PUBLIC (decl
))
5907 /* Important difference between the Stepstone translator:
5908 all instance variables should be public within the context
5909 of the implementation. */
5910 if (implementation_context
5911 && (((TREE_CODE (implementation_context
)
5912 == CLASS_IMPLEMENTATION_TYPE
)
5913 || (TREE_CODE (implementation_context
)
5914 == CATEGORY_IMPLEMENTATION_TYPE
))
5915 && (CLASS_NAME (implementation_context
)
5916 == TYPE_NAME (basetype
))))
5917 return ! is_private (decl
);
5919 error ("instance variable `%s' is declared %s",
5920 IDENTIFIER_POINTER (identifier
),
5921 TREE_PRIVATE (decl
) ? "private" : "protected");
5926 else if (implementation_context
&& (basetype
== objc_object_reference
))
5928 TREE_TYPE (expr
) = uprivate_record
;
5929 warning ("static access to object of type `id'");
5936 /* Implement @defs (<classname>) within struct bodies. */
5939 get_class_ivars (interface
)
5942 if (!doing_objc_thang
)
5945 return build_ivar_chain (interface
, 1);
5948 /* Make sure all entries in CHAIN are also in LIST. */
5951 check_methods (chain
, list
, mtype
)
5960 if (!lookup_method (list
, chain
))
5964 if (TREE_CODE (implementation_context
)
5965 == CLASS_IMPLEMENTATION_TYPE
)
5966 warning ("incomplete implementation of class `%s'",
5967 IDENTIFIER_POINTER (CLASS_NAME (implementation_context
)));
5968 else if (TREE_CODE (implementation_context
)
5969 == CATEGORY_IMPLEMENTATION_TYPE
)
5970 warning ("incomplete implementation of category `%s'",
5971 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
5975 warning ("method definition for `%c%s' not found",
5976 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
5979 chain
= TREE_CHAIN (chain
);
5986 conforms_to_protocol (class, protocol
)
5992 tree p
= CLASS_PROTOCOL_LIST (class);
5994 while (p
&& TREE_VALUE (p
) != TREE_VALUE (protocol
))
5999 tree super
= (CLASS_SUPER_NAME (class)
6000 ? lookup_interface (CLASS_SUPER_NAME (class))
6002 int tmp
= super
? conforms_to_protocol (super
, protocol
) : 0;
6007 protocol
= TREE_CHAIN (protocol
);
6013 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
6014 CONTEXT. This is one of two mechanisms to check protocol integrity. */
6017 check_methods_accessible (chain
, context
, mtype
)
6024 tree base_context
= context
;
6028 context
= base_context
;
6032 list
= CLASS_CLS_METHODS (context
);
6034 list
= CLASS_NST_METHODS (context
);
6036 if (lookup_method (list
, chain
))
6039 else if (TREE_CODE (context
) == CLASS_IMPLEMENTATION_TYPE
6040 || TREE_CODE (context
) == CLASS_INTERFACE_TYPE
)
6041 context
= (CLASS_SUPER_NAME (context
)
6042 ? lookup_interface (CLASS_SUPER_NAME (context
))
6045 else if (TREE_CODE (context
) == CATEGORY_IMPLEMENTATION_TYPE
6046 || TREE_CODE (context
) == CATEGORY_INTERFACE_TYPE
)
6047 context
= (CLASS_NAME (context
)
6048 ? lookup_interface (CLASS_NAME (context
))
6054 if (context
== NULL_TREE
)
6058 if (TREE_CODE (implementation_context
)
6059 == CLASS_IMPLEMENTATION_TYPE
)
6060 warning ("incomplete implementation of class `%s'",
6062 (CLASS_NAME (implementation_context
)));
6063 else if (TREE_CODE (implementation_context
)
6064 == CATEGORY_IMPLEMENTATION_TYPE
)
6065 warning ("incomplete implementation of category `%s'",
6067 (CLASS_SUPER_NAME (implementation_context
)));
6070 warning ("method definition for `%c%s' not found",
6071 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
6074 chain
= TREE_CHAIN (chain
); /* next method... */
6080 check_protocols (proto_list
, type
, name
)
6085 for ( ; proto_list
; proto_list
= TREE_CHAIN (proto_list
))
6087 tree p
= TREE_VALUE (proto_list
);
6089 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
6093 /* Ensure that all protocols have bodies. */
6094 if (flag_warn_protocol
) {
6095 f1
= check_methods (PROTOCOL_CLS_METHODS (p
),
6096 CLASS_CLS_METHODS (implementation_context
),
6098 f2
= check_methods (PROTOCOL_NST_METHODS (p
),
6099 CLASS_NST_METHODS (implementation_context
),
6102 f1
= check_methods_accessible (PROTOCOL_CLS_METHODS (p
),
6103 implementation_context
,
6105 f2
= check_methods_accessible (PROTOCOL_NST_METHODS (p
),
6106 implementation_context
,
6111 warning ("%s `%s' does not fully implement the `%s' protocol",
6112 type
, name
, IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
6117 ; /* An identifier if we could not find a protocol. */
6120 /* Check protocols recursively. */
6121 if (PROTOCOL_LIST (p
))
6124 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
6125 if (! conforms_to_protocol (super_class
, PROTOCOL_LIST (p
)))
6126 check_protocols (PROTOCOL_LIST (p
), type
, name
);
6131 /* Make sure that the class CLASS_NAME is defined
6132 CODE says which kind of thing CLASS_NAME ought to be.
6133 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6134 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE.
6136 If CODE is CLASS_INTERFACE_TYPE, we also do a push_obstacks_nochange
6137 whose matching pop is in continue_class. */
6140 start_class (code
, class_name
, super_name
, protocol_list
)
6141 enum tree_code code
;
6148 if (code
== CLASS_INTERFACE_TYPE
)
6150 push_obstacks_nochange ();
6151 end_temporary_allocation ();
6154 if (!doing_objc_thang
)
6157 class = make_node (code
);
6158 TYPE_BINFO (class) = make_tree_vec (5);
6160 CLASS_NAME (class) = class_name
;
6161 CLASS_SUPER_NAME (class) = super_name
;
6162 CLASS_CLS_METHODS (class) = NULL_TREE
;
6164 if (! is_class_name (class_name
) && (decl
= lookup_name (class_name
)))
6166 error ("`%s' redeclared as different kind of symbol",
6167 IDENTIFIER_POINTER (class_name
));
6168 error_with_decl (decl
, "previous declaration of `%s'");
6171 if (code
== CLASS_IMPLEMENTATION_TYPE
)
6174 static tree implemented_classes
= 0;
6175 tree chain
= implemented_classes
;
6176 for (chain
= implemented_classes
; chain
; chain
= TREE_CHAIN (chain
))
6177 if (TREE_VALUE (chain
) == class_name
)
6179 error ("reimplementation of class `%s'",
6180 IDENTIFIER_POINTER (class_name
));
6181 return error_mark_node
;
6183 implemented_classes
= perm_tree_cons (NULL_TREE
, class_name
,
6184 implemented_classes
);
6187 /* Pre-build the following entities - for speed/convenience. */
6189 self_id
= get_identifier ("self");
6191 ucmd_id
= get_identifier ("_cmd");
6194 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6195 if (!objc_super_template
)
6196 objc_super_template
= build_super_template ();
6198 /* Reset for multiple classes per file. */
6201 implementation_context
= class;
6203 /* Lookup the interface for this implementation. */
6205 if (!(implementation_template
= lookup_interface (class_name
)))
6207 warning ("Cannot find interface declaration for `%s'",
6208 IDENTIFIER_POINTER (class_name
));
6209 add_class (implementation_template
= implementation_context
);
6212 /* If a super class has been specified in the implementation,
6213 insure it conforms to the one specified in the interface. */
6216 && (super_name
!= CLASS_SUPER_NAME (implementation_template
)))
6218 tree previous_name
= CLASS_SUPER_NAME (implementation_template
);
6219 char *name
= previous_name
? IDENTIFIER_POINTER (previous_name
) : "";
6220 error ("conflicting super class name `%s'",
6221 IDENTIFIER_POINTER (super_name
));
6222 error ("previous declaration of `%s'", name
);
6225 else if (! super_name
)
6227 CLASS_SUPER_NAME (implementation_context
)
6228 = CLASS_SUPER_NAME (implementation_template
);
6232 else if (code
== CLASS_INTERFACE_TYPE
)
6234 if (lookup_interface (class_name
))
6235 warning ("duplicate interface declaration for class `%s'",
6236 IDENTIFIER_POINTER (class_name
));
6241 CLASS_PROTOCOL_LIST (class)
6242 = lookup_and_install_protocols (protocol_list
);
6245 else if (code
== CATEGORY_INTERFACE_TYPE
)
6247 tree class_category_is_assoc_with
;
6249 /* For a category, class_name is really the name of the class that
6250 the following set of methods will be associated with. We must
6251 find the interface so that can derive the objects template. */
6253 if (!(class_category_is_assoc_with
= lookup_interface (class_name
)))
6255 error ("Cannot find interface declaration for `%s'",
6256 IDENTIFIER_POINTER (class_name
));
6257 exit (FATAL_EXIT_CODE
);
6260 add_category (class_category_is_assoc_with
, class);
6263 CLASS_PROTOCOL_LIST (class)
6264 = lookup_and_install_protocols (protocol_list
);
6267 else if (code
== CATEGORY_IMPLEMENTATION_TYPE
)
6269 /* Pre-build the following entities for speed/convenience. */
6271 self_id
= get_identifier ("self");
6273 ucmd_id
= get_identifier ("_cmd");
6276 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6277 if (!objc_super_template
)
6278 objc_super_template
= build_super_template ();
6280 /* Reset for multiple classes per file. */
6283 implementation_context
= class;
6285 /* For a category, class_name is really the name of the class that
6286 the following set of methods will be associated with. We must
6287 find the interface so that can derive the objects template. */
6289 if (!(implementation_template
= lookup_interface (class_name
)))
6291 error ("Cannot find interface declaration for `%s'",
6292 IDENTIFIER_POINTER (class_name
));
6293 exit (FATAL_EXIT_CODE
);
6300 continue_class (class)
6303 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6304 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6306 struct imp_entry
*imp_entry
;
6309 /* Check consistency of the instance variables. */
6311 if (CLASS_IVARS (class))
6312 check_ivars (implementation_template
, class);
6314 /* code generation */
6316 ivar_context
= build_private_template (implementation_template
);
6318 if (!objc_class_template
)
6319 build_class_template ();
6322 = (struct imp_entry
*) xmalloc (sizeof (struct imp_entry
))))
6323 perror ("unable to allocate in objc-tree.c");
6325 imp_entry
->next
= imp_list
;
6326 imp_entry
->imp_context
= class;
6327 imp_entry
->imp_template
= implementation_template
;
6329 synth_forward_declarations ();
6330 imp_entry
->class_decl
= UOBJC_CLASS_decl
;
6331 imp_entry
->meta_decl
= UOBJC_METACLASS_decl
;
6333 /* Append to front and increment count. */
6334 imp_list
= imp_entry
;
6335 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6340 return ivar_context
;
6343 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6345 tree record
= xref_tag (RECORD_TYPE
, CLASS_NAME (class));
6347 if (!TYPE_FIELDS (record
))
6349 finish_struct (record
, build_ivar_chain (class, 0), NULL_TREE
);
6350 CLASS_STATIC_TEMPLATE (class) = record
;
6352 /* Mark this record as a class template for static typing. */
6353 TREE_STATIC_TEMPLATE (record
) = 1;
6360 return error_mark_node
;
6363 /* This is called once we see the "@end" in an interface/implementation. */
6366 finish_class (class)
6369 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6371 /* All code generation is done in finish_objc. */
6373 if (implementation_template
!= implementation_context
)
6375 /* Ensure that all method listed in the interface contain bodies. */
6376 check_methods (CLASS_CLS_METHODS (implementation_template
),
6377 CLASS_CLS_METHODS (implementation_context
), '+');
6378 check_methods (CLASS_NST_METHODS (implementation_template
),
6379 CLASS_NST_METHODS (implementation_context
), '-');
6381 if (CLASS_PROTOCOL_LIST (implementation_template
))
6382 check_protocols (CLASS_PROTOCOL_LIST (implementation_template
),
6384 IDENTIFIER_POINTER (CLASS_NAME (implementation_context
)));
6388 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6390 tree category
= CLASS_CATEGORY_LIST (implementation_template
);
6392 /* Find the category interface from the class it is associated with. */
6395 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category
))
6397 category
= CLASS_CATEGORY_LIST (category
);
6402 /* Ensure all method listed in the interface contain bodies. */
6403 check_methods (CLASS_CLS_METHODS (category
),
6404 CLASS_CLS_METHODS (implementation_context
), '+');
6405 check_methods (CLASS_NST_METHODS (category
),
6406 CLASS_NST_METHODS (implementation_context
), '-');
6408 if (CLASS_PROTOCOL_LIST (category
))
6409 check_protocols (CLASS_PROTOCOL_LIST (category
),
6411 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
6415 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6418 char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (class));
6419 char *string
= (char *) alloca (strlen (class_name
) + 3);
6421 /* extern struct objc_object *_<my_name>; */
6423 sprintf (string
, "_%s", class_name
);
6425 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
6426 decl_specs
= tree_cons (NULL_TREE
, objc_object_reference
, decl_specs
);
6427 define_decl (build1 (INDIRECT_REF
, NULL_TREE
, get_identifier (string
)),
6433 add_protocol (protocol
)
6436 /* Put protocol on list in reverse order. */
6437 TREE_CHAIN (protocol
) = protocol_chain
;
6438 protocol_chain
= protocol
;
6439 return protocol_chain
;
6443 lookup_protocol (ident
)
6448 for (chain
= protocol_chain
; chain
; chain
= TREE_CHAIN (chain
))
6450 if (ident
== PROTOCOL_NAME (chain
))
6458 start_protocol (code
, name
, list
)
6459 enum tree_code code
;
6465 if (!doing_objc_thang
)
6468 /* This is as good a place as any. Need to invoke push_tag_toplevel. */
6469 if (!objc_protocol_template
)
6470 objc_protocol_template
= build_protocol_template ();
6472 protocol
= make_node (code
);
6473 TYPE_BINFO (protocol
) = make_tree_vec (2);
6475 PROTOCOL_NAME (protocol
) = name
;
6476 PROTOCOL_LIST (protocol
) = list
;
6478 lookup_and_install_protocols (list
);
6480 if (lookup_protocol (name
))
6481 warning ("duplicate declaration for protocol `%s'",
6482 IDENTIFIER_POINTER (name
));
6484 add_protocol (protocol
);
6486 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6492 finish_protocol (protocol
)
6493 tree protocol ATTRIBUTE_UNUSED
;
6498 /* "Encode" a data type into a string, which grows in util_obstack.
6499 ??? What is the FORMAT? Someone please document this! */
6502 encode_type_qualifiers (declspecs
)
6507 for (spec
= declspecs
; spec
; spec
= TREE_CHAIN (spec
))
6509 if (ridpointers
[(int) RID_CONST
] == TREE_VALUE (spec
))
6510 obstack_1grow (&util_obstack
, 'r');
6511 else if (ridpointers
[(int) RID_IN
] == TREE_VALUE (spec
))
6512 obstack_1grow (&util_obstack
, 'n');
6513 else if (ridpointers
[(int) RID_INOUT
] == TREE_VALUE (spec
))
6514 obstack_1grow (&util_obstack
, 'N');
6515 else if (ridpointers
[(int) RID_OUT
] == TREE_VALUE (spec
))
6516 obstack_1grow (&util_obstack
, 'o');
6517 else if (ridpointers
[(int) RID_BYCOPY
] == TREE_VALUE (spec
))
6518 obstack_1grow (&util_obstack
, 'O');
6519 else if (ridpointers
[(int) RID_BYREF
] == TREE_VALUE (spec
))
6520 obstack_1grow (&util_obstack
, 'R');
6521 else if (ridpointers
[(int) RID_ONEWAY
] == TREE_VALUE (spec
))
6522 obstack_1grow (&util_obstack
, 'V');
6526 /* Encode a pointer type. */
6529 encode_pointer (type
, curtype
, format
)
6534 tree pointer_to
= TREE_TYPE (type
);
6536 if (TREE_CODE (pointer_to
) == RECORD_TYPE
)
6538 if (TYPE_NAME (pointer_to
)
6539 && TREE_CODE (TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
)
6541 char *name
= IDENTIFIER_POINTER (TYPE_NAME (pointer_to
));
6543 if (strcmp (name
, TAG_OBJECT
) == 0) /* '@' */
6545 obstack_1grow (&util_obstack
, '@');
6548 else if (TREE_STATIC_TEMPLATE (pointer_to
))
6550 if (generating_instance_variables
)
6552 obstack_1grow (&util_obstack
, '@');
6553 obstack_1grow (&util_obstack
, '"');
6554 obstack_grow (&util_obstack
, name
, strlen (name
));
6555 obstack_1grow (&util_obstack
, '"');
6560 obstack_1grow (&util_obstack
, '@');
6564 else if (strcmp (name
, TAG_CLASS
) == 0) /* '#' */
6566 obstack_1grow (&util_obstack
, '#');
6569 #ifndef OBJC_INT_SELECTORS
6570 else if (strcmp (name
, TAG_SELECTOR
) == 0) /* ':' */
6572 obstack_1grow (&util_obstack
, ':');
6575 #endif /* OBJC_INT_SELECTORS */
6578 else if (TREE_CODE (pointer_to
) == INTEGER_TYPE
6579 && TYPE_MODE (pointer_to
) == QImode
)
6581 obstack_1grow (&util_obstack
, '*');
6585 /* We have a type that does not get special treatment. */
6587 /* NeXT extension */
6588 obstack_1grow (&util_obstack
, '^');
6589 encode_type (pointer_to
, curtype
, format
);
6593 encode_array (type
, curtype
, format
)
6598 tree an_int_cst
= TYPE_SIZE (type
);
6599 tree array_of
= TREE_TYPE (type
);
6602 /* An incomplete array is treated like a pointer. */
6603 if (an_int_cst
== NULL
)
6605 encode_pointer (type
, curtype
, format
);
6609 sprintf (buffer
, "[%ld",
6610 (long) (TREE_INT_CST_LOW (an_int_cst
)
6611 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
6613 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6614 encode_type (array_of
, curtype
, format
);
6615 obstack_1grow (&util_obstack
, ']');
6620 encode_aggregate_within (type
, curtype
, format
, left
, right
)
6627 if (obstack_object_size (&util_obstack
) > 0
6628 && *(obstack_next_free (&util_obstack
) - 1) == '^')
6630 tree name
= TYPE_NAME (type
);
6632 /* we have a reference; this is a NeXT extension. */
6634 if (obstack_object_size (&util_obstack
) - curtype
== 1
6635 && format
== OBJC_ENCODE_INLINE_DEFS
)
6637 /* Output format of struct for first level only. */
6638 tree fields
= TYPE_FIELDS (type
);
6640 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6642 obstack_1grow (&util_obstack
, left
);
6643 obstack_grow (&util_obstack
,
6644 IDENTIFIER_POINTER (name
),
6645 strlen (IDENTIFIER_POINTER (name
)));
6646 obstack_1grow (&util_obstack
, '=');
6650 obstack_1grow (&util_obstack
, left
);
6651 obstack_grow (&util_obstack
, "?=", 2);
6654 for ( ; fields
; fields
= TREE_CHAIN (fields
))
6655 encode_field_decl (fields
, curtype
, format
);
6657 obstack_1grow (&util_obstack
, right
);
6660 else if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6662 obstack_1grow (&util_obstack
, left
);
6663 obstack_grow (&util_obstack
,
6664 IDENTIFIER_POINTER (name
),
6665 strlen (IDENTIFIER_POINTER (name
)));
6666 obstack_1grow (&util_obstack
, right
);
6671 /* We have an untagged structure or a typedef. */
6672 obstack_1grow (&util_obstack
, left
);
6673 obstack_1grow (&util_obstack
, '?');
6674 obstack_1grow (&util_obstack
, right
);
6680 tree name
= TYPE_NAME (type
);
6681 tree fields
= TYPE_FIELDS (type
);
6683 if (format
== OBJC_ENCODE_INLINE_DEFS
6684 || generating_instance_variables
)
6686 obstack_1grow (&util_obstack
, left
);
6687 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6688 obstack_grow (&util_obstack
,
6689 IDENTIFIER_POINTER (name
),
6690 strlen (IDENTIFIER_POINTER (name
)));
6692 obstack_1grow (&util_obstack
, '?');
6694 obstack_1grow (&util_obstack
, '=');
6696 for (; fields
; fields
= TREE_CHAIN (fields
))
6698 if (generating_instance_variables
)
6700 tree fname
= DECL_NAME (fields
);
6702 obstack_1grow (&util_obstack
, '"');
6703 if (fname
&& TREE_CODE (fname
) == IDENTIFIER_NODE
)
6705 obstack_grow (&util_obstack
,
6706 IDENTIFIER_POINTER (fname
),
6707 strlen (IDENTIFIER_POINTER (fname
)));
6710 obstack_1grow (&util_obstack
, '"');
6713 encode_field_decl (fields
, curtype
, format
);
6716 obstack_1grow (&util_obstack
, right
);
6721 obstack_1grow (&util_obstack
, left
);
6722 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6723 obstack_grow (&util_obstack
,
6724 IDENTIFIER_POINTER (name
),
6725 strlen (IDENTIFIER_POINTER (name
)));
6727 /* We have an untagged structure or a typedef. */
6728 obstack_1grow (&util_obstack
, '?');
6730 obstack_1grow (&util_obstack
, right
);
6736 encode_aggregate (type
, curtype
, format
)
6741 enum tree_code code
= TREE_CODE (type
);
6747 encode_aggregate_within(type
, curtype
, format
, '{', '}');
6752 encode_aggregate_within(type
, curtype
, format
, '(', ')');
6757 obstack_1grow (&util_obstack
, 'i');
6765 /* Support bitfields. The current version of Objective-C does not support
6766 them. The string will consist of one or more "b:n"'s where n is an
6767 integer describing the width of the bitfield. Currently, classes in
6768 the kit implement a method "-(char *)describeBitfieldStruct:" that
6769 simulates this. If they do not implement this method, the archiver
6770 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6771 according to the GNU compiler. After looking at the "kit", it appears
6772 that all classes currently rely on this default behavior, rather than
6773 hand generating this string (which is tedious). */
6776 encode_bitfield (width
, format
)
6781 sprintf (buffer
, "b%d", width
);
6782 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6785 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6788 encode_type (type
, curtype
, format
)
6793 enum tree_code code
= TREE_CODE (type
);
6795 if (code
== INTEGER_TYPE
)
6797 if (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type
)) == 0
6798 && TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type
)) == 0)
6800 /* Unsigned integer types. */
6802 if (TYPE_MODE (type
) == QImode
)
6803 obstack_1grow (&util_obstack
, 'C');
6804 else if (TYPE_MODE (type
) == HImode
)
6805 obstack_1grow (&util_obstack
, 'S');
6806 else if (TYPE_MODE (type
) == SImode
)
6808 if (type
== long_unsigned_type_node
)
6809 obstack_1grow (&util_obstack
, 'L');
6811 obstack_1grow (&util_obstack
, 'I');
6813 else if (TYPE_MODE (type
) == DImode
)
6814 obstack_1grow (&util_obstack
, 'Q');
6818 /* Signed integer types. */
6820 if (TYPE_MODE (type
) == QImode
)
6821 obstack_1grow (&util_obstack
, 'c');
6822 else if (TYPE_MODE (type
) == HImode
)
6823 obstack_1grow (&util_obstack
, 's');
6824 else if (TYPE_MODE (type
) == SImode
)
6826 if (type
== long_integer_type_node
)
6827 obstack_1grow (&util_obstack
, 'l');
6829 obstack_1grow (&util_obstack
, 'i');
6832 else if (TYPE_MODE (type
) == DImode
)
6833 obstack_1grow (&util_obstack
, 'q');
6837 else if (code
== REAL_TYPE
)
6839 /* Floating point types. */
6841 if (TYPE_MODE (type
) == SFmode
)
6842 obstack_1grow (&util_obstack
, 'f');
6843 else if (TYPE_MODE (type
) == DFmode
6844 || TYPE_MODE (type
) == TFmode
)
6845 obstack_1grow (&util_obstack
, 'd');
6848 else if (code
== VOID_TYPE
)
6849 obstack_1grow (&util_obstack
, 'v');
6851 else if (code
== ARRAY_TYPE
)
6852 encode_array (type
, curtype
, format
);
6854 else if (code
== POINTER_TYPE
)
6855 encode_pointer (type
, curtype
, format
);
6857 else if (code
== RECORD_TYPE
|| code
== UNION_TYPE
|| code
== ENUMERAL_TYPE
)
6858 encode_aggregate (type
, curtype
, format
);
6860 else if (code
== FUNCTION_TYPE
) /* '?' */
6861 obstack_1grow (&util_obstack
, '?');
6865 encode_complete_bitfield (int position
, tree type
, int size
)
6867 enum tree_code code
= TREE_CODE (type
);
6869 char charType
= '?';
6871 if (code
== INTEGER_TYPE
)
6873 if (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type
)) == 0
6874 && TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type
)) == 0)
6876 /* Unsigned integer types. */
6878 if (TYPE_MODE (type
) == QImode
)
6880 else if (TYPE_MODE (type
) == HImode
)
6882 else if (TYPE_MODE (type
) == SImode
)
6884 if (type
== long_unsigned_type_node
)
6889 else if (TYPE_MODE (type
) == DImode
)
6894 /* Signed integer types. */
6896 if (TYPE_MODE (type
) == QImode
)
6898 else if (TYPE_MODE (type
) == HImode
)
6900 else if (TYPE_MODE (type
) == SImode
)
6902 if (type
== long_integer_type_node
)
6908 else if (TYPE_MODE (type
) == DImode
)
6916 sprintf (buffer
, "b%d%c%d", position
, charType
, size
);
6917 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6921 encode_field_decl (field_decl
, curtype
, format
)
6928 type
= TREE_TYPE (field_decl
);
6930 /* If this field is obviously a bitfield, or is a bitfield that has been
6931 clobbered to look like a ordinary integer mode, go ahead and generate
6932 the bitfield typing information. */
6933 if (flag_next_runtime
)
6935 if (DECL_BIT_FIELD (field_decl
))
6936 encode_bitfield (DECL_FIELD_SIZE (field_decl
), format
);
6937 else if (TREE_CODE (TYPE_SIZE (type
)) == INTEGER_CST
6938 && DECL_FIELD_SIZE (field_decl
)
6939 && TYPE_MODE (type
) > DECL_MODE (field_decl
))
6940 encode_bitfield (DECL_FIELD_SIZE (field_decl
), format
);
6942 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6946 if (DECL_BIT_FIELD (field_decl
)
6947 || (TREE_CODE (TYPE_SIZE (type
)) == INTEGER_CST
6948 && DECL_FIELD_SIZE (field_decl
)
6949 && TYPE_MODE (type
) > DECL_MODE (field_decl
)))
6951 encode_complete_bitfield (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl
)),
6952 DECL_BIT_FIELD_TYPE (field_decl
),
6953 DECL_FIELD_SIZE (field_decl
));
6956 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6961 expr_last (complex_expr
)
6967 while ((next
= TREE_OPERAND (complex_expr
, 0)))
6968 complex_expr
= next
;
6970 return complex_expr
;
6973 /* The selector of the current method,
6974 or NULL if we aren't compiling a method. */
6977 maybe_objc_method_name (decl
)
6981 return METHOD_SEL_NAME (method_context
);
6986 /* Transform a method definition into a function definition as follows:
6987 - synthesize the first two arguments, "self" and "_cmd". */
6990 start_method_def (method
)
6995 /* Required to implement _msgSuper. */
6996 method_context
= method
;
6997 UOBJC_SUPER_decl
= NULL_TREE
;
6999 /* Must be called BEFORE start_function. */
7002 /* Generate prototype declarations for arguments..."new-style". */
7004 if (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
)
7005 decl_specs
= build_tree_list (NULL_TREE
, uprivate_record
);
7007 /* Really a `struct objc_class *'. However, we allow people to
7008 assign to self, which changes its type midstream. */
7009 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
7011 push_parm_decl (build_tree_list
7012 (build_tree_list (decl_specs
,
7013 build1 (INDIRECT_REF
, NULL_TREE
, self_id
)),
7014 build_tree_list (unused_list
, NULL_TREE
)));
7016 #ifdef OBJC_INT_SELECTORS
7017 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_UNSIGNED
]);
7018 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_INT
], decl_specs
);
7019 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, ucmd_id
),
7020 build_tree_list (unused_list
, NULL_TREE
)));
7021 #else /* not OBJC_INT_SELECTORS */
7022 decl_specs
= build_tree_list (NULL_TREE
,
7023 xref_tag (RECORD_TYPE
,
7024 get_identifier (TAG_SELECTOR
)));
7025 push_parm_decl (build_tree_list
7026 (build_tree_list (decl_specs
,
7027 build1 (INDIRECT_REF
, NULL_TREE
, ucmd_id
)),
7028 build_tree_list (unused_list
, NULL_TREE
)));
7029 #endif /* not OBJC_INT_SELECTORS */
7031 /* Generate argument declarations if a keyword_decl. */
7032 if (METHOD_SEL_ARGS (method
))
7034 tree arglist
= METHOD_SEL_ARGS (method
);
7037 tree arg_spec
= TREE_PURPOSE (TREE_TYPE (arglist
));
7038 tree arg_decl
= TREE_VALUE (TREE_TYPE (arglist
));
7042 tree last_expr
= expr_last (arg_decl
);
7044 /* Unite the abstract decl with its name. */
7045 TREE_OPERAND (last_expr
, 0) = KEYWORD_ARG_NAME (arglist
);
7046 push_parm_decl (build_tree_list
7047 (build_tree_list (arg_spec
, arg_decl
),
7048 build_tree_list (NULL_TREE
, NULL_TREE
)));
7050 /* Unhook: restore the abstract declarator. */
7051 TREE_OPERAND (last_expr
, 0) = NULL_TREE
;
7055 push_parm_decl (build_tree_list
7056 (build_tree_list (arg_spec
,
7057 KEYWORD_ARG_NAME (arglist
)),
7058 build_tree_list (NULL_TREE
, NULL_TREE
)));
7060 arglist
= TREE_CHAIN (arglist
);
7065 if (METHOD_ADD_ARGS (method
) > (tree
)1)
7067 /* We have a variable length selector - in "prototype" format. */
7068 tree akey
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
7071 /* This must be done prior to calling pushdecl. pushdecl is
7072 going to change our chain on us. */
7073 tree nextkey
= TREE_CHAIN (akey
);
7081 warn_with_method (message
, mtype
, method
)
7086 if (count_error (1) == 0)
7089 report_error_function (DECL_SOURCE_FILE (method
));
7091 fprintf (stderr
, "%s:%d: warning: ",
7092 DECL_SOURCE_FILE (method
), DECL_SOURCE_LINE (method
));
7093 bzero (errbuf
, BUFSIZE
);
7094 fprintf (stderr
, "%s `%c%s'\n",
7095 message
, mtype
, gen_method_decl (method
, errbuf
));
7098 /* Return 1 if METHOD is consistent with PROTO. */
7101 comp_method_with_proto (method
, proto
)
7104 static tree function_type
= 0;
7106 /* Create a function_type node once. */
7109 push_obstacks_nochange ();
7110 end_temporary_allocation ();
7111 function_type
= make_node (FUNCTION_TYPE
);
7115 /* Install argument types - normally set by build_function_type. */
7116 TYPE_ARG_TYPES (function_type
) = get_arg_type_list (proto
, METHOD_DEF
, 0);
7118 /* install return type */
7119 TREE_TYPE (function_type
) = groktypename (TREE_TYPE (proto
));
7121 return comptypes (TREE_TYPE (METHOD_DEFINITION (method
)), function_type
);
7124 /* Return 1 if PROTO1 is consistent with PROTO2. */
7127 comp_proto_with_proto (proto1
, proto2
)
7128 tree proto1
, proto2
;
7130 static tree function_type1
= 0, function_type2
= 0;
7132 /* Create a couple function_type node's once. */
7133 if (!function_type1
)
7135 push_obstacks_nochange ();
7136 end_temporary_allocation ();
7137 function_type1
= make_node (FUNCTION_TYPE
);
7138 function_type2
= make_node (FUNCTION_TYPE
);
7142 /* Install argument types; normally set by build_function_type. */
7143 TYPE_ARG_TYPES (function_type1
) = get_arg_type_list (proto1
, METHOD_REF
, 0);
7144 TYPE_ARG_TYPES (function_type2
) = get_arg_type_list (proto2
, METHOD_REF
, 0);
7146 /* Install return type. */
7147 TREE_TYPE (function_type1
) = groktypename (TREE_TYPE (proto1
));
7148 TREE_TYPE (function_type2
) = groktypename (TREE_TYPE (proto2
));
7150 return comptypes (function_type1
, function_type2
);
7153 /* - Generate an identifier for the function. the format is "_n_cls",
7154 where 1 <= n <= nMethods, and cls is the name the implementation we
7156 - Install the return type from the method declaration.
7157 - If we have a prototype, check for type consistency. */
7160 really_start_method (method
, parmlist
)
7161 tree method
, parmlist
;
7163 tree sc_spec
, ret_spec
, ret_decl
, decl_specs
;
7164 tree method_decl
, method_id
;
7165 char *buf
, *sel_name
, *class_name
, *cat_name
;
7167 /* Synth the storage class & assemble the return type. */
7168 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
7169 ret_spec
= TREE_PURPOSE (TREE_TYPE (method
));
7170 decl_specs
= chainon (sc_spec
, ret_spec
);
7172 sel_name
= IDENTIFIER_POINTER (METHOD_SEL_NAME (method
));
7173 class_name
= IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
7174 cat_name
= ((TREE_CODE (implementation_context
)
7175 == CLASS_IMPLEMENTATION_TYPE
)
7177 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
7180 /* Make sure this is big enough for any plausible method label. */
7181 buf
= (char *) alloca (50 + strlen (sel_name
) + strlen (class_name
)
7182 + (cat_name
? strlen (cat_name
) : 0));
7184 OBJC_GEN_METHOD_LABEL (buf
, TREE_CODE (method
) == INSTANCE_METHOD_DECL
,
7185 class_name
, cat_name
, sel_name
, method_slot
);
7187 method_id
= get_identifier (buf
);
7189 method_decl
= build_nt (CALL_EXPR
, method_id
, parmlist
, NULL_TREE
);
7191 /* Check the declarator portion of the return type for the method. */
7192 if ((ret_decl
= TREE_VALUE (TREE_TYPE (method
))))
7194 /* Unite the complex decl (specified in the abstract decl) with the
7195 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7196 tree save_expr
= expr_last (ret_decl
);
7198 TREE_OPERAND (save_expr
, 0) = method_decl
;
7199 method_decl
= ret_decl
;
7201 /* Fool the parser into thinking it is starting a function. */
7202 start_function (decl_specs
, method_decl
, NULL_TREE
, NULL_TREE
, 0);
7204 /* Unhook: this has the effect of restoring the abstract declarator. */
7205 TREE_OPERAND (save_expr
, 0) = NULL_TREE
;
7210 TREE_VALUE (TREE_TYPE (method
)) = method_decl
;
7212 /* Fool the parser into thinking it is starting a function. */
7213 start_function (decl_specs
, method_decl
, NULL_TREE
, NULL_TREE
, 0);
7215 /* Unhook: this has the effect of restoring the abstract declarator. */
7216 TREE_VALUE (TREE_TYPE (method
)) = NULL_TREE
;
7219 METHOD_DEFINITION (method
) = current_function_decl
;
7221 if (implementation_template
!= implementation_context
)
7225 if (TREE_CODE (method
) == INSTANCE_METHOD_DECL
)
7226 proto
= lookup_instance_method_static (implementation_template
,
7227 METHOD_SEL_NAME (method
));
7229 proto
= lookup_class_method_static (implementation_template
,
7230 METHOD_SEL_NAME (method
));
7232 if (proto
&& ! comp_method_with_proto (method
, proto
))
7234 char type
= (TREE_CODE (method
) == INSTANCE_METHOD_DECL
? '-' : '+');
7236 warn_with_method ("conflicting types for", type
, method
);
7237 warn_with_method ("previous declaration of", type
, proto
);
7242 /* The following routine is always called...this "architecture" is to
7243 accommodate "old-style" variable length selectors.
7245 - a:a b:b // prototype ; id c; id d; // old-style. */
7248 continue_method_def ()
7252 if (METHOD_ADD_ARGS (method_context
) == (tree
)1)
7253 /* We have a `, ...' immediately following the selector. */
7254 parmlist
= get_parm_info (0);
7256 parmlist
= get_parm_info (1); /* place a `void_at_end' */
7258 /* Set self_decl from the first argument...this global is used by
7259 build_ivar_reference calling build_indirect_ref. */
7260 self_decl
= TREE_PURPOSE (parmlist
);
7263 really_start_method (method_context
, parmlist
);
7264 store_parm_decls ();
7267 /* Called by the parser, from the `pushlevel' production. */
7272 if (!UOBJC_SUPER_decl
)
7274 UOBJC_SUPER_decl
= start_decl (get_identifier (UTAG_SUPER
),
7275 build_tree_list (NULL_TREE
,
7276 objc_super_template
),
7277 0, NULL_TREE
, NULL_TREE
);
7279 finish_decl (UOBJC_SUPER_decl
, NULL_TREE
, NULL_TREE
);
7281 /* This prevents `unused variable' warnings when compiling with -Wall. */
7282 TREE_USED (UOBJC_SUPER_decl
) = 1;
7283 DECL_ARTIFICIAL (UOBJC_SUPER_decl
) = 1;
7287 /* _n_Method (id self, SEL sel, ...)
7289 struct objc_super _S;
7290 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7294 get_super_receiver ()
7298 tree super_expr
, super_expr_list
;
7300 /* Set receiver to self. */
7301 super_expr
= build_component_ref (UOBJC_SUPER_decl
, self_id
);
7302 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, self_decl
);
7303 super_expr_list
= build_tree_list (NULL_TREE
, super_expr
);
7305 /* Set class to begin searching. */
7306 super_expr
= build_component_ref (UOBJC_SUPER_decl
,
7307 get_identifier ("class"));
7309 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
7311 /* [_cls, __cls]Super are "pre-built" in
7312 synth_forward_declarations. */
7314 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
,
7315 ((TREE_CODE (method_context
)
7316 == INSTANCE_METHOD_DECL
)
7318 : uucls_super_ref
));
7322 /* We have a category. */
7324 tree super_name
= CLASS_SUPER_NAME (implementation_template
);
7329 error ("no super class declared in interface for `%s'",
7330 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
7331 return error_mark_node
;
7334 if (flag_next_runtime
)
7336 super_class
= get_class_reference (super_name
);
7337 if (TREE_CODE (method_context
) == CLASS_METHOD_DECL
)
7339 = build_component_ref (build_indirect_ref (super_class
, "->"),
7340 get_identifier ("isa"));
7344 add_class_reference (super_name
);
7345 super_class
= (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
7346 ? objc_get_class_decl
: objc_get_meta_class_decl
);
7347 assemble_external (super_class
);
7349 = build_function_call
7353 my_build_string (IDENTIFIER_LENGTH (super_name
) + 1,
7354 IDENTIFIER_POINTER (super_name
))));
7357 TREE_TYPE (super_class
) = TREE_TYPE (ucls_super_ref
);
7358 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, super_class
);
7361 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7363 super_expr
= build_unary_op (ADDR_EXPR
, UOBJC_SUPER_decl
, 0);
7364 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7366 return build_compound_expr (super_expr_list
);
7370 error ("[super ...] must appear in a method context");
7371 return error_mark_node
;
7376 encode_method_def (func_decl
)
7381 int max_parm_end
= 0;
7386 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
7387 obstack_object_size (&util_obstack
),
7388 OBJC_ENCODE_INLINE_DEFS
);
7391 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7392 parms
= TREE_CHAIN (parms
))
7394 int parm_end
= (forwarding_offset (parms
)
7395 + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms
)))
7398 if (!offset_is_register
&& parm_end
> max_parm_end
)
7399 max_parm_end
= parm_end
;
7402 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
7404 sprintf (buffer
, "%d", stack_size
);
7405 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7407 /* Argument types. */
7408 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7409 parms
= TREE_CHAIN (parms
))
7412 encode_type (TREE_TYPE (parms
),
7413 obstack_object_size (&util_obstack
),
7414 OBJC_ENCODE_INLINE_DEFS
);
7416 /* Compute offset. */
7417 sprintf (buffer
, "%d", forwarding_offset (parms
));
7419 /* Indicate register. */
7420 if (offset_is_register
)
7421 obstack_1grow (&util_obstack
, '+');
7423 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7426 obstack_1grow (&util_obstack
, 0);
7427 result
= get_identifier (obstack_finish (&util_obstack
));
7428 obstack_free (&util_obstack
, util_firstobj
);
7433 finish_method_def ()
7435 METHOD_ENCODING (method_context
) = encode_method_def (current_function_decl
);
7437 finish_function (0);
7439 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7440 since the optimizer may find "may be used before set" errors. */
7441 method_context
= NULL_TREE
;
7446 lang_report_error_function (decl
)
7451 fprintf (stderr
, "In method `%s'\n",
7452 IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context
)));
7462 is_complex_decl (type
)
7465 return (TREE_CODE (type
) == ARRAY_TYPE
7466 || TREE_CODE (type
) == FUNCTION_TYPE
7467 || (TREE_CODE (type
) == POINTER_TYPE
&& ! IS_ID (type
)));
7471 /* Code to convert a decl node into text for a declaration in C. */
7473 static char tmpbuf
[256];
7476 adorn_decl (decl
, str
)
7480 enum tree_code code
= TREE_CODE (decl
);
7482 if (code
== ARRAY_REF
)
7484 tree an_int_cst
= TREE_OPERAND (decl
, 1);
7486 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_CST
)
7487 sprintf (str
+ strlen (str
), "[%ld]",
7488 (long) TREE_INT_CST_LOW (an_int_cst
));
7493 else if (code
== ARRAY_TYPE
)
7495 tree an_int_cst
= TYPE_SIZE (decl
);
7496 tree array_of
= TREE_TYPE (decl
);
7498 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_TYPE
)
7499 sprintf (str
+ strlen (str
), "[%ld]",
7500 (long) (TREE_INT_CST_LOW (an_int_cst
)
7501 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
7506 else if (code
== CALL_EXPR
)
7508 tree chain
= TREE_PURPOSE (TREE_OPERAND (decl
, 1));
7513 gen_declaration (chain
, str
);
7514 chain
= TREE_CHAIN (chain
);
7521 else if (code
== FUNCTION_TYPE
)
7523 tree chain
= TYPE_ARG_TYPES (decl
);
7526 while (chain
&& TREE_VALUE (chain
) != void_type_node
)
7528 gen_declaration (TREE_VALUE (chain
), str
);
7529 chain
= TREE_CHAIN (chain
);
7530 if (chain
&& TREE_VALUE (chain
) != void_type_node
)
7536 else if (code
== INDIRECT_REF
)
7538 strcpy (tmpbuf
, "*");
7539 if (TREE_TYPE (decl
) && TREE_CODE (TREE_TYPE (decl
)) == TREE_LIST
)
7543 for (chain
= nreverse (copy_list (TREE_TYPE (decl
)));
7545 chain
= TREE_CHAIN (chain
))
7547 if (TREE_CODE (TREE_VALUE (chain
)) == IDENTIFIER_NODE
)
7549 strcat (tmpbuf
, " ");
7550 strcat (tmpbuf
, IDENTIFIER_POINTER (TREE_VALUE (chain
)));
7554 strcat (tmpbuf
, " ");
7556 strcat (tmpbuf
, str
);
7557 strcpy (str
, tmpbuf
);
7560 else if (code
== POINTER_TYPE
)
7562 strcpy (tmpbuf
, "*");
7563 if (TREE_READONLY (decl
) || TYPE_VOLATILE (decl
))
7565 if (TREE_READONLY (decl
))
7566 strcat (tmpbuf
, " const");
7567 if (TYPE_VOLATILE (decl
))
7568 strcat (tmpbuf
, " volatile");
7570 strcat (tmpbuf
, " ");
7572 strcat (tmpbuf
, str
);
7573 strcpy (str
, tmpbuf
);
7578 gen_declarator (decl
, buf
, name
)
7585 enum tree_code code
= TREE_CODE (decl
);
7595 op
= TREE_OPERAND (decl
, 0);
7597 /* We have a pointer to a function or array...(*)(), (*)[] */
7598 if ((code
== ARRAY_REF
|| code
== CALL_EXPR
)
7599 && op
&& TREE_CODE (op
) == INDIRECT_REF
)
7602 str
= gen_declarator (op
, buf
, name
);
7606 strcpy (tmpbuf
, "(");
7607 strcat (tmpbuf
, str
);
7608 strcat (tmpbuf
, ")");
7609 strcpy (str
, tmpbuf
);
7612 adorn_decl (decl
, str
);
7621 /* This clause is done iteratively rather than recursively. */
7624 op
= (is_complex_decl (TREE_TYPE (decl
))
7625 ? TREE_TYPE (decl
) : NULL_TREE
);
7627 adorn_decl (decl
, str
);
7629 /* We have a pointer to a function or array...(*)(), (*)[] */
7630 if (code
== POINTER_TYPE
7631 && op
&& (TREE_CODE (op
) == FUNCTION_TYPE
7632 || TREE_CODE (op
) == ARRAY_TYPE
))
7634 strcpy (tmpbuf
, "(");
7635 strcat (tmpbuf
, str
);
7636 strcat (tmpbuf
, ")");
7637 strcpy (str
, tmpbuf
);
7640 decl
= (is_complex_decl (TREE_TYPE (decl
))
7641 ? TREE_TYPE (decl
) : NULL_TREE
);
7644 while (decl
&& (code
= TREE_CODE (decl
)))
7649 case IDENTIFIER_NODE
:
7650 /* Will only happen if we are processing a "raw" expr-decl. */
7651 strcpy (buf
, IDENTIFIER_POINTER (decl
));
7662 /* We have an abstract declarator or a _DECL node. */
7670 gen_declspecs (declspecs
, buf
, raw
)
7679 for (chain
= nreverse (copy_list (declspecs
));
7680 chain
; chain
= TREE_CHAIN (chain
))
7682 tree aspec
= TREE_VALUE (chain
);
7684 if (TREE_CODE (aspec
) == IDENTIFIER_NODE
)
7685 strcat (buf
, IDENTIFIER_POINTER (aspec
));
7686 else if (TREE_CODE (aspec
) == RECORD_TYPE
)
7688 if (TYPE_NAME (aspec
))
7690 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7692 if (! TREE_STATIC_TEMPLATE (aspec
))
7693 strcat (buf
, "struct ");
7694 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7699 tree chain
= protocol_list
;
7706 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7707 chain
= TREE_CHAIN (chain
);
7716 strcat (buf
, "untagged struct");
7719 else if (TREE_CODE (aspec
) == UNION_TYPE
)
7721 if (TYPE_NAME (aspec
))
7723 if (! TREE_STATIC_TEMPLATE (aspec
))
7724 strcat (buf
, "union ");
7725 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7728 strcat (buf
, "untagged union");
7731 else if (TREE_CODE (aspec
) == ENUMERAL_TYPE
)
7733 if (TYPE_NAME (aspec
))
7735 if (! TREE_STATIC_TEMPLATE (aspec
))
7736 strcat (buf
, "enum ");
7737 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7740 strcat (buf
, "untagged enum");
7743 else if (TREE_CODE (aspec
) == TYPE_DECL
&& DECL_NAME (aspec
))
7744 strcat (buf
, IDENTIFIER_POINTER (DECL_NAME (aspec
)));
7746 else if (IS_ID (aspec
))
7748 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7753 tree chain
= protocol_list
;
7760 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7761 chain
= TREE_CHAIN (chain
);
7768 if (TREE_CHAIN (chain
))
7774 /* Type qualifiers. */
7775 if (TREE_READONLY (declspecs
))
7776 strcat (buf
, "const ");
7777 if (TYPE_VOLATILE (declspecs
))
7778 strcat (buf
, "volatile ");
7780 switch (TREE_CODE (declspecs
))
7782 /* Type specifiers. */
7785 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7787 /* Signed integer types. */
7789 if (declspecs
== short_integer_type_node
)
7790 strcat (buf
, "short int ");
7791 else if (declspecs
== integer_type_node
)
7792 strcat (buf
, "int ");
7793 else if (declspecs
== long_integer_type_node
)
7794 strcat (buf
, "long int ");
7795 else if (declspecs
== long_long_integer_type_node
)
7796 strcat (buf
, "long long int ");
7797 else if (declspecs
== signed_char_type_node
7798 || declspecs
== char_type_node
)
7799 strcat (buf
, "char ");
7801 /* Unsigned integer types. */
7803 else if (declspecs
== short_unsigned_type_node
)
7804 strcat (buf
, "unsigned short ");
7805 else if (declspecs
== unsigned_type_node
)
7806 strcat (buf
, "unsigned int ");
7807 else if (declspecs
== long_unsigned_type_node
)
7808 strcat (buf
, "unsigned long ");
7809 else if (declspecs
== long_long_unsigned_type_node
)
7810 strcat (buf
, "unsigned long long ");
7811 else if (declspecs
== unsigned_char_type_node
)
7812 strcat (buf
, "unsigned char ");
7816 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7818 if (declspecs
== float_type_node
)
7819 strcat (buf
, "float ");
7820 else if (declspecs
== double_type_node
)
7821 strcat (buf
, "double ");
7822 else if (declspecs
== long_double_type_node
)
7823 strcat (buf
, "long double ");
7827 if (TYPE_NAME (declspecs
)
7828 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7830 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7832 if (! TREE_STATIC_TEMPLATE (declspecs
))
7833 strcat (buf
, "struct ");
7834 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7838 tree chain
= protocol_list
;
7845 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7846 chain
= TREE_CHAIN (chain
);
7855 strcat (buf
, "untagged struct");
7861 if (TYPE_NAME (declspecs
)
7862 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7864 strcat (buf
, "union ");
7865 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7870 strcat (buf
, "untagged union ");
7874 if (TYPE_NAME (declspecs
)
7875 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7877 strcat (buf
, "enum ");
7878 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7883 strcat (buf
, "untagged enum ");
7887 strcat (buf
, "void ");
7892 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7897 tree chain
= protocol_list
;
7904 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7905 chain
= TREE_CHAIN (chain
);
7922 gen_declaration (atype_or_adecl
, buf
)
7923 tree atype_or_adecl
;
7928 if (TREE_CODE (atype_or_adecl
) == TREE_LIST
)
7930 tree declspecs
; /* "identifier_node", "record_type" */
7931 tree declarator
; /* "array_ref", "indirect_ref", "call_expr"... */
7933 /* We have a "raw", abstract declarator (typename). */
7934 declarator
= TREE_VALUE (atype_or_adecl
);
7935 declspecs
= TREE_PURPOSE (atype_or_adecl
);
7937 gen_declspecs (declspecs
, buf
, 1);
7941 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7948 tree declspecs
; /* "integer_type", "real_type", "record_type"... */
7949 tree declarator
; /* "array_type", "function_type", "pointer_type". */
7951 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7952 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7953 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7954 atype
= TREE_TYPE (atype_or_adecl
);
7956 /* Assume we have a *_type node. */
7957 atype
= atype_or_adecl
;
7959 if (is_complex_decl (atype
))
7963 /* Get the declaration specifier; it is at the end of the list. */
7964 declarator
= chain
= atype
;
7966 chain
= TREE_TYPE (chain
); /* not TREE_CHAIN (chain); */
7967 while (is_complex_decl (chain
));
7974 declarator
= NULL_TREE
;
7977 gen_declspecs (declspecs
, buf
, 0);
7979 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7980 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7981 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7983 char *decl_name
= (DECL_NAME (atype_or_adecl
)
7984 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl
))
7990 strcat (buf
, gen_declarator (declarator
, declbuf
, decl_name
));
7993 else if (decl_name
[0])
7996 strcat (buf
, decl_name
);
7999 else if (declarator
)
8002 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
8009 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
8012 gen_method_decl (method
, buf
)
8018 if (RAW_TYPESPEC (method
) != objc_object_reference
)
8021 gen_declaration (TREE_TYPE (method
), buf
);
8025 chain
= METHOD_SEL_ARGS (method
);
8028 /* We have a chain of keyword_decls. */
8031 if (KEYWORD_KEY_NAME (chain
))
8032 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain
)));
8035 if (RAW_TYPESPEC (chain
) != objc_object_reference
)
8038 gen_declaration (TREE_TYPE (chain
), buf
);
8042 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain
)));
8043 if ((chain
= TREE_CHAIN (chain
)))
8048 if (METHOD_ADD_ARGS (method
) == (tree
)1)
8049 strcat (buf
, ", ...");
8050 else if (METHOD_ADD_ARGS (method
))
8052 /* We have a tree list node as generate by get_parm_info. */
8053 chain
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
8055 /* Know we have a chain of parm_decls. */
8059 gen_declaration (chain
, buf
);
8060 chain
= TREE_CHAIN (chain
);
8066 /* We have a unary selector. */
8067 strcat (buf
, IDENTIFIER_POINTER (METHOD_SEL_NAME (method
)));
8075 dump_interface (fp
, chain
)
8079 char *buf
= (char *)xmalloc (256);
8080 char *my_name
= IDENTIFIER_POINTER (CLASS_NAME (chain
));
8081 tree ivar_decls
= CLASS_RAW_IVARS (chain
);
8082 tree nst_methods
= CLASS_NST_METHODS (chain
);
8083 tree cls_methods
= CLASS_CLS_METHODS (chain
);
8085 fprintf (fp
, "\n@interface %s", my_name
);
8087 if (CLASS_SUPER_NAME (chain
))
8089 char *super_name
= IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain
));
8090 fprintf (fp
, " : %s\n", super_name
);
8097 fprintf (fp
, "{\n");
8101 fprintf (fp
, "\t%s;\n", gen_declaration (ivar_decls
, buf
));
8102 ivar_decls
= TREE_CHAIN (ivar_decls
);
8105 fprintf (fp
, "}\n");
8111 fprintf (fp
, "- %s;\n", gen_method_decl (nst_methods
, buf
));
8112 nst_methods
= TREE_CHAIN (nst_methods
);
8118 fprintf (fp
, "+ %s;\n", gen_method_decl (cls_methods
, buf
));
8119 cls_methods
= TREE_CHAIN (cls_methods
);
8121 fprintf (fp
, "\n@end");
8124 /* Demangle function for Objective-C */
8126 objc_demangle (mangled
)
8127 const char *mangled
;
8129 char *demangled
, *cp
;
8131 if (mangled
[0] == '_' &&
8132 (mangled
[1] == 'i' || mangled
[1] == 'c') &&
8135 cp
= demangled
= xmalloc(strlen(mangled
) + 2);
8136 if (mangled
[1] == 'i')
8137 *cp
++ = '-'; /* for instance method */
8139 *cp
++ = '+'; /* for class method */
8140 *cp
++ = '['; /* opening left brace */
8141 strcpy(cp
, mangled
+3); /* tack on the rest of the mangled name */
8142 while (*cp
&& *cp
== '_')
8143 cp
++; /* skip any initial underbars in class name */
8144 cp
= strchr(cp
, '_'); /* find first non-initial underbar */
8147 free(demangled
); /* not mangled name */
8150 if (cp
[1] == '_') /* easy case: no category name */
8152 *cp
++ = ' '; /* replace two '_' with one ' ' */
8153 strcpy(cp
, mangled
+ (cp
- demangled
) + 2);
8157 *cp
++ = '('; /* less easy case: category name */
8158 cp
= strchr(cp
, '_');
8161 free(demangled
); /* not mangled name */
8165 *cp
++ = ' '; /* overwriting 1st char of method name... */
8166 strcpy(cp
, mangled
+ (cp
- demangled
)); /* get it back */
8168 while (*cp
&& *cp
== '_')
8169 cp
++; /* skip any initial underbars in method name */
8172 *cp
= ':'; /* replace remaining '_' with ':' */
8173 *cp
++ = ']'; /* closing right brace */
8174 *cp
++ = 0; /* string terminator */
8178 return mangled
; /* not an objc mangled name */
8182 objc_printable_name (decl
, kind
)
8186 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl
)));
8192 /* Add the special tree codes of Objective C to the tables. */
8194 #define LAST_CODE LAST_AND_UNUSED_TREE_CODE
8196 gcc_obstack_init (&util_obstack
);
8197 util_firstobj
= (char *) obstack_finish (&util_obstack
);
8199 bcopy (objc_tree_code_type
,
8200 tree_code_type
+ (int) LAST_CODE
,
8201 (int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
);
8202 bcopy ((char *) objc_tree_code_length
,
8203 (char *) (tree_code_length
+ (int) LAST_CODE
),
8204 (((int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
)
8206 bcopy ((char *) objc_tree_code_name
,
8207 (char *) (tree_code_name
+ (int) LAST_CODE
),
8208 (((int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
)
8209 * sizeof (char *)));
8211 errbuf
= (char *)xmalloc (BUFSIZE
);
8213 synth_module_prologue ();
8215 /* Change the default error function */
8216 decl_printable_name
= (char* (*)()) objc_printable_name
;
8222 struct imp_entry
*impent
;
8224 /* The internally generated initializers appear to have missing braces.
8225 Don't warn about this. */
8226 int save_warn_missing_braces
= warn_missing_braces
;
8227 warn_missing_braces
= 0;
8229 generate_forward_declaration_to_string_table ();
8231 #ifdef OBJC_PROLOGUE
8235 /* Process the static instances here because initialization of objc_symtab
8237 if (objc_static_instances
)
8238 generate_static_references ();
8240 if (implementation_context
|| class_names_chain
8241 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8242 generate_objc_symtab_decl ();
8244 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8246 implementation_context
= impent
->imp_context
;
8247 implementation_template
= impent
->imp_template
;
8249 UOBJC_CLASS_decl
= impent
->class_decl
;
8250 UOBJC_METACLASS_decl
= impent
->meta_decl
;
8252 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
8254 /* all of the following reference the string pool... */
8255 generate_ivar_lists ();
8256 generate_dispatch_tables ();
8257 generate_shared_structures ();
8261 generate_dispatch_tables ();
8262 generate_category (implementation_context
);
8266 /* If we are using an array of selectors, we must always
8267 finish up the array decl even if no selectors were used. */
8268 if (! flag_next_runtime
|| sel_ref_chain
)
8269 build_selector_translation_table ();
8272 generate_protocols ();
8274 if (implementation_context
|| class_names_chain
|| objc_static_instances
8275 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8277 /* Arrange for Objc data structures to be initialized at run time. */
8278 char *init_name
= build_module_descriptor ();
8280 assemble_constructor (init_name
);
8283 /* Dump the class references. This forces the appropriate classes
8284 to be linked into the executable image, preserving unix archive
8285 semantics. This can be removed when we move to a more dynamically
8286 linked environment. */
8288 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
8290 handle_class_ref (chain
);
8291 if (TREE_PURPOSE (chain
))
8292 generate_classref_translation_entry (chain
);
8295 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8296 handle_impent (impent
);
8298 /* Dump the string table last. */
8300 generate_strings ();
8302 if (flag_gen_declaration
)
8304 add_class (implementation_context
);
8305 dump_interface (gen_declaration_file
, implementation_context
);
8313 /* Run through the selector hash tables and print a warning for any
8314 selector which has multiple methods. */
8316 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8317 for (hsh
= cls_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8320 tree meth
= hsh
->key
;
8321 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8325 warning ("potential selector conflict for method `%s'",
8326 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8327 warn_with_method ("found", type
, meth
);
8328 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8329 warn_with_method ("found", type
, loop
->value
);
8332 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8333 for (hsh
= nst_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8336 tree meth
= hsh
->key
;
8337 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8341 warning ("potential selector conflict for method `%s'",
8342 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8343 warn_with_method ("found", type
, meth
);
8344 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8345 warn_with_method ("found", type
, loop
->value
);
8349 warn_missing_braces
= save_warn_missing_braces
;
8352 /* Subroutines of finish_objc. */
8355 generate_classref_translation_entry (chain
)
8358 tree expr
, name
, decl_specs
, decl
, sc_spec
;
8361 type
= TREE_TYPE (TREE_PURPOSE (chain
));
8363 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
8364 expr
= build_c_cast (type
, expr
); /* cast! */
8366 name
= DECL_NAME (TREE_PURPOSE (chain
));
8368 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
8370 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8371 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
8373 /* The decl that is returned from start_decl is the one that we
8374 forward declared in build_class_reference. */
8375 decl
= start_decl (name
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
8376 finish_decl (decl
, expr
, NULL_TREE
);
8381 handle_class_ref (chain
)
8384 char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
8385 if (! flag_next_runtime
)
8388 char *string
= (char *) alloca (strlen (name
) + 30);
8391 sprintf (string
, "%sobjc_class_name_%s",
8392 (flag_next_runtime
? "." : "__"), name
);
8394 /* Make a decl for this name, so we can use its address in a tree. */
8395 decl
= build_decl (VAR_DECL
, get_identifier (string
), char_type_node
);
8396 DECL_EXTERNAL (decl
) = 1;
8397 TREE_PUBLIC (decl
) = 1;
8400 rest_of_decl_compilation (decl
, 0, 0, 0);
8402 /* Make following constant read-only (why not)? */
8403 readonly_data_section ();
8405 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
8407 /* Align the section properly. */
8408 assemble_constant_align (exp
);
8410 /* Inform the assembler about this new external thing. */
8411 assemble_external (decl
);
8413 /* Output a constant to reference this address. */
8414 output_constant (exp
, int_size_in_bytes (string_type_node
));
8418 /* This overreliance on our assembler (i.e. lack of portability)
8419 should be dealt with at some point. The GNU strategy (above)
8420 won't work either, but it is a start. */
8421 char *string
= (char *) alloca (strlen (name
) + 30);
8422 sprintf (string
, ".reference .objc_class_name_%s", name
);
8423 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8428 handle_impent (impent
)
8429 struct imp_entry
*impent
;
8431 implementation_context
= impent
->imp_context
;
8432 implementation_template
= impent
->imp_template
;
8434 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
8436 char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8437 char *string
= (char *) alloca (strlen (class_name
) + 30);
8439 if (flag_next_runtime
)
8441 /* Grossly unportable.
8442 People should know better than to assume
8443 such things about assembler syntax! */
8444 sprintf (string
, ".objc_class_name_%s=0", class_name
);
8445 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8447 sprintf (string
, ".globl .objc_class_name_%s", class_name
);
8448 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8453 sprintf (string
, "%sobjc_class_name_%s",
8454 (flag_next_runtime
? "." : "__"), class_name
);
8455 assemble_global (string
);
8456 assemble_label (string
);
8460 else if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
8462 char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8463 char *class_super_name
8464 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
8465 char *string
= (char *) alloca (strlen (class_name
)
8466 + strlen (class_super_name
) + 30);
8468 /* Do the same for categories. Even though no references to these
8469 symbols are generated automatically by the compiler, it gives
8470 you a handle to pull them into an archive by hand. */
8471 if (flag_next_runtime
)
8473 /* Grossly unportable. */
8474 sprintf (string
, ".objc_category_name_%s_%s=0",
8475 class_name
, class_super_name
);
8476 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8478 sprintf (string
, ".globl .objc_category_name_%s_%s",
8479 class_name
, class_super_name
);
8480 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8485 sprintf (string
, "%sobjc_category_name_%s_%s",
8486 (flag_next_runtime
? "." : "__"),
8487 class_name
, class_super_name
);
8488 assemble_global (string
);
8489 assemble_label (string
);
8500 char *buf
= (char *)xmalloc (256);
8502 { /* dump function prototypes */
8503 tree loop
= UOBJC_MODULES_decl
;
8505 fprintf (fp
, "\n\nfunction prototypes:\n");
8508 if (TREE_CODE (loop
) == FUNCTION_DECL
&& DECL_INITIAL (loop
))
8510 /* We have a function definition: generate prototype. */
8511 bzero (errbuf
, BUFSIZE
);
8512 gen_declaration (loop
, errbuf
);
8513 fprintf (fp
, "%s;\n", errbuf
);
8515 loop
= TREE_CHAIN (loop
);
8519 /* Dump global chains. */
8521 int i
, index
= 0, offset
= 0;
8524 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
8526 if (hashlist
= nst_method_hash_list
[i
])
8528 fprintf (fp
, "\n\nnst_method_hash_list[%d]:\n", i
);
8532 fprintf (fp
, "-%s;\n", gen_method_decl (hashlist
->key
, buf
));
8533 hashlist
= hashlist
->next
;
8539 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
8541 if (hashlist
= cls_method_hash_list
[i
])
8543 fprintf (fp
, "\n\ncls_method_hash_list[%d]:\n", i
);
8547 fprintf (fp
, "-%s;\n", gen_method_decl (hashlist
->key
, buf
));
8548 hashlist
= hashlist
->next
;
8554 fprintf (fp
, "\nsel_refdef_chain:\n");
8555 for (loop
= sel_refdef_chain
; loop
; loop
= TREE_CHAIN (loop
))
8557 fprintf (fp
, "(index: %4d offset: %4d) %s\n", index
, offset
,
8558 IDENTIFIER_POINTER (TREE_VALUE (loop
)));
8560 /* add one for the '\0' character */
8561 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (loop
)) + 1;
8564 fprintf (fp
, "\n (max_selector_index: %4d.\n", max_selector_index
);
8570 print_lang_statistics ()