1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
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, 675 Mass Ave, Cambridge, MA 02139, USA. */
21 /* Purpose: This module implements the Objective-C 4.0 language.
23 compatibility issues (with the Stepstone translator):
25 - does not recognize the following 3.3 constructs.
26 @requires, @classes, @messages, = (...)
27 - methods with variable arguments must conform to ANSI standard.
28 - tagged structure definitions that appear in BOTH the interface
29 and implementation are not allowed.
30 - public/private: all instance variables are public within the
31 context of the implementation...I consider this to be a bug in
33 - statically allocated objects are not supported. the user will
34 receive an error if this service is requested.
36 code generation `options':
38 - OBJC_INT_SELECTORS */
51 /* This is the default way of generating a method name. */
52 /* I am not sure it is really correct.
53 Perhaps there's a danger that it will make name conflicts
54 if method names contain underscores. -- rms. */
55 #ifndef OBJC_GEN_METHOD_LABEL
56 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
59 sprintf ((BUF), "_%s_%s_%s_%s", \
60 ((IS_INST) ? "i" : "c"), \
62 ((CAT_NAME)? (CAT_NAME) : ""), \
64 for (temp = (BUF); *temp; temp++) \
65 if (*temp == ':') *temp = '_'; \
69 /* These need specifying. */
70 #ifndef OBJC_FORWARDING_STACK_OFFSET
71 #define OBJC_FORWARDING_STACK_OFFSET 0
74 #ifndef OBJC_FORWARDING_MIN_OFFSET
75 #define OBJC_FORWARDING_MIN_OFFSET 0
78 /* Define the special tree codes that we use. */
80 /* Table indexed by tree code giving a string containing a character
81 classifying the tree code. Possibilities are
82 t, d, s, c, r, <, 1 and 2. See objc-tree.def for details. */
84 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
86 char *objc_tree_code_type
[] = {
88 #include "objc-tree.def"
92 /* Table indexed by tree code giving number of expression
93 operands beyond the fixed part of the node structure.
94 Not used for types or decls. */
96 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
98 int objc_tree_code_length
[] = {
100 #include "objc-tree.def"
104 /* Names of tree components.
105 Used for printing out the tree and error messages. */
106 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
108 char *objc_tree_code_name
[] = {
110 #include "objc-tree.def"
114 /* Set up for use of obstacks. */
118 #define obstack_chunk_alloc xmalloc
119 #define obstack_chunk_free free
121 /* This obstack is used to accumulate the encoding of a data type. */
122 static struct obstack util_obstack
;
123 /* This points to the beginning of obstack contents,
124 so we can free the whole contents. */
127 /* for encode_method_def */
131 #define OBJC_VERSION (flag_next_runtime ? 5 : 6)
132 #define PROTOCOL_VERSION 2
134 #define NULLT (tree) 0
136 #define OBJC_ENCODE_INLINE_DEFS 0
137 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
139 /*** Private Interface (procedures) ***/
141 /* used by compile_file */
143 static void init_objc
PROTO((void));
144 static void finish_objc
PROTO((void));
146 /* code generation */
148 static void synth_module_prologue
PROTO((void));
149 static tree build_constructor
PROTO((tree
, tree
));
150 static char *build_module_descriptor
PROTO((void));
151 static tree init_module_descriptor
PROTO((tree
));
152 static tree build_objc_method_call
PROTO((int, tree
, tree
, tree
, tree
, tree
));
153 static void generate_strings
PROTO((void));
154 static tree get_proto_encoding
PROTO((tree
));
155 static void build_selector_translation_table
PROTO((void));
156 static tree build_ivar_chain
PROTO((tree
, int));
158 static tree build_ivar_template
PROTO((void));
159 static tree build_method_template
PROTO((void));
160 static tree build_private_template
PROTO((tree
));
161 static void build_class_template
PROTO((void));
162 static void build_selector_template
PROTO((void));
163 static void build_category_template
PROTO((void));
164 static tree build_super_template
PROTO((void));
165 static tree build_category_initializer
PROTO((tree
, tree
, tree
, tree
, tree
, tree
));
166 static tree build_protocol_initializer
PROTO((tree
, tree
, tree
, tree
, tree
));
168 static void synth_forward_declarations
PROTO((void));
169 static void generate_ivar_lists
PROTO((void));
170 static void generate_dispatch_tables
PROTO((void));
171 static void generate_shared_structures
PROTO((void));
172 static tree generate_protocol_list
PROTO((tree
));
173 static void generate_forward_declaration_to_string_table
PROTO((void));
174 static void build_protocol_reference
PROTO((tree
));
176 static tree init_selector
PROTO((int));
177 static tree build_keyword_selector
PROTO((tree
));
178 static tree synth_id_with_class_suffix
PROTO((char *, tree
));
181 extern int apply_args_register_offset
PROTO((int));
183 /* misc. bookkeeping */
185 typedef struct hashed_entry
*hash
;
186 typedef struct hashed_attribute
*attr
;
188 struct hashed_attribute
200 static void hash_init
PROTO((void));
201 static void hash_enter
PROTO((hash
*, tree
));
202 static hash hash_lookup
PROTO((hash
*, tree
));
203 static void hash_add_attr
PROTO((hash
, tree
));
204 static tree lookup_method
PROTO((tree
, tree
));
205 static tree lookup_instance_method_static
PROTO((tree
, tree
));
206 static tree lookup_class_method_static
PROTO((tree
, tree
));
207 static tree add_class
PROTO((tree
));
208 static void add_category
PROTO((tree
, tree
));
212 class_names
, /* class, category, protocol, module names */
213 meth_var_names
, /* method and variable names */
214 meth_var_types
/* method and variable type descriptors */
217 static tree add_objc_string
PROTO((tree
, enum string_section
));
218 static tree build_objc_string_decl
PROTO((tree
, enum string_section
));
219 static tree build_selector_reference_decl
PROTO((tree
));
221 /* protocol additions */
223 static tree add_protocol
PROTO((tree
));
224 static tree lookup_protocol
PROTO((tree
));
225 static tree lookup_and_install_protocols
PROTO((tree
));
229 static void encode_type_qualifiers
PROTO((tree
));
230 static void encode_pointer
PROTO((tree
, int, int));
231 static void encode_array
PROTO((tree
, int, int));
232 static void encode_aggregate
PROTO((tree
, int, int));
233 static void encode_bitfield
PROTO((int, int));
234 static void encode_type
PROTO((tree
, int, int));
235 static void encode_field_decl
PROTO((tree
, int, int));
237 static void really_start_method
PROTO((tree
, tree
));
238 static int comp_method_with_proto
PROTO((tree
, tree
));
239 static int comp_proto_with_proto
PROTO((tree
, tree
));
240 static tree get_arg_type_list
PROTO((tree
, int, int));
241 static tree expr_last
PROTO((tree
));
243 /* utilities for debugging and error diagnostics: */
245 static void warn_with_method
PROTO((char *, int, tree
));
246 static void error_with_ivar
PROTO((char *, tree
, tree
));
247 static char *gen_method_decl
PROTO((tree
, char *));
248 static char *gen_declaration
PROTO((tree
, char *));
249 static char *gen_declarator
PROTO((tree
, char *, char *));
250 static int is_complex_decl
PROTO((tree
));
251 static void adorn_decl
PROTO((tree
, char *));
252 static void dump_interface
PROTO((FILE *, tree
));
254 /* everything else. */
256 static void objc_fatal
PROTO((void));
257 static tree define_decl
PROTO((tree
, tree
));
258 static tree lookup_method_in_protocol_list
PROTO((tree
, tree
, int));
259 static tree lookup_protocol_in_reflist
PROTO((tree
, tree
));
260 static tree create_builtin_decl
PROTO((enum tree_code
, tree
, char *));
261 static tree my_build_string
PROTO((int, char *));
262 static void build_objc_symtab_template
PROTO((void));
263 static tree init_def_list
PROTO((tree
));
264 static tree init_objc_symtab
PROTO((tree
));
265 static void forward_declare_categories
PROTO((void));
266 static void generate_objc_symtab_decl
PROTO((void));
267 static tree build_selector
PROTO((tree
));
268 static tree build_msg_pool_reference
PROTO((int));
269 static tree build_typed_selector_reference
PROTO((tree
, tree
));
270 static tree build_selector_reference
PROTO((tree
));
271 static tree build_class_reference_decl
PROTO((tree
));
272 static void add_class_reference
PROTO((tree
));
273 static tree objc_copy_list
PROTO((tree
, tree
*));
274 static tree build_protocol_template
PROTO((void));
275 static tree build_descriptor_table_initializer
PROTO((tree
, tree
));
276 static tree build_method_prototype_list_template
PROTO((tree
, int));
277 static tree build_method_prototype_template
PROTO((void));
278 static int forwarding_offset
PROTO((tree
));
279 static tree encode_method_prototype
PROTO((tree
, tree
));
280 static tree generate_descriptor_table
PROTO((tree
, char *, int, tree
, tree
));
281 static void generate_method_descriptors
PROTO((tree
));
282 static tree build_tmp_function_decl
PROTO((void));
283 static void hack_method_prototype
PROTO((tree
, tree
));
284 static void generate_protocol_references
PROTO((tree
));
285 static void generate_protocols
PROTO((void));
286 static void check_ivars
PROTO((tree
, tree
));
287 static tree build_ivar_list_template
PROTO((tree
, int));
288 static tree build_method_list_template
PROTO((tree
, int));
289 static tree build_ivar_list_initializer
PROTO((tree
, tree
));
290 static tree generate_ivars_list
PROTO((tree
, char *, int, tree
));
291 static tree build_dispatch_table_initializer
PROTO((tree
, tree
));
292 static tree generate_dispatch_table
PROTO((tree
, char *, int, tree
));
293 static tree build_shared_structure_initializer
PROTO((tree
, tree
, tree
, tree
, tree
, int, tree
, tree
, tree
));
294 static void generate_category
PROTO((tree
));
295 static int is_objc_type_qualifier
PROTO((tree
));
296 static tree adjust_type_for_id_default
PROTO((tree
));
297 static tree check_duplicates
PROTO((hash
));
298 static tree receiver_is_class_object
PROTO((tree
));
299 static int check_methods
PROTO((tree
, tree
, int));
300 static int conforms_to_protocol
PROTO((tree
, tree
));
301 static void check_protocols
PROTO((tree
, char *, char *));
302 static tree encode_method_def
PROTO((tree
));
303 static void gen_declspecs
PROTO((tree
, char *, int));
304 static void generate_classref_translation_entry
PROTO((tree
));
305 static void handle_class_ref
PROTO((tree
));
307 /*** Private Interface (data) ***/
309 /* reserved tag definitions: */
312 #define TAG_OBJECT "objc_object"
313 #define TAG_CLASS "objc_class"
314 #define TAG_SUPER "objc_super"
315 #define TAG_SELECTOR "objc_selector"
317 #define UTAG_CLASS "_objc_class"
318 #define UTAG_IVAR "_objc_ivar"
319 #define UTAG_IVAR_LIST "_objc_ivar_list"
320 #define UTAG_METHOD "_objc_method"
321 #define UTAG_METHOD_LIST "_objc_method_list"
322 #define UTAG_CATEGORY "_objc_category"
323 #define UTAG_MODULE "_objc_module"
324 #define UTAG_SYMTAB "_objc_symtab"
325 #define UTAG_SUPER "_objc_super"
326 #define UTAG_SELECTOR "_objc_selector"
328 #define UTAG_PROTOCOL "_objc_protocol"
329 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
330 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
331 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
333 #define STRING_OBJECT_CLASS_NAME "NXConstantString"
334 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
336 static char* TAG_GETCLASS
;
337 static char* TAG_GETMETACLASS
;
338 static char* TAG_MSGSEND
;
339 static char* TAG_MSGSENDSUPER
;
340 static char* TAG_EXECCLASS
;
342 /* Set by `continue_class' and checked by `is_public'. */
344 #define TREE_STATIC_TEMPLATE(record_type) (TREE_PUBLIC (record_type))
345 #define TYPED_OBJECT(type) \
346 (TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type))
348 /* Some commonly used instances of "identifier_node". */
350 static tree self_id
, ucmd_id
;
352 static tree self_decl
, umsg_decl
, umsg_super_decl
;
353 static tree objc_get_class_decl
, objc_get_meta_class_decl
;
355 static tree super_type
, selector_type
, id_type
, objc_class_type
;
356 static tree instance_type
, protocol_type
;
358 /* Type checking macros. */
360 #define IS_ID(TYPE) \
361 (TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (id_type))
362 #define IS_PROTOCOL_QUALIFIED_ID(TYPE) \
363 (IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE))
364 #define IS_SUPER(TYPE) \
365 (super_type && TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (super_type))
367 static tree class_chain
= NULLT
;
368 static tree alias_chain
= NULLT
;
369 static tree interface_chain
= NULLT
;
370 static tree protocol_chain
= NULLT
;
372 /* chains to manage selectors that are referenced and defined in the module */
374 static tree cls_ref_chain
= NULLT
; /* classes referenced */
375 static tree sel_ref_chain
= NULLT
; /* selectors referenced */
377 /* chains to manage uniquing of strings */
379 static tree class_names_chain
= NULLT
;
380 static tree meth_var_names_chain
= NULLT
;
381 static tree meth_var_types_chain
= NULLT
;
383 /* hash tables to manage the global pool of method prototypes */
385 static hash
*nst_method_hash_list
= 0;
386 static hash
*cls_method_hash_list
= 0;
388 /* backend data declarations */
390 static tree UOBJC_SYMBOLS_decl
;
391 static tree UOBJC_INSTANCE_VARIABLES_decl
, UOBJC_CLASS_VARIABLES_decl
;
392 static tree UOBJC_INSTANCE_METHODS_decl
, UOBJC_CLASS_METHODS_decl
;
393 static tree UOBJC_CLASS_decl
, UOBJC_METACLASS_decl
;
394 static tree UOBJC_SELECTOR_TABLE_decl
;
395 static tree UOBJC_MODULES_decl
;
396 static tree UOBJC_STRINGS_decl
;
398 /* The following are used when compiling a class implementation.
399 implementation_template will normally be an interface, however if
400 none exists this will be equal to implementation_context...it is
401 set in start_class. */
403 static tree implementation_context
= NULLT
,
404 implementation_template
= NULLT
;
408 struct imp_entry
*next
;
411 tree class_decl
; /* _OBJC_CLASS_<my_name>; */
412 tree meta_decl
; /* _OBJC_METACLASS_<my_name>; */
415 static void handle_impent
PROTO((struct imp_entry
*));
417 static struct imp_entry
*imp_list
= 0;
418 static int imp_count
= 0; /* `@implementation' */
419 static int cat_count
= 0; /* `@category' */
421 static tree objc_class_template
, objc_category_template
, uprivate_record
;
422 static tree objc_protocol_template
, objc_selector_template
;
423 static tree ucls_super_ref
, uucls_super_ref
;
425 static tree objc_method_template
, objc_ivar_template
;
426 static tree objc_symtab_template
, objc_module_template
;
427 static tree objc_super_template
, objc_object_reference
;
429 static tree objc_object_id
, objc_class_id
, objc_id_id
;
430 static tree constant_string_id
;
431 static tree constant_string_type
;
432 static tree UOBJC_SUPER_decl
;
434 static tree method_context
= NULLT
;
435 static int method_slot
= 0; /* used by start_method_def */
439 static char *errbuf
; /* a buffer for error diagnostics */
441 /* data imported from tree.c */
443 extern struct obstack permanent_obstack
, *current_obstack
, *rtl_obstack
;
444 extern enum debug_info_type write_symbols
;
446 /* data imported from toplev.c */
448 extern char *dump_base_name
;
450 /* Generate code for GNU or NeXT runtime environment. */
452 #ifdef NEXT_OBJC_RUNTIME
453 int flag_next_runtime
= 1;
455 int flag_next_runtime
= 0;
458 int flag_typed_selectors
;
460 /* Open and close the file for outputting class declarations, if requested. */
462 int flag_gen_declaration
= 0;
464 FILE *gen_declaration_file
;
466 /* Warn if multiple methods are seen for the same selector, but with
467 different argument types. */
469 int warn_selector
= 0;
471 /* Warn if methods required by a protocol are not implemented in the
472 class adopting it. When turned off, methods inherited to that
473 class are also considered implemented */
475 int flag_warn_protocol
= 1;
477 /* tells "encode_pointer/encode_aggregate" whether we are generating
478 type descriptors for instance variables (as opposed to methods).
479 Type descriptors for instance variables contain more information
480 than methods (for static typing and embedded structures). This
481 was added to support features being planned for dbkit2. */
483 static int generating_instance_variables
= 0;
488 /* the beginning of the file is a new line; check for # */
489 /* With luck, we discover the real source file's name from that
490 and put it in input_filename. */
491 ungetc (check_newline (), finput
);
493 /* The line number can be -1 if we had -g3 and the input file
494 had a directive specifying line 0. But we want predefined
495 functions to have a line number of 0, not -1. */
499 /* If gen_declaration desired, open the output file. */
500 if (flag_gen_declaration
)
502 int dump_base_name_length
= strlen (dump_base_name
);
503 register char *dumpname
= (char *) xmalloc (dump_base_name_length
+ 7);
504 strcpy (dumpname
, dump_base_name
);
505 strcat (dumpname
, ".decl");
506 gen_declaration_file
= fopen (dumpname
, "w");
507 if (gen_declaration_file
== 0)
508 pfatal_with_name (dumpname
);
511 if (flag_next_runtime
)
513 TAG_GETCLASS
= "objc_getClass";
514 TAG_GETMETACLASS
= "objc_getMetaClass";
515 TAG_MSGSEND
= "objc_msgSend";
516 TAG_MSGSENDSUPER
= "objc_msgSendSuper";
517 TAG_EXECCLASS
= "__objc_execClass";
521 TAG_GETCLASS
= "objc_get_class";
522 TAG_GETMETACLASS
= "objc_get_meta_class";
523 TAG_MSGSEND
= "objc_msg_lookup";
524 TAG_MSGSENDSUPER
= "objc_msg_lookup_super";
525 TAG_EXECCLASS
= "__objc_exec_class";
526 flag_typed_selectors
= 1;
529 if (doing_objc_thang
)
536 fatal ("Objective-C text in C source file");
542 if (doing_objc_thang
)
543 finish_objc (); /* Objective-C finalization */
545 if (gen_declaration_file
)
546 fclose (gen_declaration_file
);
561 lang_decode_option (p
)
564 if (!strcmp (p
, "-lang-objc"))
565 doing_objc_thang
= 1;
566 else if (!strcmp (p
, "-gen-decls"))
567 flag_gen_declaration
= 1;
568 else if (!strcmp (p
, "-Wselector"))
570 else if (!strcmp (p
, "-Wno-selector"))
572 else if (!strcmp (p
, "-Wprotocol"))
573 flag_warn_protocol
= 1;
574 else if (!strcmp (p
, "-Wno-protocol"))
575 flag_warn_protocol
= 0;
576 else if (!strcmp (p
, "-fgnu-runtime"))
577 flag_next_runtime
= 0;
578 else if (!strcmp (p
, "-fno-next-runtime"))
579 flag_next_runtime
= 0;
580 else if (!strcmp (p
, "-fno-gnu-runtime"))
581 flag_next_runtime
= 1;
582 else if (!strcmp (p
, "-fnext-runtime"))
583 flag_next_runtime
= 1;
585 return c_decode_option (p
);
591 define_decl (declarator
, declspecs
)
595 tree decl
= start_decl (declarator
, declspecs
, 0);
596 finish_decl (decl
, NULLT
, NULLT
);
600 /* Return 1 if LHS and RHS are compatible types for assignment or
601 various other operations. Return 0 if they are incompatible, and
602 return -1 if we choose to not decide. When the operation is
603 REFLEXIVE, check for compatibility in either direction.
605 For statically typed objects, an assignment of the form `a' = `b'
609 `a' and `b' are the same class type, or
610 `a' and `b' are of class types A and B such that B is a descendant of A. */
613 maybe_objc_comptypes (lhs
, rhs
, reflexive
)
617 if (doing_objc_thang
)
618 return objc_comptypes (lhs
, rhs
, reflexive
);
623 lookup_method_in_protocol_list (rproto_list
, sel_name
, class_meth
)
631 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
633 p
= TREE_VALUE (rproto
);
635 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
637 if ((fnd
= lookup_method (class_meth
638 ? PROTOCOL_CLS_METHODS (p
)
639 : PROTOCOL_NST_METHODS (p
), sel_name
)))
641 else if (PROTOCOL_LIST (p
))
642 fnd
= lookup_method_in_protocol_list (PROTOCOL_LIST (p
), sel_name
, class_meth
);
645 ; /* an identifier...if we could not find a protocol. */
654 lookup_protocol_in_reflist (rproto_list
, lproto
)
660 /* make sure the protocol is support by the object on the rhs */
661 if (TREE_CODE (lproto
) == PROTOCOL_INTERFACE_TYPE
)
664 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
666 p
= TREE_VALUE (rproto
);
668 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
673 else if (PROTOCOL_LIST (p
))
674 fnd
= lookup_protocol_in_reflist (PROTOCOL_LIST (p
), lproto
);
682 ; /* an identifier...if we could not find a protocol. */
687 /* Return 1 if LHS and RHS are compatible types for assignment
688 or various other operations. Return 0 if they are incompatible,
689 and return -1 if we choose to not decide. When the operation
690 is REFLEXIVE, check for compatibility in either direction. */
693 objc_comptypes (lhs
, rhs
, reflexive
)
698 /* new clause for protocols */
700 if (TREE_CODE (lhs
) == POINTER_TYPE
701 && TREE_CODE (TREE_TYPE (lhs
)) == RECORD_TYPE
702 && TREE_CODE (rhs
) == POINTER_TYPE
703 && TREE_CODE (TREE_TYPE (rhs
)) == RECORD_TYPE
)
705 int lhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (lhs
);
706 int rhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (rhs
);
710 tree lproto
, lproto_list
= TYPE_PROTOCOL_LIST (lhs
);
711 tree rproto
, rproto_list
;
716 rproto_list
= TYPE_PROTOCOL_LIST (rhs
);
718 /* Make sure the protocol is supported by the object
720 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
722 p
= TREE_VALUE (lproto
);
723 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
726 warning ("object does not conform to the `%s' protocol",
727 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
730 else if (TYPED_OBJECT (TREE_TYPE (rhs
)))
732 tree rname
= TYPE_NAME (TREE_TYPE (rhs
));
735 /* Make sure the protocol is supported by the object
737 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
739 p
= TREE_VALUE (lproto
);
741 rinter
= lookup_interface (rname
);
743 while (rinter
&& !rproto
)
747 rproto_list
= CLASS_PROTOCOL_LIST (rinter
);
748 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
751 /* Check for protocols adopted by categories. */
752 cat
= CLASS_CATEGORY_LIST (rinter
);
753 while (cat
&& !rproto
)
755 rproto_list
= CLASS_PROTOCOL_LIST (cat
);
756 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
758 cat
= CLASS_CATEGORY_LIST (cat
);
761 rinter
= lookup_interface (CLASS_SUPER_NAME (rinter
));
764 warning ("class `%s' does not implement the `%s' protocol",
765 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs
))),
766 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
770 return 1; /* may change...based on whether there was any mismatch */
772 else if (rhs_is_proto
)
774 /* lhs is not a protocol...warn if it is statically typed */
776 if (TYPED_OBJECT (TREE_TYPE (lhs
)))
779 return 1; /* one of the types is a protocol */
782 return -1; /* defer to comptypes */
784 else if (TREE_CODE (lhs
) == RECORD_TYPE
&& TREE_CODE (rhs
) == RECORD_TYPE
)
785 ; /* fall thru...this is the case we have been handling all along */
787 return -1; /* defer to comptypes */
789 /* End of new protocol support. */
791 /* `id' = `<class> *', `<class> *' = `id' */
793 if ((TYPE_NAME (lhs
) == objc_object_id
&& TYPED_OBJECT (rhs
))
794 || (TYPE_NAME (rhs
) == objc_object_id
&& TYPED_OBJECT (lhs
)))
797 /* `id' = `Class', `Class' = `id' */
799 else if ((TYPE_NAME (lhs
) == objc_object_id
800 && TYPE_NAME (rhs
) == objc_class_id
)
801 || (TYPE_NAME (lhs
) == objc_class_id
802 && TYPE_NAME (rhs
) == objc_object_id
))
805 /* `<class> *' = `<class> *' */
807 else if (TYPED_OBJECT (lhs
) && TYPED_OBJECT (rhs
))
809 tree lname
= TYPE_NAME (lhs
);
810 tree rname
= TYPE_NAME (rhs
);
816 /* If the left hand side is a super class of the right hand side,
818 for (inter
= lookup_interface (rname
); inter
;
819 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
820 if (lname
== CLASS_SUPER_NAME (inter
))
823 /* Allow the reverse when reflexive. */
825 for (inter
= lookup_interface (lname
); inter
;
826 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
827 if (rname
== CLASS_SUPER_NAME (inter
))
833 return -1; /* defer to comptypes */
836 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
839 objc_check_decl (decl
)
842 tree type
= TREE_TYPE (decl
);
844 if (TREE_CODE (type
) == RECORD_TYPE
845 && TREE_STATIC_TEMPLATE (type
)
846 && type
!= constant_string_type
)
848 error_with_decl (decl
, "`%s' cannot be statically allocated");
849 fatal ("statically allocated objects not supported");
854 maybe_objc_check_decl (decl
)
857 if (doing_objc_thang
)
858 objc_check_decl (decl
);
861 /* Implement static typing. At this point, we know we have an interface. */
864 get_static_reference (interface
, protocols
)
868 tree type
= xref_tag (RECORD_TYPE
, interface
);
872 tree t
, m
= TYPE_MAIN_VARIANT (type
);
873 struct obstack
*ambient_obstack
= current_obstack
;
875 current_obstack
= &permanent_obstack
;
876 t
= copy_node (type
);
877 TYPE_BINFO (t
) = make_tree_vec (2);
879 /* Add this type to the chain of variants of TYPE. */
880 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
881 TYPE_NEXT_VARIANT (m
) = t
;
883 current_obstack
= ambient_obstack
;
885 /* Look up protocols and install in lang specific list. */
886 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
888 /* This forces a new pointer type to be created later
889 (in build_pointer_type)...so that the new template
890 we just created will actually be used...what a hack! */
891 if (TYPE_POINTER_TO (t
))
892 TYPE_POINTER_TO (t
) = NULL
;
901 get_object_reference (protocols
)
904 tree type_decl
= lookup_name (objc_id_id
);
907 if (type_decl
&& TREE_CODE (type_decl
) == TYPE_DECL
)
909 type
= TREE_TYPE (type_decl
);
910 if (TYPE_MAIN_VARIANT (type
) != id_type
)
911 warning ("Unexpected type for `id' (%s)",
912 gen_declaration (type
, errbuf
));
916 fatal ("Undefined type `id', please import <objc/objc.h>");
919 /* This clause creates a new pointer type that is qualified with
920 the protocol specification...this info is used later to do more
921 elaborate type checking. */
924 tree t
, m
= TYPE_MAIN_VARIANT (type
);
925 struct obstack
*ambient_obstack
= current_obstack
;
927 current_obstack
= &permanent_obstack
;
928 t
= copy_node (type
);
929 TYPE_BINFO (t
) = make_tree_vec (2);
931 /* Add this type to the chain of variants of TYPE. */
932 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
933 TYPE_NEXT_VARIANT (m
) = t
;
935 current_obstack
= ambient_obstack
;
937 /* look up protocols...and install in lang specific list */
938 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
940 /* This forces a new pointer type to be created later
941 (in build_pointer_type)...so that the new template
942 we just created will actually be used...what a hack! */
943 if (TYPE_POINTER_TO (t
))
944 TYPE_POINTER_TO (t
) = NULL
;
952 lookup_and_install_protocols (protocols
)
957 tree return_value
= protocols
;
959 for (proto
= protocols
; proto
; proto
= TREE_CHAIN (proto
))
961 tree ident
= TREE_VALUE (proto
);
962 tree p
= lookup_protocol (ident
);
966 error ("Cannot find protocol declaration for `%s'",
967 IDENTIFIER_POINTER (ident
));
969 TREE_CHAIN (prev
) = TREE_CHAIN (proto
);
971 return_value
= TREE_CHAIN (proto
);
975 /* replace identifier with actual protocol node */
976 TREE_VALUE (proto
) = p
;
983 /* Create and push a decl for a built-in external variable or field NAME.
985 TYPE is its data type. */
988 create_builtin_decl (code
, type
, name
)
993 tree decl
= build_decl (code
, get_identifier (name
), type
);
994 if (code
== VAR_DECL
)
996 TREE_STATIC (decl
) = 1;
997 make_decl_rtl (decl
, 0, 1);
1003 /* purpose: "play" parser, creating/installing representations
1004 of the declarations that are required by Objective-C.
1008 type_spec--------->sc_spec
1009 (tree_list) (tree_list)
1012 identifier_node identifier_node */
1015 synth_module_prologue ()
1020 /* defined in `objc.h' */
1021 objc_object_id
= get_identifier (TAG_OBJECT
);
1023 objc_object_reference
= xref_tag (RECORD_TYPE
, objc_object_id
);
1025 id_type
= build_pointer_type (objc_object_reference
);
1027 objc_id_id
= get_identifier (TYPE_ID
);
1028 objc_class_id
= get_identifier (TAG_CLASS
);
1030 objc_class_type
= build_pointer_type (xref_tag (RECORD_TYPE
, objc_class_id
));
1031 protocol_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
1032 get_identifier (PROTOCOL_OBJECT_CLASS_NAME
)));
1034 /* Declare type of selector-objects that represent an operation name. */
1036 #ifdef OBJC_INT_SELECTORS
1037 /* `unsigned int' */
1038 selector_type
= unsigned_type_node
;
1040 /* `struct objc_selector *' */
1042 = build_pointer_type (xref_tag (RECORD_TYPE
,
1043 get_identifier (TAG_SELECTOR
)));
1044 #endif /* not OBJC_INT_SELECTORS */
1046 /* Forward declare type, or else the prototype for msgSendSuper will
1049 super_p
= build_pointer_type (xref_tag (RECORD_TYPE
,
1050 get_identifier (TAG_SUPER
)));
1053 /* id objc_msgSend (id, SEL, ...); */
1056 = build_function_type (id_type
,
1057 tree_cons (NULL_TREE
, id_type
,
1058 tree_cons (NULLT
, selector_type
, NULLT
)));
1060 if (! flag_next_runtime
)
1062 umsg_decl
= build_decl (FUNCTION_DECL
,
1063 get_identifier (TAG_MSGSEND
), temp_type
);
1064 DECL_EXTERNAL (umsg_decl
) = 1;
1065 TREE_PUBLIC (umsg_decl
) = 1;
1066 DECL_INLINE (umsg_decl
) = 1;
1068 if (flag_traditional
&& TAG_MSGSEND
[0] != '_')
1069 DECL_BUILT_IN_NONANSI (umsg_decl
) = 1;
1071 make_decl_rtl (umsg_decl
, NULL_PTR
, 1);
1072 pushdecl (umsg_decl
);
1075 umsg_decl
= builtin_function (TAG_MSGSEND
, temp_type
, NOT_BUILT_IN
, 0);
1077 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1080 = build_function_type (id_type
,
1081 tree_cons (NULL_TREE
, super_p
,
1082 tree_cons (NULLT
, selector_type
, NULLT
)));
1084 umsg_super_decl
= builtin_function (TAG_MSGSENDSUPER
,
1085 temp_type
, NOT_BUILT_IN
, 0);
1087 /* id objc_getClass (const char *); */
1089 temp_type
= build_function_type (id_type
,
1091 const_string_type_node
,
1092 tree_cons (NULLT
, void_type_node
, NULLT
)));
1095 = builtin_function (TAG_GETCLASS
, temp_type
, NOT_BUILT_IN
, 0);
1097 /* id objc_getMetaClass (const char *); */
1099 objc_get_meta_class_decl
1100 = builtin_function (TAG_GETMETACLASS
, temp_type
, NOT_BUILT_IN
, 0);
1102 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1104 if (! flag_next_runtime
)
1106 if (flag_typed_selectors
)
1108 /* supress outputting debug symbols, because
1109 dbxout_init hasn'r been called yet... */
1110 enum debug_info_type save_write_symbols
= write_symbols
;
1111 write_symbols
= NO_DEBUG
;
1113 build_selector_template ();
1114 temp_type
= build_array_type (objc_selector_template
, NULLT
);
1116 write_symbols
= save_write_symbols
;
1119 temp_type
= build_array_type (selector_type
, NULLT
);
1121 layout_type (temp_type
);
1122 UOBJC_SELECTOR_TABLE_decl
1123 = create_builtin_decl (VAR_DECL
, temp_type
,
1124 "_OBJC_SELECTOR_TABLE");
1128 generate_forward_declaration_to_string_table ();
1130 /* Forward declare constant_string_id and constant_string_type. */
1131 constant_string_id
= get_identifier (STRING_OBJECT_CLASS_NAME
);
1132 constant_string_type
= xref_tag (RECORD_TYPE
, constant_string_id
);
1135 /* Custom build_string which sets TREE_TYPE! */
1138 my_build_string (len
, str
)
1143 tree a_string
= build_string (len
, str
);
1144 /* Some code from combine_strings, which is local to c-parse.y. */
1145 if (TREE_TYPE (a_string
) == int_array_type_node
)
1148 TREE_TYPE (a_string
) =
1149 build_array_type (wide_flag
? integer_type_node
: char_type_node
,
1150 build_index_type (build_int_2 (len
- 1, 0)));
1152 TREE_CONSTANT (a_string
) = 1; /* puts string in the ".text" segment */
1153 TREE_STATIC (a_string
) = 1;
1158 /* Return a newly constructed OBJC_STRING_CST node whose value is
1159 the LEN characters at STR.
1160 The TREE_TYPE is not initialized. */
1163 build_objc_string (len
, str
)
1167 tree s
= build_string (len
, str
);
1169 TREE_SET_CODE (s
, OBJC_STRING_CST
);
1173 /* Given a chain of OBJC_STRING_CST's, build a static instance of
1174 NXConstantString which points at the concatenation of those strings.
1175 We place the string object in the __string_objects section of the
1176 __OBJC segment. The Objective-C runtime will initialize the isa
1177 pointers of the string objects to point at the NXConstantString
1181 build_objc_string_object (strings
)
1184 tree string
, initlist
, constructor
;
1187 if (!doing_objc_thang
)
1190 if (lookup_interface (constant_string_id
) == NULLT
)
1192 error ("Cannot find interface declaration for `%s'",
1193 IDENTIFIER_POINTER (constant_string_id
));
1194 return error_mark_node
;
1197 add_class_reference (constant_string_id
);
1199 /* combine_strings will work for OBJC_STRING_CST's too. */
1200 string
= combine_strings (strings
);
1201 TREE_SET_CODE (string
, STRING_CST
);
1202 length
= TREE_STRING_LENGTH (string
) - 1;
1204 /* & ((NXConstantString) {0, string, length}) */
1206 initlist
= build_tree_list (NULLT
, build_int_2 (0, 0));
1207 initlist
= tree_cons (NULLT
, build_unary_op (ADDR_EXPR
, string
, 1),
1209 initlist
= tree_cons (NULLT
, build_int_2 (length
, 0), initlist
);
1210 constructor
= build_constructor (constant_string_type
,
1211 nreverse (initlist
));
1213 return build_unary_op (ADDR_EXPR
, constructor
, 1);
1216 /* Build a static constant CONSTRUCTOR
1217 with type TYPE and elements ELTS. */
1220 build_constructor (type
, elts
)
1223 tree constructor
= build (CONSTRUCTOR
, type
, NULL_TREE
, elts
);
1225 TREE_CONSTANT (constructor
) = 1;
1226 TREE_STATIC (constructor
) = 1;
1227 TREE_READONLY (constructor
) = 1;
1232 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1234 /* Predefine the following data type:
1242 void *defs[cls_def_cnt + cat_def_cnt];
1246 build_objc_symtab_template ()
1248 tree field_decl
, field_decl_chain
, index
;
1250 objc_symtab_template
= start_struct (RECORD_TYPE
, get_identifier (UTAG_SYMTAB
));
1252 /* long sel_ref_cnt; */
1254 field_decl
= create_builtin_decl (FIELD_DECL
,
1255 long_integer_type_node
,
1257 field_decl_chain
= field_decl
;
1261 field_decl
= create_builtin_decl (FIELD_DECL
,
1262 build_pointer_type (selector_type
),
1264 chainon (field_decl_chain
, field_decl
);
1266 /* short cls_def_cnt; */
1268 field_decl
= create_builtin_decl (FIELD_DECL
,
1269 short_integer_type_node
,
1271 chainon (field_decl_chain
, field_decl
);
1273 /* short cat_def_cnt; */
1275 field_decl
= create_builtin_decl (FIELD_DECL
,
1276 short_integer_type_node
,
1278 chainon (field_decl_chain
, field_decl
);
1280 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1282 index
= build_index_type (build_int_2 (imp_count
+ cat_count
- 1,
1283 imp_count
== 0 && cat_count
== 0
1285 field_decl
= create_builtin_decl (FIELD_DECL
,
1286 build_array_type (ptr_type_node
, index
),
1288 chainon (field_decl_chain
, field_decl
);
1290 finish_struct (objc_symtab_template
, field_decl_chain
);
1293 /* Create the initial value for the `defs' field of _objc_symtab.
1294 This is a CONSTRUCTOR. */
1297 init_def_list (type
)
1300 tree expr
, initlist
= NULLT
;
1301 struct imp_entry
*impent
;
1304 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1306 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
1308 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1309 initlist
= tree_cons (NULLT
, expr
, initlist
);
1314 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1316 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1318 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1319 initlist
= tree_cons (NULLT
, expr
, initlist
);
1322 return build_constructor (type
, nreverse (initlist
));
1325 /* Construct the initial value for all of _objc_symtab. */
1328 init_objc_symtab (type
)
1333 /* sel_ref_cnt = { ..., 5, ... } */
1335 initlist
= build_tree_list (NULLT
, build_int_2 (0, 0));
1337 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1339 if (flag_next_runtime
|| ! sel_ref_chain
)
1340 initlist
= tree_cons (NULLT
, build_int_2 (0, 0), initlist
);
1342 initlist
= tree_cons (NULLT
,
1343 build_unary_op (ADDR_EXPR
,
1344 UOBJC_SELECTOR_TABLE_decl
, 1),
1347 /* cls_def_cnt = { ..., 5, ... } */
1349 initlist
= tree_cons (NULLT
, build_int_2 (imp_count
, 0), initlist
);
1351 /* cat_def_cnt = { ..., 5, ... } */
1353 initlist
= tree_cons (NULLT
, build_int_2 (cat_count
, 0), initlist
);
1355 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1357 if (imp_count
|| cat_count
)
1359 tree field
= TYPE_FIELDS (type
);
1360 field
= TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field
))));
1362 initlist
= tree_cons (NULLT
, init_def_list (TREE_TYPE (field
)),
1366 return build_constructor (type
, nreverse (initlist
));
1369 /* Push forward-declarations of all the categories
1370 so that init_def_list can use them in a CONSTRUCTOR. */
1373 forward_declare_categories ()
1375 struct imp_entry
*impent
;
1376 tree sav
= implementation_context
;
1377 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1379 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1381 /* Set an invisible arg to synth_id_with_class_suffix. */
1382 implementation_context
= impent
->imp_context
;
1384 = create_builtin_decl (VAR_DECL
, objc_category_template
,
1385 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", implementation_context
)));
1388 implementation_context
= sav
;
1391 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1392 and initialized appropriately. */
1395 generate_objc_symtab_decl ()
1399 if (!objc_category_template
)
1400 build_category_template ();
1402 /* forward declare categories */
1404 forward_declare_categories ();
1406 if (!objc_symtab_template
)
1407 build_objc_symtab_template ();
1409 sc_spec
= build_tree_list (NULLT
, ridpointers
[(int) RID_STATIC
]);
1411 UOBJC_SYMBOLS_decl
= start_decl (get_identifier ("_OBJC_SYMBOLS"),
1412 tree_cons (NULLT
, objc_symtab_template
, sc_spec
), 1);
1414 end_temporary_allocation (); /* start_decl trying to be smart about inits */
1415 TREE_USED (UOBJC_SYMBOLS_decl
) = 1;
1416 DECL_IGNORED_P (UOBJC_SYMBOLS_decl
) = 1;
1417 finish_decl (UOBJC_SYMBOLS_decl
,
1418 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)),
1423 init_module_descriptor (type
)
1426 tree initlist
, expr
;
1428 /* version = { 1, ... } */
1430 expr
= build_int_2 (OBJC_VERSION
, 0);
1431 initlist
= build_tree_list (NULLT
, expr
);
1433 /* size = { ..., sizeof (struct objc_module), ... } */
1435 expr
= size_in_bytes (objc_module_template
);
1436 initlist
= tree_cons (NULLT
, expr
, initlist
);
1438 /* name = { ..., "foo.m", ... } */
1440 expr
= add_objc_string (get_identifier (input_filename
), class_names
);
1441 initlist
= tree_cons (NULLT
, expr
, initlist
);
1443 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1445 if (UOBJC_SYMBOLS_decl
)
1446 expr
= build_unary_op (ADDR_EXPR
, UOBJC_SYMBOLS_decl
, 0);
1448 expr
= build_int_2 (0, 0);
1449 initlist
= tree_cons (NULLT
, expr
, initlist
);
1451 return build_constructor (type
, nreverse (initlist
));
1454 /* Write out the data structures to describe Objective C classes defined.
1455 If appropriate, compile and output a setup function to initialize them.
1456 Return a string which is the name of a function to call to initialize
1457 the Objective C data structures for this file (and perhaps for other files
1460 struct objc_module { ... } _OBJC_MODULE = { ... };
1465 build_module_descriptor ()
1467 tree decl_specs
, field_decl
, field_decl_chain
;
1469 objc_module_template
= start_struct (RECORD_TYPE
, get_identifier (UTAG_MODULE
));
1473 decl_specs
= build_tree_list (NULLT
, ridpointers
[(int) RID_LONG
]);
1474 field_decl
= get_identifier ("version");
1475 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
1476 field_decl_chain
= field_decl
;
1480 decl_specs
= build_tree_list (NULLT
, ridpointers
[(int) RID_LONG
]);
1481 field_decl
= get_identifier ("size");
1482 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
1483 chainon (field_decl_chain
, field_decl
);
1487 decl_specs
= build_tree_list (NULLT
, ridpointers
[(int) RID_CHAR
]);
1488 field_decl
= build1 (INDIRECT_REF
, NULLT
, get_identifier ("name"));
1489 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
1490 chainon (field_decl_chain
, field_decl
);
1492 /* struct objc_symtab *symtab; */
1494 decl_specs
= get_identifier (UTAG_SYMTAB
);
1495 decl_specs
= build_tree_list (NULLT
, xref_tag (RECORD_TYPE
, decl_specs
));
1496 field_decl
= build1 (INDIRECT_REF
, NULLT
, get_identifier ("symtab"));
1497 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
1498 chainon (field_decl_chain
, field_decl
);
1500 finish_struct (objc_module_template
, field_decl_chain
);
1502 /* create an instance of "objc_module" */
1504 decl_specs
= tree_cons (NULLT
, objc_module_template
,
1505 build_tree_list (NULLT
, ridpointers
[(int) RID_STATIC
]));
1507 UOBJC_MODULES_decl
= start_decl (get_identifier ("_OBJC_MODULES"),
1510 end_temporary_allocation (); /* start_decl trying to be smart about inits */
1511 DECL_IGNORED_P (UOBJC_MODULES_decl
) = 1;
1512 finish_decl (UOBJC_MODULES_decl
,
1513 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl
)),
1516 /* Mark the decl to avoid "defined but not used" warning. */
1517 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl
) = 1;
1519 /* Generate a constructor call for the module descriptor.
1520 This code was generated by reading the grammar rules
1521 of c-parse.y; Therefore, it may not be the most efficient
1522 way of generating the requisite code. */
1524 if (flag_next_runtime
)
1528 tree parms
, function_decl
, decelerator
, void_list_node
;
1530 extern tree
get_file_function_name ();
1531 tree init_function_name
= get_file_function_name ('I');
1533 /* Declare void __objc_execClass (void*); */
1535 void_list_node
= build_tree_list (NULL_TREE
, void_type_node
);
1537 = build_function_type (void_type_node
,
1538 tree_cons (NULL_TREE
, ptr_type_node
,
1540 function_decl
= build_decl (FUNCTION_DECL
,
1541 get_identifier (TAG_EXECCLASS
),
1543 DECL_EXTERNAL (function_decl
) = 1;
1544 TREE_PUBLIC (function_decl
) = 1;
1546 pushdecl (function_decl
);
1547 rest_of_decl_compilation (function_decl
, 0, 0, 0);
1550 = build_tree_list (NULLT
,
1551 build_unary_op (ADDR_EXPR
, UOBJC_MODULES_decl
, 0));
1552 decelerator
= build_function_call (function_decl
, parms
);
1554 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1556 start_function (void_list_node
,
1557 build_parse_node (CALL_EXPR
, init_function_name
,
1558 /* This has the format of the output
1559 of get_parm_info. */
1560 tree_cons (NULL_TREE
, NULL_TREE
,
1564 #if 0 /* This should be turned back on later
1565 for the systems where collect is not needed. */
1566 /* Make these functions nonglobal
1567 so each file can use the same name. */
1568 TREE_PUBLIC (current_function_decl
) = 0;
1570 TREE_USED (current_function_decl
) = 1;
1571 store_parm_decls ();
1573 assemble_external (function_decl
);
1574 c_expand_expr_stmt (decelerator
);
1576 TREE_PUBLIC (current_function_decl
) = 1;
1578 function_decl
= current_function_decl
;
1579 finish_function (0);
1581 /* Return the name of the constructor function. */
1582 return XSTR (XEXP (DECL_RTL (function_decl
), 0), 0);
1586 /* extern const char _OBJC_STRINGS[]; */
1589 generate_forward_declaration_to_string_table ()
1591 tree sc_spec
, decl_specs
, expr_decl
;
1593 sc_spec
= tree_cons (NULLT
, ridpointers
[(int) RID_EXTERN
], NULLT
);
1594 decl_specs
= tree_cons (NULLT
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1596 expr_decl
= build_nt (ARRAY_REF
, get_identifier ("_OBJC_STRINGS"), NULLT
);
1598 UOBJC_STRINGS_decl
= define_decl (expr_decl
, decl_specs
);
1601 /* Output all strings. */
1606 tree sc_spec
, decl_specs
, expr_decl
;
1607 tree chain
, string_expr
;
1610 for (chain
= class_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1612 string
= TREE_VALUE (chain
);
1613 decl
= TREE_PURPOSE (chain
);
1614 sc_spec
= tree_cons (NULLT
, ridpointers
[(int) RID_STATIC
], NULLT
);
1615 decl_specs
= tree_cons (NULLT
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1616 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULLT
);
1617 decl
= start_decl (expr_decl
, decl_specs
, 1);
1618 end_temporary_allocation ();
1619 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1620 IDENTIFIER_POINTER (string
));
1621 finish_decl (decl
, string_expr
, NULLT
);
1624 for (chain
= meth_var_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1626 string
= TREE_VALUE (chain
);
1627 decl
= TREE_PURPOSE (chain
);
1628 sc_spec
= tree_cons (NULLT
, ridpointers
[(int) RID_STATIC
], NULLT
);
1629 decl_specs
= tree_cons (NULLT
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1630 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULLT
);
1631 decl
= start_decl (expr_decl
, decl_specs
, 1);
1632 end_temporary_allocation ();
1633 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1634 IDENTIFIER_POINTER (string
));
1635 finish_decl (decl
, string_expr
, NULLT
);
1638 for (chain
= meth_var_types_chain
; chain
; chain
= TREE_CHAIN (chain
))
1640 string
= TREE_VALUE (chain
);
1641 decl
= TREE_PURPOSE (chain
);
1642 sc_spec
= tree_cons (NULLT
, ridpointers
[(int) RID_STATIC
], NULLT
);
1643 decl_specs
= tree_cons (NULLT
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1644 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULLT
);
1645 decl
= start_decl (expr_decl
, decl_specs
, 1);
1646 end_temporary_allocation ();
1647 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1648 IDENTIFIER_POINTER (string
));
1649 finish_decl (decl
, string_expr
, NULLT
);
1654 build_selector_reference_decl (name
)
1659 struct obstack
*save_current_obstack
= current_obstack
;
1660 struct obstack
*save_rtl_obstack
= rtl_obstack
;
1663 sprintf (buf
, "_OBJC_SELECTOR_REFERENCES_%d", idx
++);
1666 rtl_obstack
= current_obstack
= &permanent_obstack
;
1667 ident
= get_identifier (buf
);
1669 decl
= build_decl (VAR_DECL
, ident
, selector_type
);
1670 DECL_EXTERNAL (decl
) = 1;
1671 TREE_PUBLIC (decl
) = 1;
1672 TREE_USED (decl
) = 1;
1673 TREE_READONLY (decl
) = 1;
1675 make_decl_rtl (decl
, 0, 1); /* usually called from `rest_of_decl_compilation' */
1676 pushdecl_top_level (decl
); /* our `extended/custom' pushdecl in c-decl.c */
1678 current_obstack
= save_current_obstack
;
1679 rtl_obstack
= save_rtl_obstack
;
1684 /* Just a handy wrapper for add_objc_string. */
1687 build_selector (ident
)
1690 tree expr
= add_objc_string (ident
, meth_var_names
);
1691 if (flag_typed_selectors
)
1694 return build_c_cast (selector_type
, expr
); /* cast! */
1697 /* Synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>]
1698 The cast stops the compiler from issuing the following message:
1699 grok.m: warning: initialization of non-const * pointer from const *
1700 grok.m: warning: initialization between incompatible pointer types. */
1703 build_msg_pool_reference (offset
)
1706 tree expr
= build_int_2 (offset
, 0);
1709 expr
= build_array_ref (UOBJC_STRINGS_decl
, expr
);
1710 expr
= build_unary_op (ADDR_EXPR
, expr
, 0);
1712 cast
= build_tree_list (build_tree_list (NULLT
, ridpointers
[(int) RID_CHAR
]),
1713 build1 (INDIRECT_REF
, NULLT
, NULLT
));
1714 TREE_TYPE (expr
) = groktypename (cast
);
1719 init_selector (offset
)
1722 tree expr
= build_msg_pool_reference (offset
);
1723 TREE_TYPE (expr
) = selector_type
; /* cast */
1728 build_selector_translation_table ()
1730 tree sc_spec
, decl_specs
;
1731 tree chain
, initlist
= NULLT
;
1733 tree decl
, var_decl
, name
;
1735 /* The corresponding pop_obstacks is in finish_decl,
1736 called at the end of this function. */
1737 if (! flag_next_runtime
)
1738 push_obstacks_nochange ();
1740 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
1744 expr
= build_selector (TREE_VALUE (chain
));
1746 if (flag_next_runtime
)
1748 name
= DECL_NAME (TREE_PURPOSE (chain
));
1750 sc_spec
= build_tree_list (NULLT
, ridpointers
[(int) RID_STATIC
]);
1752 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
1753 decl_specs
= tree_cons (NULLT
, selector_type
, sc_spec
);
1757 /* the `decl' that is returned from start_decl is the one that we
1758 forward declared in `build_selector_reference' */
1759 decl
= start_decl (var_decl
, decl_specs
, 1);
1762 /* add one for the '\0' character */
1763 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (chain
)) + 1;
1765 if (flag_next_runtime
)
1767 end_temporary_allocation ();
1768 finish_decl (decl
, expr
, NULLT
);
1772 if (flag_typed_selectors
)
1774 tree eltlist
= NULLT
;
1775 tree encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
1776 eltlist
= tree_cons (NULLT
, expr
, NULLT
);
1777 eltlist
= tree_cons (NULLT
, encoding
, eltlist
);
1778 expr
= build_constructor (objc_selector_template
,
1779 nreverse (eltlist
));
1781 initlist
= tree_cons (NULLT
, expr
, initlist
);
1786 if (! flag_next_runtime
)
1788 /* Cause the variable and its initial value to be actually output. */
1789 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl
) = 0;
1790 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl
) = 1;
1791 /* NULL terminate the list and fix the decl for output. */
1792 initlist
= tree_cons (NULLT
, build_int_2 (0, 0), initlist
);
1793 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl
) = (tree
) 1;
1794 initlist
= build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
1795 nreverse (initlist
));
1796 finish_decl (UOBJC_SELECTOR_TABLE_decl
, initlist
, NULLT
);
1797 current_function_decl
= NULLT
;
1803 get_proto_encoding (proto
)
1811 if (! METHOD_ENCODING (proto
))
1813 tmp_decl
= build_tmp_function_decl ();
1814 hack_method_prototype (proto
, tmp_decl
);
1815 encoding
= encode_method_prototype (proto
, tmp_decl
);
1816 METHOD_ENCODING (proto
) = encoding
;
1819 encoding
= METHOD_ENCODING (proto
);
1821 return add_objc_string (encoding
, meth_var_types
);
1824 return build_int_2 (0, 0);
1827 /* sel_ref_chain is a list whose "value" fields will be instances of
1828 identifier_node that represent the selector. */
1831 build_typed_selector_reference (ident
, proto
)
1834 tree
*chain
= &sel_ref_chain
;
1840 if (TREE_PURPOSE (*chain
) == ident
&& TREE_VALUE (*chain
) == proto
)
1841 goto return_at_index
;
1843 chain
= &TREE_CHAIN (*chain
);
1846 *chain
= perm_tree_cons (proto
, ident
, NULLT
);
1849 expr
= build_unary_op (ADDR_EXPR
,
1850 build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
1851 build_int_2 (index
, 0)),
1853 return build_c_cast (selector_type
, expr
);
1857 build_selector_reference (ident
)
1860 tree
*chain
= &sel_ref_chain
;
1866 if (TREE_VALUE (*chain
) == ident
)
1867 return (flag_next_runtime
1868 ? TREE_PURPOSE (*chain
)
1869 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
1870 build_int_2 (index
, 0)));
1873 chain
= &TREE_CHAIN (*chain
);
1876 expr
= build_selector_reference_decl (ident
);
1878 *chain
= perm_tree_cons (expr
, ident
, NULLT
);
1880 return (flag_next_runtime
1882 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
1883 build_int_2 (index
, 0)));
1887 build_class_reference_decl (name
)
1892 struct obstack
*save_current_obstack
= current_obstack
;
1893 struct obstack
*save_rtl_obstack
= rtl_obstack
;
1896 sprintf (buf
, "_OBJC_CLASS_REFERENCES_%d", idx
++);
1899 rtl_obstack
= current_obstack
= &permanent_obstack
;
1900 ident
= get_identifier (buf
);
1902 decl
= build_decl (VAR_DECL
, ident
, objc_class_type
);
1903 DECL_EXTERNAL (decl
) = 1;
1904 TREE_PUBLIC (decl
) = 1;
1905 TREE_USED (decl
) = 1;
1906 TREE_READONLY (decl
) = 1;
1908 make_decl_rtl (decl
, 0, 1); /* usually called from `rest_of_decl_compilation' */
1909 pushdecl_top_level (decl
); /* our `extended/custom' pushdecl in c-decl.c */
1911 current_obstack
= save_current_obstack
;
1912 rtl_obstack
= save_rtl_obstack
;
1917 /* Create a class reference, but don't create a variable to reference
1921 add_class_reference (ident
)
1926 if ((chain
= cls_ref_chain
))
1931 if (ident
== TREE_VALUE (chain
))
1935 chain
= TREE_CHAIN (chain
);
1939 /* append to the end of the list */
1940 TREE_CHAIN (tail
) = perm_tree_cons (NULLT
, ident
, NULLT
);
1943 cls_ref_chain
= perm_tree_cons (NULLT
, ident
, NULLT
);
1946 /* Get a class reference, creating it if necessary. Also create the
1947 reference variable. */
1950 get_class_reference (ident
)
1953 if (flag_next_runtime
)
1958 for (chain
= &cls_ref_chain
; *chain
; chain
= &TREE_CHAIN (*chain
))
1959 if (TREE_VALUE (*chain
) == ident
)
1961 if (! TREE_PURPOSE (*chain
))
1962 TREE_PURPOSE (*chain
) = build_class_reference_decl (ident
);
1963 return TREE_PURPOSE (*chain
);
1966 decl
= build_class_reference_decl (ident
);
1967 *chain
= perm_tree_cons (decl
, ident
, NULLT
);
1974 add_class_reference (ident
);
1976 params
= build_tree_list (NULLT
,
1977 my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
1978 IDENTIFIER_POINTER (ident
)));
1980 assemble_external (objc_get_class_decl
);
1981 return build_function_call (objc_get_class_decl
, params
);
1985 /* sel_refdef_chain is a list whose "value" fields will be instances
1986 of identifier_node that represent the selector. It returns the
1987 offset of the selector from the beginning of the _OBJC_STRINGS
1988 pool. This offset is typically used by init_selector during code
1991 For each string section we have a chain which maps identifier nodes
1992 to decls for the strings. */
1995 add_objc_string (ident
, section
)
1997 enum string_section section
;
2001 if (section
== class_names
)
2002 chain
= &class_names_chain
;
2003 else if (section
== meth_var_names
)
2004 chain
= &meth_var_names_chain
;
2005 else if (section
== meth_var_types
)
2006 chain
= &meth_var_types_chain
;
2010 if (TREE_VALUE (*chain
) == ident
)
2011 return build_unary_op (ADDR_EXPR
, TREE_PURPOSE (*chain
), 1);
2013 chain
= &TREE_CHAIN (*chain
);
2016 decl
= build_objc_string_decl (ident
, section
);
2018 *chain
= perm_tree_cons (decl
, ident
, NULLT
);
2020 return build_unary_op (ADDR_EXPR
, decl
, 1);
2024 build_objc_string_decl (name
, section
)
2026 enum string_section section
;
2030 struct obstack
*save_current_obstack
= current_obstack
;
2031 struct obstack
*save_rtl_obstack
= rtl_obstack
;
2032 static int class_names_idx
= 0;
2033 static int meth_var_names_idx
= 0;
2034 static int meth_var_types_idx
= 0;
2036 if (section
== class_names
)
2037 sprintf (buf
, "_OBJC_CLASS_NAME_%d", class_names_idx
++);
2038 else if (section
== meth_var_names
)
2039 sprintf (buf
, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx
++);
2040 else if (section
== meth_var_types
)
2041 sprintf (buf
, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx
++);
2043 rtl_obstack
= current_obstack
= &permanent_obstack
;
2044 ident
= get_identifier (buf
);
2046 decl
= build_decl (VAR_DECL
, ident
, build_array_type (char_type_node
, 0));
2047 DECL_EXTERNAL (decl
) = 1;
2048 TREE_PUBLIC (decl
) = 1;
2049 TREE_USED (decl
) = 1;
2050 TREE_READONLY (decl
) = 1;
2051 TREE_CONSTANT (decl
) = 1;
2053 make_decl_rtl (decl
, 0, 1); /* usually called from `rest_of_decl_compilation */
2054 pushdecl_top_level (decl
); /* our `extended/custom' pushdecl in c-decl.c */
2056 current_obstack
= save_current_obstack
;
2057 rtl_obstack
= save_rtl_obstack
;
2064 objc_declare_alias (alias_ident
, class_ident
)
2068 if (!doing_objc_thang
)
2071 if (is_class_name (class_ident
) != class_ident
)
2072 warning ("Cannot find class `%s'", IDENTIFIER_POINTER (class_ident
));
2073 else if (is_class_name (alias_ident
))
2074 warning ("Class `%s' already exists", IDENTIFIER_POINTER (alias_ident
));
2076 alias_chain
= tree_cons (class_ident
, alias_ident
, alias_chain
);
2080 objc_declare_class (ident_list
)
2085 if (!doing_objc_thang
)
2088 for (list
= ident_list
; list
; list
= TREE_CHAIN (list
))
2090 tree ident
= TREE_VALUE (list
);
2093 if ((decl
= lookup_name (ident
)))
2095 error ("`%s' redeclared as different kind of symbol",
2096 IDENTIFIER_POINTER (ident
));
2097 error_with_decl (decl
, "previous declaration of `%s'");
2100 if (! is_class_name (ident
))
2102 tree record
= xref_tag (RECORD_TYPE
, ident
);
2103 TREE_STATIC_TEMPLATE (record
) = 1;
2104 class_chain
= tree_cons (NULLT
, ident
, class_chain
);
2110 is_class_name (ident
)
2115 if (lookup_interface (ident
))
2118 for (chain
= class_chain
; chain
; chain
= TREE_CHAIN (chain
))
2120 if (ident
== TREE_VALUE (chain
))
2124 for (chain
= alias_chain
; chain
; chain
= TREE_CHAIN (chain
))
2126 if (ident
== TREE_VALUE (chain
))
2127 return TREE_PURPOSE (chain
);
2134 lookup_interface (ident
)
2139 for (chain
= interface_chain
; chain
; chain
= TREE_CHAIN (chain
))
2141 if (ident
== CLASS_NAME (chain
))
2148 objc_copy_list (list
, head
)
2152 tree newlist
= NULL_TREE
, tail
= NULL_TREE
;
2156 tail
= copy_node (list
);
2158 /* The following statement fixes a bug when inheriting instance
2159 variables that are declared to be bitfields. finish_struct
2160 expects to find the width of the bitfield in DECL_INITIAL,
2161 which it nulls out after processing the decl of the super
2162 class...rather than change the way finish_struct works (which
2163 is risky), I create the situation it expects...s.naroff
2166 if (DECL_BIT_FIELD (tail
) && DECL_INITIAL (tail
) == 0)
2167 DECL_INITIAL (tail
) = build_int_2 (DECL_FIELD_SIZE (tail
), 0);
2169 newlist
= chainon (newlist
, tail
);
2170 list
= TREE_CHAIN (list
);
2176 /* Used by: build_private_template, get_class_ivars, and
2177 continue_class. COPY is 1 when called from @defs. In this case
2178 copy all fields. Otherwise don't copy leaf ivars since we rely on
2179 them being side-effected exactly once by finish_struct. */
2182 build_ivar_chain (interface
, copy
)
2186 tree my_name
, super_name
, ivar_chain
;
2188 my_name
= CLASS_NAME (interface
);
2189 super_name
= CLASS_SUPER_NAME (interface
);
2191 /* Possibly copy leaf ivars. */
2193 objc_copy_list (CLASS_IVARS (interface
), &ivar_chain
);
2195 ivar_chain
= CLASS_IVARS (interface
);
2200 tree super_interface
= lookup_interface (super_name
);
2202 if (!super_interface
)
2204 /* fatal did not work with 2 args...should fix */
2205 error ("Cannot find interface declaration for `%s', superclass of `%s'",
2206 IDENTIFIER_POINTER (super_name
),
2207 IDENTIFIER_POINTER (my_name
));
2210 if (super_interface
== interface
)
2212 fatal ("Circular inheritance in interface declaration for `%s'",
2213 IDENTIFIER_POINTER (super_name
));
2215 interface
= super_interface
;
2216 my_name
= CLASS_NAME (interface
);
2217 super_name
= CLASS_SUPER_NAME (interface
);
2219 op1
= CLASS_IVARS (interface
);
2222 tree head
, tail
= objc_copy_list (op1
, &head
);
2224 /* Prepend super class ivars...make a copy of the list, we
2225 do not want to alter the original. */
2226 TREE_CHAIN (tail
) = ivar_chain
;
2233 /* struct <classname> {
2234 struct objc_class *isa;
2239 build_private_template (class)
2244 if (CLASS_STATIC_TEMPLATE (class))
2246 uprivate_record
= CLASS_STATIC_TEMPLATE (class);
2247 ivar_context
= TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2251 uprivate_record
= start_struct (RECORD_TYPE
, CLASS_NAME (class));
2253 ivar_context
= build_ivar_chain (class, 0);
2255 finish_struct (uprivate_record
, ivar_context
);
2257 CLASS_STATIC_TEMPLATE (class) = uprivate_record
;
2259 /* mark this record as class template - for class type checking */
2260 TREE_STATIC_TEMPLATE (uprivate_record
) = 1;
2262 instance_type
= groktypename (build_tree_list (build_tree_list (NULLT
, uprivate_record
),
2263 build1 (INDIRECT_REF
, NULLT
, NULLT
)));
2264 return ivar_context
;
2267 /* Begin code generation for protocols... */
2269 /* struct objc_protocol {
2270 char *protocol_name;
2271 struct objc_protocol **protocol_list;
2272 struct objc_method_desc *instance_methods;
2273 struct objc_method_desc *class_methods;
2277 build_protocol_template ()
2279 tree decl_specs
, field_decl
, field_decl_chain
;
2282 template = start_struct (RECORD_TYPE
, get_identifier (UTAG_PROTOCOL
));
2284 /* struct objc_class *isa; */
2286 decl_specs
= build_tree_list (NULLT
, xref_tag (RECORD_TYPE
,
2287 get_identifier (UTAG_CLASS
)));
2288 field_decl
= build1 (INDIRECT_REF
, NULLT
, get_identifier ("isa"));
2289 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
2290 field_decl_chain
= field_decl
;
2292 /* char *protocol_name; */
2294 decl_specs
= build_tree_list (NULLT
, ridpointers
[(int) RID_CHAR
]);
2295 field_decl
= build1 (INDIRECT_REF
, NULLT
, get_identifier ("protocol_name"));
2296 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
2297 chainon (field_decl_chain
, field_decl
);
2299 /* struct objc_protocol **protocol_list; */
2301 decl_specs
= build_tree_list (NULLT
, template);
2302 field_decl
= build1 (INDIRECT_REF
, NULLT
, get_identifier ("protocol_list"));
2303 field_decl
= build1 (INDIRECT_REF
, NULLT
, field_decl
);
2304 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
2305 chainon (field_decl_chain
, field_decl
);
2307 /* struct objc_method_list *instance_methods; */
2309 decl_specs
= build_tree_list (NULLT
, xref_tag (RECORD_TYPE
,
2310 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2311 field_decl
= build1 (INDIRECT_REF
, NULLT
, get_identifier ("instance_methods"));
2312 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
2313 chainon (field_decl_chain
, field_decl
);
2315 /* struct objc_method_list *class_methods; */
2317 decl_specs
= build_tree_list (NULLT
, xref_tag (RECORD_TYPE
,
2318 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2319 field_decl
= build1 (INDIRECT_REF
, NULLT
, get_identifier ("class_methods"));
2320 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
2321 chainon (field_decl_chain
, field_decl
);
2323 return finish_struct (template, field_decl_chain
);
2327 build_descriptor_table_initializer (type
, entries
)
2331 tree initlist
= NULLT
;
2335 tree eltlist
= NULLT
;
2337 eltlist
= tree_cons (NULLT
, build_selector (METHOD_SEL_NAME (entries
)), NULLT
);
2338 eltlist
= tree_cons (NULLT
, add_objc_string (METHOD_ENCODING (entries
), meth_var_types
), eltlist
);
2340 initlist
= tree_cons (NULLT
, build_constructor (type
, nreverse (eltlist
)), initlist
);
2342 entries
= TREE_CHAIN (entries
);
2346 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
2349 /* struct objc_method_prototype_list {
2351 struct objc_method_prototype {
2358 build_method_prototype_list_template (list_type
, size
)
2362 tree objc_ivar_list_record
;
2363 tree decl_specs
, field_decl
, field_decl_chain
;
2365 /* generate an unnamed struct definition */
2367 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULLT
);
2369 /* int method_count; */
2371 decl_specs
= build_tree_list (NULLT
, ridpointers
[(int) RID_INT
]);
2372 field_decl
= get_identifier ("method_count");
2374 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
2375 field_decl_chain
= field_decl
;
2377 /* struct objc_method method_list[]; */
2379 decl_specs
= build_tree_list (NULLT
, list_type
);
2380 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
2381 build_int_2 (size
, 0));
2383 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
2384 chainon (field_decl_chain
, field_decl
);
2386 finish_struct (objc_ivar_list_record
, field_decl_chain
);
2388 return objc_ivar_list_record
;
2392 build_method_prototype_template ()
2395 tree decl_specs
, field_decl
, field_decl_chain
;
2397 proto_record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD_PROTOTYPE
));
2399 #ifdef OBJC_INT_SELECTORS
2400 /* unsigned int _cmd; */
2401 decl_specs
= tree_cons (NULLT
, ridpointers
[(int) RID_UNSIGNED
], NULLT
);
2402 decl_specs
= tree_cons (NULLT
, ridpointers
[(int) RID_INT
], decl_specs
);
2403 field_decl
= get_identifier ("_cmd");
2404 #else /* OBJC_INT_SELECTORS */
2405 /* struct objc_selector *_cmd; */
2406 decl_specs
= tree_cons (NULLT
, xref_tag (RECORD_TYPE
,
2407 get_identifier (TAG_SELECTOR
)), NULLT
);
2408 field_decl
= build1 (INDIRECT_REF
, NULLT
, get_identifier ("_cmd"));
2409 #endif /* OBJC_INT_SELECTORS */
2411 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
2412 field_decl_chain
= field_decl
;
2414 decl_specs
= tree_cons (NULLT
, ridpointers
[(int) RID_CHAR
], NULLT
);
2415 field_decl
= build1 (INDIRECT_REF
, NULLT
, get_identifier ("method_types"));
2416 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
2417 chainon (field_decl_chain
, field_decl
);
2419 finish_struct (proto_record
, field_decl_chain
);
2421 return proto_record
;
2424 /* True if last call to forwarding_offset yielded a register offset */
2425 static int offset_is_register
;
2428 forwarding_offset (parm
)
2431 int offset_in_bytes
;
2433 if (GET_CODE (DECL_INCOMING_RTL (parm
)) == MEM
)
2435 rtx addr
= XEXP (DECL_INCOMING_RTL (parm
), 0);
2437 /* ??? Here we assume that the parm address is indexed
2438 off the frame pointer or arg pointer.
2439 If that is not true, we produce meaningless results,
2440 but do not crash. */
2441 if (GET_CODE (addr
) == PLUS
2442 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
2443 offset_in_bytes
= INTVAL (XEXP (addr
, 1));
2445 offset_in_bytes
= 0;
2447 offset_in_bytes
+= OBJC_FORWARDING_STACK_OFFSET
;
2448 offset_is_register
= 0;
2450 else if (GET_CODE (DECL_INCOMING_RTL (parm
)) == REG
)
2452 int regno
= REGNO (DECL_INCOMING_RTL (parm
));
2453 offset_in_bytes
= apply_args_register_offset (regno
);
2454 offset_is_register
= 1;
2459 /* This is the case where the parm is passed as an int or double
2460 and it is converted to a char, short or float and stored back
2461 in the parmlist. In this case, describe the parm
2462 with the variable's declared type, and adjust the address
2463 if the least significant bytes (which we are using) are not
2465 if (BYTES_BIG_ENDIAN
&& TREE_TYPE (parm
) != DECL_ARG_TYPE (parm
))
2466 offset_in_bytes
+= (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm
)))
2467 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm
))));
2469 return offset_in_bytes
;
2473 encode_method_prototype (method_decl
, func_decl
)
2480 int max_parm_end
= 0;
2484 /* `oneway' and 'bycopy', for remote object are the only method qualifiers */
2485 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl
)));
2488 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
2489 obstack_object_size (&util_obstack
),
2490 OBJC_ENCODE_INLINE_DEFS
);
2493 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
2494 parms
= TREE_CHAIN (parms
))
2496 int parm_end
= (forwarding_offset (parms
)
2497 + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms
)))
2500 if (!offset_is_register
&& max_parm_end
< parm_end
)
2501 max_parm_end
= parm_end
;
2504 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
2506 sprintf (buf
, "%d", stack_size
);
2507 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2509 user_args
= METHOD_SEL_ARGS (method_decl
);
2511 /* argument types */
2512 for (parms
= DECL_ARGUMENTS (func_decl
), i
= 0; parms
;
2513 parms
= TREE_CHAIN (parms
), i
++)
2515 /* process argument qualifiers for user supplied arguments */
2518 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args
)));
2519 user_args
= TREE_CHAIN (user_args
);
2523 encode_type (TREE_TYPE (parms
),
2524 obstack_object_size (&util_obstack
),
2525 OBJC_ENCODE_INLINE_DEFS
);
2527 /* compute offset */
2528 sprintf (buf
, "%d", forwarding_offset (parms
));
2530 /* indicate register */
2531 if (offset_is_register
)
2532 obstack_1grow (&util_obstack
, '+');
2534 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2537 obstack_1grow (&util_obstack
, '\0');
2538 result
= get_identifier (obstack_finish (&util_obstack
));
2539 obstack_free (&util_obstack
, util_firstobj
);
2544 generate_descriptor_table (type
, name
, size
, list
, proto
)
2551 tree sc_spec
, decl_specs
, decl
, initlist
;
2553 sc_spec
= tree_cons (NULLT
, ridpointers
[(int) RID_STATIC
], NULLT
);
2554 decl_specs
= tree_cons (NULLT
, type
, sc_spec
);
2556 decl
= start_decl (synth_id_with_class_suffix (name
, proto
),
2558 end_temporary_allocation ();
2560 initlist
= build_tree_list (NULLT
, build_int_2 (size
, 0));
2561 initlist
= tree_cons (NULLT
, list
, initlist
);
2563 finish_decl (decl
, build_constructor (type
, nreverse (initlist
)),
2570 generate_method_descriptors (protocol
) /* generate_dispatch_tables */
2573 static tree objc_method_prototype_template
;
2574 tree initlist
, chain
, method_list_template
;
2575 tree cast
, variable_length_type
;
2578 if (!objc_method_prototype_template
)
2579 objc_method_prototype_template
= build_method_prototype_template ();
2581 cast
= build_tree_list (build_tree_list (NULLT
, xref_tag (RECORD_TYPE
,
2582 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
))), NULLT
);
2583 variable_length_type
= groktypename (cast
);
2585 chain
= PROTOCOL_CLS_METHODS (protocol
);
2588 size
= list_length (chain
);
2590 method_list_template
2591 = build_method_prototype_list_template (objc_method_prototype_template
,
2595 = build_descriptor_table_initializer (objc_method_prototype_template
,
2598 UOBJC_CLASS_METHODS_decl
2599 = generate_descriptor_table (method_list_template
,
2600 "_OBJC_PROTOCOL_CLASS_METHODS",
2601 size
, initlist
, protocol
);
2603 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
2606 UOBJC_CLASS_METHODS_decl
= 0;
2608 chain
= PROTOCOL_NST_METHODS (protocol
);
2611 size
= list_length (chain
);
2613 method_list_template
2614 = build_method_prototype_list_template (objc_method_prototype_template
,
2617 = build_descriptor_table_initializer (objc_method_prototype_template
,
2620 UOBJC_INSTANCE_METHODS_decl
2621 = generate_descriptor_table (method_list_template
,
2622 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2623 size
, initlist
, protocol
);
2625 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
2628 UOBJC_INSTANCE_METHODS_decl
= 0;
2632 build_tmp_function_decl ()
2634 tree decl_specs
, expr_decl
, parms
;
2638 /* struct objc_object *objc_xxx (id, SEL, ...); */
2640 decl_specs
= build_tree_list (NULLT
, objc_object_reference
);
2641 push_parm_decl (build_tree_list (decl_specs
,
2642 build1 (INDIRECT_REF
, NULLT
, NULLT
)));
2644 decl_specs
= build_tree_list (NULLT
, xref_tag (RECORD_TYPE
,
2645 get_identifier (TAG_SELECTOR
)));
2646 expr_decl
= build1 (INDIRECT_REF
, NULLT
, NULLT
);
2648 push_parm_decl (build_tree_list (decl_specs
, expr_decl
));
2649 parms
= get_parm_info (0);
2652 decl_specs
= build_tree_list (NULLT
, objc_object_reference
);
2653 sprintf (buffer
, "__objc_tmp_%x", xxx
++);
2654 expr_decl
= build_nt (CALL_EXPR
, get_identifier (buffer
), parms
, NULLT
);
2655 expr_decl
= build1 (INDIRECT_REF
, NULLT
, expr_decl
);
2657 return define_decl (expr_decl
, decl_specs
);
2661 hack_method_prototype (nst_methods
, tmp_decl
)
2667 /* Hack to avoid problem with static typing of self arg. */
2668 TREE_SET_CODE (nst_methods
, CLASS_METHOD_DECL
);
2669 start_method_def (nst_methods
);
2670 TREE_SET_CODE (nst_methods
, INSTANCE_METHOD_DECL
);
2672 if (METHOD_ADD_ARGS (nst_methods
) == (tree
) 1)
2673 parms
= get_parm_info (0); /* we have a `, ...' */
2675 parms
= get_parm_info (1); /* place a `void_at_end' */
2677 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2679 /* Usually called from store_parm_decls -> init_function_start. */
2681 DECL_ARGUMENTS (tmp_decl
) = TREE_PURPOSE (parms
);
2682 current_function_decl
= tmp_decl
;
2685 /* Code taken from start_function. */
2686 tree restype
= TREE_TYPE (TREE_TYPE (tmp_decl
));
2687 /* Promote the value to int before returning it. */
2688 if (TREE_CODE (restype
) == INTEGER_TYPE
2689 && TYPE_PRECISION (restype
) < TYPE_PRECISION (integer_type_node
))
2690 restype
= integer_type_node
;
2691 DECL_RESULT (tmp_decl
) = build_decl (RESULT_DECL
, 0, restype
);
2694 init_function_start (tmp_decl
, "objc-act", 0);
2696 /* Typically called from expand_function_start for function definitions. */
2697 assign_parms (tmp_decl
, 0);
2699 /* install return type */
2700 TREE_TYPE (TREE_TYPE (tmp_decl
)) = groktypename (TREE_TYPE (nst_methods
));
2705 generate_protocol_references (plist
)
2710 /* forward declare protocols referenced */
2711 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
2713 tree proto
= TREE_VALUE (lproto
);
2715 if (TREE_CODE (proto
) == PROTOCOL_INTERFACE_TYPE
2716 && PROTOCOL_NAME (proto
))
2718 if (! PROTOCOL_FORWARD_DECL (proto
))
2719 build_protocol_reference (proto
);
2721 if (PROTOCOL_LIST (proto
))
2722 generate_protocol_references (PROTOCOL_LIST (proto
));
2728 generate_protocols ()
2730 tree p
, tmp_decl
, encoding
;
2731 tree sc_spec
, decl_specs
, decl
;
2732 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
2733 tree cast_type2
= 0;
2735 tmp_decl
= build_tmp_function_decl ();
2737 if (! objc_protocol_template
)
2738 objc_protocol_template
= build_protocol_template ();
2740 /* if a protocol was directly referenced, pull in indirect references */
2741 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
2742 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
2743 generate_protocol_references (PROTOCOL_LIST (p
));
2745 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
2747 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
2748 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
2750 /* if protocol wasn't referenced, don't generate any code */
2751 if (! PROTOCOL_FORWARD_DECL (p
))
2754 /* Make sure we link in the Protocol class. */
2755 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
2759 if (! METHOD_ENCODING (nst_methods
))
2761 hack_method_prototype (nst_methods
, tmp_decl
);
2762 encoding
= encode_method_prototype (nst_methods
, tmp_decl
);
2763 METHOD_ENCODING (nst_methods
) = encoding
;
2765 nst_methods
= TREE_CHAIN (nst_methods
);
2770 if (! METHOD_ENCODING (cls_methods
))
2772 hack_method_prototype (cls_methods
, tmp_decl
);
2773 encoding
= encode_method_prototype (cls_methods
, tmp_decl
);
2774 METHOD_ENCODING (cls_methods
) = encoding
;
2777 cls_methods
= TREE_CHAIN (cls_methods
);
2779 generate_method_descriptors (p
);
2781 if (PROTOCOL_LIST (p
))
2782 refs_decl
= generate_protocol_list (p
);
2786 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
2788 sc_spec
= tree_cons (NULLT
, ridpointers
[(int) RID_STATIC
], NULLT
);
2789 decl_specs
= tree_cons (NULLT
, objc_protocol_template
, sc_spec
);
2791 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
),
2793 end_temporary_allocation ();
2795 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
2801 = groktypename (build_tree_list (build_tree_list (NULLT
, objc_protocol_template
),
2802 build1 (INDIRECT_REF
, NULLT
,
2803 build1 (INDIRECT_REF
, NULLT
, NULLT
))));
2805 refs_expr
= build_unary_op (ADDR_EXPR
, refs_decl
, 0);
2806 TREE_TYPE (refs_expr
) = cast_type2
;
2809 refs_expr
= build_int_2 (0, 0);
2811 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
2812 by generate_method_descriptors, which is called above. */
2813 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
2814 protocol_name_expr
, refs_expr
,
2815 UOBJC_INSTANCE_METHODS_decl
,
2816 UOBJC_CLASS_METHODS_decl
);
2817 finish_decl (decl
, initlist
, NULLT
);
2819 /* Mark the decl as used to avoid "defined but not used" warning. */
2820 TREE_USED (decl
) = 1;
2825 build_protocol_initializer (type
, protocol_name
, protocol_list
,
2826 instance_methods
, class_methods
)
2830 tree instance_methods
;
2833 tree initlist
= NULLT
, expr
;
2834 static tree cast_type
= 0;
2838 = groktypename (build_tree_list
2839 (build_tree_list (NULLT
,
2840 xref_tag (RECORD_TYPE
,
2841 get_identifier (UTAG_CLASS
))),
2842 build1 (INDIRECT_REF
, NULLT
, NULLT
)));
2844 /* filling the "isa" in with one allows the runtime system to
2845 detect that the version change...should remove before final release */
2847 expr
= build_int_2 (PROTOCOL_VERSION
, 0);
2848 TREE_TYPE (expr
) = cast_type
;
2849 initlist
= tree_cons (NULLT
, expr
, initlist
);
2850 initlist
= tree_cons (NULLT
, protocol_name
, initlist
);
2851 initlist
= tree_cons (NULLT
, protocol_list
, initlist
);
2853 if (!instance_methods
)
2854 initlist
= tree_cons (NULLT
, build_int_2 (0, 0), initlist
);
2857 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
2858 initlist
= tree_cons (NULLT
, expr
, initlist
);
2861 initlist
= tree_cons (NULLT
, build_int_2 (0, 0), initlist
);
2864 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
2865 initlist
= tree_cons (NULLT
, expr
, initlist
);
2867 return build_constructor (type
, nreverse (initlist
));
2869 /* end code generation for protocols... */
2871 /* struct objc_category {
2872 char *category_name;
2874 struct objc_method_list *instance_methods;
2875 struct objc_method_list *class_methods;
2876 struct objc_protocol_list *protocols;
2880 build_category_template ()
2882 tree decl_specs
, field_decl
, field_decl_chain
;
2884 objc_category_template
= start_struct (RECORD_TYPE
,
2885 get_identifier (UTAG_CATEGORY
));
2886 /* char *category_name; */
2888 decl_specs
= build_tree_list (NULLT
, ridpointers
[(int) RID_CHAR
]);
2889 field_decl
= build1 (INDIRECT_REF
, NULLT
, get_identifier ("category_name"));
2890 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
2891 field_decl_chain
= field_decl
;
2893 /* char *class_name; */
2895 decl_specs
= build_tree_list (NULLT
, ridpointers
[(int) RID_CHAR
]);
2896 field_decl
= build1 (INDIRECT_REF
, NULLT
, get_identifier ("class_name"));
2897 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
2898 chainon (field_decl_chain
, field_decl
);
2900 /* struct objc_method_list *instance_methods; */
2902 decl_specs
= build_tree_list (NULLT
, xref_tag (RECORD_TYPE
,
2903 get_identifier (UTAG_METHOD_LIST
)));
2904 field_decl
= build1 (INDIRECT_REF
, NULLT
, get_identifier ("instance_methods"));
2905 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
2906 chainon (field_decl_chain
, field_decl
);
2908 /* struct objc_method_list *class_methods; */
2910 decl_specs
= build_tree_list (NULLT
, xref_tag (RECORD_TYPE
,
2911 get_identifier (UTAG_METHOD_LIST
)));
2912 field_decl
= build1 (INDIRECT_REF
, NULLT
, get_identifier ("class_methods"));
2913 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
2914 chainon (field_decl_chain
, field_decl
);
2916 /* struct objc_protocol **protocol_list; */
2918 decl_specs
= build_tree_list (NULLT
, xref_tag (RECORD_TYPE
,
2919 get_identifier (UTAG_PROTOCOL
)));
2920 field_decl
= build1 (INDIRECT_REF
, NULLT
, get_identifier ("protocol_list"));
2921 field_decl
= build1 (INDIRECT_REF
, NULLT
, field_decl
);
2922 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
)
2924 chainon (field_decl_chain
, field_decl
);
2926 finish_struct (objc_category_template
, field_decl_chain
);
2929 /* struct objc_selector {
2935 build_selector_template ()
2938 tree decl_specs
, field_decl
, field_decl_chain
;
2940 objc_selector_template
2941 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SELECTOR
));
2945 decl_specs
= build_tree_list (NULLT
, ridpointers
[(int) RID_VOID
]);
2946 field_decl
= build1 (INDIRECT_REF
, NULLT
, get_identifier ("sel_id"));
2947 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
2948 field_decl_chain
= field_decl
;
2950 /* char *sel_type; */
2952 decl_specs
= build_tree_list (NULLT
, ridpointers
[(int) RID_CHAR
]);
2953 field_decl
= build1 (INDIRECT_REF
, NULLT
, get_identifier ("sel_type"));
2954 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
2955 chainon (field_decl_chain
, field_decl
);
2957 finish_struct (objc_selector_template
, field_decl_chain
);
2960 /* struct objc_class {
2961 struct objc_class *isa;
2962 struct objc_class *super_class;
2967 struct objc_ivar_list *ivars;
2968 struct objc_method_list *methods;
2969 if (flag_next_runtime)
2970 struct objc_cache *cache;
2972 struct sarray *dtable;
2973 struct objc_class *subclass_list;
2974 struct objc_class *sibling_class;
2976 struct objc_protocol_list *protocols;
2980 build_class_template ()
2982 tree decl_specs
, field_decl
, field_decl_chain
;
2984 objc_class_template
= start_struct (RECORD_TYPE
, get_identifier (UTAG_CLASS
));
2986 /* struct objc_class *isa; */
2988 decl_specs
= build_tree_list (NULLT
, objc_class_template
);
2989 field_decl
= build1 (INDIRECT_REF
, NULLT
, get_identifier ("isa"));
2990 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
2991 field_decl_chain
= field_decl
;
2993 /* struct objc_class *super_class; */
2995 decl_specs
= build_tree_list (NULLT
, objc_class_template
);
2996 field_decl
= build1 (INDIRECT_REF
, NULLT
, get_identifier ("super_class"));
2997 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
2998 chainon (field_decl_chain
, field_decl
);
3002 decl_specs
= build_tree_list (NULLT
, ridpointers
[(int) RID_CHAR
]);
3003 field_decl
= build1 (INDIRECT_REF
, NULLT
, get_identifier ("name"));
3004 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
3005 chainon (field_decl_chain
, field_decl
);
3009 decl_specs
= build_tree_list (NULLT
, ridpointers
[(int) RID_LONG
]);
3010 field_decl
= get_identifier ("version");
3011 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
3012 chainon (field_decl_chain
, field_decl
);
3016 decl_specs
= build_tree_list (NULLT
, ridpointers
[(int) RID_LONG
]);
3017 field_decl
= get_identifier ("info");
3018 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
3019 chainon (field_decl_chain
, field_decl
);
3021 /* long instance_size; */
3023 decl_specs
= build_tree_list (NULLT
, ridpointers
[(int) RID_LONG
]);
3024 field_decl
= get_identifier ("instance_size");
3025 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
3026 chainon (field_decl_chain
, field_decl
);
3028 /* struct objc_ivar_list *ivars; */
3030 decl_specs
= build_tree_list (NULLT
, xref_tag (RECORD_TYPE
,
3031 get_identifier (UTAG_IVAR_LIST
)));
3032 field_decl
= build1 (INDIRECT_REF
, NULLT
, get_identifier ("ivars"));
3033 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
3034 chainon (field_decl_chain
, field_decl
);
3036 /* struct objc_method_list *methods; */
3038 decl_specs
= build_tree_list (NULLT
, xref_tag (RECORD_TYPE
,
3039 get_identifier (UTAG_METHOD_LIST
)));
3040 field_decl
= build1 (INDIRECT_REF
, NULLT
, get_identifier ("methods"));
3041 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
3042 chainon (field_decl_chain
, field_decl
);
3044 if (flag_next_runtime
)
3046 /* struct objc_cache *cache; */
3048 decl_specs
= build_tree_list (NULLT
, xref_tag (RECORD_TYPE
,
3049 get_identifier ("objc_cache")));
3050 field_decl
= build1 (INDIRECT_REF
, NULLT
, get_identifier ("cache"));
3051 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
3052 chainon (field_decl_chain
, field_decl
);
3056 /* struct sarray *dtable; */
3058 decl_specs
= build_tree_list (NULLT
, xref_tag (RECORD_TYPE
,
3059 get_identifier ("sarray")));
3060 field_decl
= build1 (INDIRECT_REF
, NULLT
, get_identifier ("dtable"));
3061 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
3062 chainon (field_decl_chain
, field_decl
);
3064 /* struct objc_class *subclass_list; */
3066 decl_specs
= build_tree_list (NULLT
, objc_class_template
);
3067 field_decl
= build1 (INDIRECT_REF
, NULLT
, get_identifier ("subclass_list"));
3068 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
3069 chainon (field_decl_chain
, field_decl
);
3071 /* struct objc_class *sibling_class; */
3073 decl_specs
= build_tree_list (NULLT
, objc_class_template
);
3074 field_decl
= build1 (INDIRECT_REF
, NULLT
, get_identifier ("sibling_class"));
3075 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
3076 chainon (field_decl_chain
, field_decl
);
3079 /* struct objc_protocol **protocol_list; */
3081 decl_specs
= build_tree_list (NULLT
, xref_tag (RECORD_TYPE
,
3082 get_identifier (UTAG_PROTOCOL
)));
3083 field_decl
= build1 (INDIRECT_REF
, NULLT
, get_identifier ("protocol_list"));
3084 field_decl
= build1 (INDIRECT_REF
, NULLT
, field_decl
);
3085 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
3086 chainon (field_decl_chain
, field_decl
);
3089 finish_struct (objc_class_template
, field_decl_chain
);
3092 /* Generate appropriate forward declarations for an implementation. */
3095 synth_forward_declarations ()
3097 tree sc_spec
, decl_specs
, an_id
;
3099 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3101 an_id
= synth_id_with_class_suffix ("_OBJC_CLASS", implementation_context
);
3103 sc_spec
= build_tree_list (NULLT
, ridpointers
[(int) RID_EXTERN
]);
3104 decl_specs
= tree_cons (NULLT
, objc_class_template
, sc_spec
);
3105 UOBJC_CLASS_decl
= define_decl (an_id
, decl_specs
);
3106 TREE_USED (UOBJC_CLASS_decl
) = 1;
3108 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3110 an_id
= synth_id_with_class_suffix ("_OBJC_METACLASS",
3111 implementation_context
);
3113 UOBJC_METACLASS_decl
= define_decl (an_id
, decl_specs
);
3114 TREE_USED (UOBJC_METACLASS_decl
) = 1;
3116 /* pre-build the following entities - for speed/convenience. */
3118 an_id
= get_identifier ("super_class");
3119 ucls_super_ref
= build_component_ref (UOBJC_CLASS_decl
, an_id
);
3120 uucls_super_ref
= build_component_ref (UOBJC_METACLASS_decl
, an_id
);
3124 error_with_ivar (message
, decl
, rawdecl
)
3131 report_error_function (DECL_SOURCE_FILE (decl
));
3133 fprintf (stderr
, "%s:%d: ",
3134 DECL_SOURCE_FILE (decl
), DECL_SOURCE_LINE (decl
));
3135 bzero (errbuf
, BUFSIZE
);
3136 fprintf (stderr
, "%s `%s'\n", message
, gen_declaration (rawdecl
, errbuf
));
3139 #define USERTYPE(t) (TREE_CODE (t) == RECORD_TYPE || \
3140 TREE_CODE (t) == UNION_TYPE || \
3141 TREE_CODE (t) == ENUMERAL_TYPE)
3144 check_ivars (inter
, imp
)
3148 tree intdecls
= CLASS_IVARS (inter
);
3149 tree impdecls
= CLASS_IVARS (imp
);
3150 tree rawintdecls
= CLASS_RAW_IVARS (inter
);
3151 tree rawimpdecls
= CLASS_RAW_IVARS (imp
);
3157 if (intdecls
== 0 && impdecls
== 0)
3159 if (intdecls
== 0 || impdecls
== 0)
3161 error ("inconsistent instance variable specification");
3164 t1
= TREE_TYPE (intdecls
); t2
= TREE_TYPE (impdecls
);
3166 if (!comptypes (t1
, t2
))
3168 if (DECL_NAME (intdecls
) == DECL_NAME (impdecls
))
3170 error_with_ivar ("conflicting instance variable type",
3171 impdecls
, rawimpdecls
);
3172 error_with_ivar ("previous declaration of",
3173 intdecls
, rawintdecls
);
3175 else /* both the type and the name don't match */
3177 error ("inconsistent instance variable specification");
3181 else if (DECL_NAME (intdecls
) != DECL_NAME (impdecls
))
3183 error_with_ivar ("conflicting instance variable name",
3184 impdecls
, rawimpdecls
);
3185 error_with_ivar ("previous declaration of",
3186 intdecls
, rawintdecls
);
3188 intdecls
= TREE_CHAIN (intdecls
);
3189 impdecls
= TREE_CHAIN (impdecls
);
3190 rawintdecls
= TREE_CHAIN (rawintdecls
);
3191 rawimpdecls
= TREE_CHAIN (rawimpdecls
);
3195 /* Set super_type to the data type node for struct objc_super *,
3196 first defining struct objc_super itself.
3197 This needs to be done just once per compilation. */
3200 build_super_template ()
3202 tree record
, decl_specs
, field_decl
, field_decl_chain
;
3204 record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_SUPER
));
3206 /* struct objc_object *self; */
3208 decl_specs
= build_tree_list (NULLT
, objc_object_reference
);
3209 field_decl
= get_identifier ("self");
3210 field_decl
= build1 (INDIRECT_REF
, NULLT
, field_decl
);
3211 field_decl
= grokfield (input_filename
, lineno
,
3212 field_decl
, decl_specs
, NULLT
);
3213 field_decl_chain
= field_decl
;
3215 /* struct objc_class *class; */
3217 decl_specs
= get_identifier (UTAG_CLASS
);
3218 decl_specs
= build_tree_list (NULLT
, xref_tag (RECORD_TYPE
, decl_specs
));
3219 field_decl
= build1 (INDIRECT_REF
, NULLT
, get_identifier ("class"));
3221 field_decl
= grokfield (input_filename
, lineno
,
3222 field_decl
, decl_specs
, NULLT
);
3223 chainon (field_decl_chain
, field_decl
);
3225 finish_struct (record
, field_decl_chain
);
3227 /* `struct objc_super *' */
3228 super_type
= groktypename (build_tree_list (build_tree_list (NULLT
, record
),
3229 build1 (INDIRECT_REF
,
3234 /* struct objc_ivar {
3241 build_ivar_template ()
3243 tree objc_ivar_id
, objc_ivar_record
;
3244 tree decl_specs
, field_decl
, field_decl_chain
;
3246 objc_ivar_id
= get_identifier (UTAG_IVAR
);
3247 objc_ivar_record
= start_struct (RECORD_TYPE
, objc_ivar_id
);
3249 /* char *ivar_name; */
3251 decl_specs
= build_tree_list (NULLT
, ridpointers
[(int) RID_CHAR
]);
3252 field_decl
= build1 (INDIRECT_REF
, NULLT
, get_identifier ("ivar_name"));
3254 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3256 field_decl_chain
= field_decl
;
3258 /* char *ivar_type; */
3260 decl_specs
= build_tree_list (NULLT
, ridpointers
[(int) RID_CHAR
]);
3261 field_decl
= build1 (INDIRECT_REF
, NULLT
, get_identifier ("ivar_type"));
3263 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3265 chainon (field_decl_chain
, field_decl
);
3267 /* int ivar_offset; */
3269 decl_specs
= build_tree_list (NULLT
, ridpointers
[(int) RID_INT
]);
3270 field_decl
= get_identifier ("ivar_offset");
3272 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3274 chainon (field_decl_chain
, field_decl
);
3276 finish_struct (objc_ivar_record
, field_decl_chain
);
3278 return objc_ivar_record
;
3283 struct objc_ivar ivar_list[ivar_count];
3287 build_ivar_list_template (list_type
, size
)
3291 tree objc_ivar_list_record
;
3292 tree decl_specs
, field_decl
, field_decl_chain
;
3294 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULLT
);
3296 /* int ivar_count; */
3298 decl_specs
= build_tree_list (NULLT
, ridpointers
[(int) RID_INT
]);
3299 field_decl
= get_identifier ("ivar_count");
3301 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3303 field_decl_chain
= field_decl
;
3305 /* struct objc_ivar ivar_list[]; */
3307 decl_specs
= build_tree_list (NULLT
, list_type
);
3308 field_decl
= build_nt (ARRAY_REF
, get_identifier ("ivar_list"),
3309 build_int_2 (size
, 0));
3311 field_decl
= grokfield (input_filename
, lineno
,
3312 field_decl
, decl_specs
, NULLT
);
3313 chainon (field_decl_chain
, field_decl
);
3315 finish_struct (objc_ivar_list_record
, field_decl_chain
);
3317 return objc_ivar_list_record
;
3323 struct objc_method method_list[method_count];
3327 build_method_list_template (list_type
, size
)
3331 tree objc_ivar_list_record
;
3332 tree decl_specs
, field_decl
, field_decl_chain
;
3334 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULLT
);
3336 /* int method_next; */
3338 decl_specs
= build_tree_list (NULLT
,
3339 xref_tag (RECORD_TYPE
,
3340 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
3341 field_decl
= build1 (INDIRECT_REF
, NULLT
, get_identifier ("method_next"));
3342 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
3343 field_decl_chain
= field_decl
;
3345 /* int method_count; */
3347 decl_specs
= build_tree_list (NULLT
, ridpointers
[(int) RID_INT
]);
3348 field_decl
= get_identifier ("method_count");
3350 field_decl
= grokfield (input_filename
, lineno
,
3351 field_decl
, decl_specs
, NULLT
);
3352 chainon (field_decl_chain
, field_decl
);
3354 /* struct objc_method method_list[]; */
3356 decl_specs
= build_tree_list (NULLT
, list_type
);
3357 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
3358 build_int_2 (size
, 0));
3360 field_decl
= grokfield (input_filename
, lineno
,
3361 field_decl
, decl_specs
, NULLT
);
3362 chainon (field_decl_chain
, field_decl
);
3364 finish_struct (objc_ivar_list_record
, field_decl_chain
);
3366 return objc_ivar_list_record
;
3370 build_ivar_list_initializer (type
, field_decl
)
3374 tree initlist
= NULLT
;
3381 if (DECL_NAME (field_decl
))
3382 ivar
= tree_cons (NULLT
,
3383 add_objc_string (DECL_NAME (field_decl
),
3387 /* unnamed bit-field ivar (yuck). */
3388 ivar
= tree_cons (NULLT
, build_int_2 (0, 0), ivar
);
3391 encode_field_decl (field_decl
,
3392 obstack_object_size (&util_obstack
),
3393 OBJC_ENCODE_DONT_INLINE_DEFS
);
3394 obstack_1grow (&util_obstack
, 0); /* null terminate string */
3398 add_objc_string (get_identifier (obstack_finish (&util_obstack
)),
3401 obstack_free (&util_obstack
, util_firstobj
);
3407 build_int_2 ((TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl
))
3412 initlist
= tree_cons (NULLT
,
3413 build_constructor (type
, nreverse (ivar
)),
3416 field_decl
= TREE_CHAIN (field_decl
);
3420 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3424 generate_ivars_list (type
, name
, size
, list
)
3430 tree sc_spec
, decl_specs
, decl
, initlist
;
3432 sc_spec
= tree_cons (NULLT
, ridpointers
[(int) RID_STATIC
], NULLT
);
3433 decl_specs
= tree_cons (NULLT
, type
, sc_spec
);
3435 decl
= start_decl (synth_id_with_class_suffix (name
, implementation_context
),
3437 end_temporary_allocation ();
3439 initlist
= build_tree_list (NULLT
, build_int_2 (size
, 0));
3440 initlist
= tree_cons (NULLT
, list
, initlist
);
3443 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3450 generate_ivar_lists ()
3452 tree initlist
, ivar_list_template
, chain
;
3453 tree cast
, variable_length_type
;
3456 generating_instance_variables
= 1;
3458 if (!objc_ivar_template
)
3459 objc_ivar_template
= build_ivar_template ();
3463 (build_tree_list (NULLT
, xref_tag (RECORD_TYPE
,
3464 get_identifier (UTAG_IVAR_LIST
))),
3466 variable_length_type
= groktypename (cast
);
3468 /* only generate class variables for the root of the inheritance
3469 hierarchy since these will be the same for every class */
3471 if (CLASS_SUPER_NAME (implementation_template
) == NULLT
3472 && (chain
= TYPE_FIELDS (objc_class_template
)))
3474 size
= list_length (chain
);
3476 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3477 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3479 UOBJC_CLASS_VARIABLES_decl
3480 = generate_ivars_list (ivar_list_template
, "_OBJC_CLASS_VARIABLES",
3483 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl
) = variable_length_type
;
3486 UOBJC_CLASS_VARIABLES_decl
= 0;
3488 chain
= CLASS_IVARS (implementation_template
);
3491 size
= list_length (chain
);
3492 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3493 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3495 UOBJC_INSTANCE_VARIABLES_decl
3496 = generate_ivars_list (ivar_list_template
, "_OBJC_INSTANCE_VARIABLES",
3499 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl
) = variable_length_type
;
3502 UOBJC_INSTANCE_VARIABLES_decl
= 0;
3504 generating_instance_variables
= 0;
3508 build_dispatch_table_initializer (type
, entries
)
3512 tree initlist
= NULLT
;
3516 tree elemlist
= NULLT
;
3518 elemlist
= tree_cons (NULLT
, build_selector (METHOD_SEL_NAME (entries
)),
3521 elemlist
= tree_cons (NULLT
, add_objc_string (METHOD_ENCODING (entries
),
3525 elemlist
= tree_cons (NULLT
,
3526 build_unary_op (ADDR_EXPR
, METHOD_DEFINITION (entries
), 1),
3529 initlist
= tree_cons (NULLT
,
3530 build_constructor (type
, nreverse (elemlist
)),
3533 entries
= TREE_CHAIN (entries
);
3537 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3540 /* To accomplish method prototyping without generating all kinds of
3541 inane warnings, the definition of the dispatch table entries were
3544 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3546 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3549 build_method_template ()
3552 tree decl_specs
, field_decl
, field_decl_chain
;
3554 _SLT_record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD
));
3556 #ifdef OBJC_INT_SELECTORS
3557 /* unsigned int _cmd; */
3558 decl_specs
= tree_cons (NULLT
, ridpointers
[(int) RID_UNSIGNED
], NULLT
);
3559 decl_specs
= tree_cons (NULLT
, ridpointers
[(int) RID_INT
], decl_specs
);
3560 field_decl
= get_identifier ("_cmd");
3561 #else /* not OBJC_INT_SELECTORS */
3562 /* struct objc_selector *_cmd; */
3563 decl_specs
= tree_cons (NULLT
,
3564 xref_tag (RECORD_TYPE
,
3565 get_identifier (TAG_SELECTOR
)),
3567 field_decl
= build1 (INDIRECT_REF
, NULLT
, get_identifier ("_cmd"));
3568 #endif /* not OBJC_INT_SELECTORS */
3570 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
3571 field_decl_chain
= field_decl
;
3573 decl_specs
= tree_cons (NULLT
, ridpointers
[(int) RID_CHAR
], NULLT
);
3574 field_decl
= build1 (INDIRECT_REF
, NULLT
, get_identifier ("method_types"));
3575 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
3576 chainon (field_decl_chain
, field_decl
);
3580 decl_specs
= tree_cons (NULLT
, ridpointers
[(int) RID_VOID
], NULLT
);
3581 field_decl
= build1 (INDIRECT_REF
, NULLT
, get_identifier ("_imp"));
3582 field_decl
= grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULLT
);
3583 chainon (field_decl_chain
, field_decl
);
3585 finish_struct (_SLT_record
, field_decl_chain
);
3592 generate_dispatch_table (type
, name
, size
, list
)
3598 tree sc_spec
, decl_specs
, decl
, initlist
;
3600 sc_spec
= tree_cons (NULLT
, ridpointers
[(int) RID_STATIC
], NULLT
);
3601 decl_specs
= tree_cons (NULLT
, type
, sc_spec
);
3603 decl
= start_decl (synth_id_with_class_suffix (name
, implementation_context
),
3605 end_temporary_allocation ();
3607 initlist
= build_tree_list (NULLT
, build_int_2 (0, 0));
3608 initlist
= tree_cons (NULLT
, build_int_2 (size
, 0), initlist
);
3609 initlist
= tree_cons (NULLT
, list
, initlist
);
3612 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3619 generate_dispatch_tables ()
3621 tree initlist
, chain
, method_list_template
;
3622 tree cast
, variable_length_type
;
3625 if (!objc_method_template
)
3626 objc_method_template
= build_method_template ();
3630 (build_tree_list (NULLT
, xref_tag (RECORD_TYPE
,
3631 get_identifier (UTAG_METHOD_LIST
))),
3633 variable_length_type
= groktypename (cast
);
3635 chain
= CLASS_CLS_METHODS (implementation_context
);
3638 size
= list_length (chain
);
3640 method_list_template
= build_method_list_template (objc_method_template
, size
);
3641 initlist
= build_dispatch_table_initializer (objc_method_template
, chain
);
3643 UOBJC_CLASS_METHODS_decl
3644 = generate_dispatch_table (method_list_template
,
3645 ((TREE_CODE (implementation_context
)
3646 == CLASS_IMPLEMENTATION_TYPE
)
3647 ? "_OBJC_CLASS_METHODS"
3648 : "_OBJC_CATEGORY_CLASS_METHODS"),
3651 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
3654 UOBJC_CLASS_METHODS_decl
= 0;
3656 chain
= CLASS_NST_METHODS (implementation_context
);
3659 size
= list_length (chain
);
3661 method_list_template
= build_method_list_template (objc_method_template
, size
);
3662 initlist
= build_dispatch_table_initializer (objc_method_template
, chain
);
3664 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
3665 UOBJC_INSTANCE_METHODS_decl
3666 = generate_dispatch_table (method_list_template
,
3667 "_OBJC_INSTANCE_METHODS",
3670 /* we have a category */
3671 UOBJC_INSTANCE_METHODS_decl
3672 = generate_dispatch_table (method_list_template
,
3673 "_OBJC_CATEGORY_INSTANCE_METHODS",
3676 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
3679 UOBJC_INSTANCE_METHODS_decl
= 0;
3683 generate_protocol_list (i_or_p
)
3686 static tree cast_type
= 0;
3687 tree initlist
, decl_specs
, sc_spec
;
3688 tree refs_decl
, expr_decl
, lproto
, e
, plist
;
3691 if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
3692 || TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
3693 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
3694 else if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
3695 plist
= PROTOCOL_LIST (i_or_p
);
3703 (build_tree_list (NULLT
,
3704 xref_tag (RECORD_TYPE
,
3705 get_identifier (UTAG_PROTOCOL
))),
3706 build1 (INDIRECT_REF
, NULLT
, NULLT
)));
3709 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
3710 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
3711 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
3714 /* build initializer */
3715 initlist
= tree_cons (NULLT
, build_int_2 (0, 0), NULLT
);
3717 e
= build_int_2 (size
, 0);
3718 TREE_TYPE (e
) = cast_type
;
3719 initlist
= tree_cons (NULLT
, e
, initlist
);
3721 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
3723 tree pval
= TREE_VALUE (lproto
);
3725 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
3726 && PROTOCOL_FORWARD_DECL (pval
))
3728 e
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (pval
), 0);
3729 initlist
= tree_cons (NULLT
, e
, initlist
);
3733 /* static struct objc_protocol *refs[n]; */
3735 sc_spec
= tree_cons (NULLT
, ridpointers
[(int) RID_STATIC
], NULLT
);
3736 decl_specs
= tree_cons (NULLT
, xref_tag (RECORD_TYPE
,
3737 get_identifier (UTAG_PROTOCOL
)),
3740 if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
3741 expr_decl
= build_nt (ARRAY_REF
,
3742 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
3744 build_int_2 (size
+ 2, 0));
3745 else if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
)
3746 expr_decl
= build_nt (ARRAY_REF
,
3747 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
3749 build_int_2 (size
+ 2, 0));
3750 else if (TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
3751 expr_decl
= build_nt (ARRAY_REF
,
3752 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
3754 build_int_2 (size
+ 2, 0));
3756 expr_decl
= build1 (INDIRECT_REF
, NULLT
, expr_decl
);
3758 refs_decl
= start_decl (expr_decl
, decl_specs
, 1);
3759 end_temporary_allocation ();
3761 finish_decl (refs_decl
, build_constructor (TREE_TYPE (refs_decl
),
3762 nreverse (initlist
)),
3769 build_category_initializer (type
, cat_name
, class_name
,
3770 instance_methods
, class_methods
, protocol_list
)
3774 tree instance_methods
;
3778 tree initlist
= NULLT
, expr
;
3780 initlist
= tree_cons (NULLT
, cat_name
, initlist
);
3781 initlist
= tree_cons (NULLT
, class_name
, initlist
);
3783 if (!instance_methods
)
3784 initlist
= tree_cons (NULLT
, build_int_2 (0, 0), initlist
);
3787 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
3788 initlist
= tree_cons (NULLT
, expr
, initlist
);
3791 initlist
= tree_cons (NULLT
, build_int_2 (0, 0), initlist
);
3794 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
3795 initlist
= tree_cons (NULLT
, expr
, initlist
);
3798 /* protocol_list = */
3800 initlist
= tree_cons (NULLT
, build_int_2 (0, 0), initlist
);
3803 static tree cast_type2
;
3809 (build_tree_list (NULLT
,
3810 xref_tag (RECORD_TYPE
,
3811 get_identifier (UTAG_PROTOCOL
))),
3812 build1 (INDIRECT_REF
, NULLT
,
3813 build1 (INDIRECT_REF
, NULLT
, NULLT
))));
3815 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
3816 TREE_TYPE (expr
) = cast_type2
;
3817 initlist
= tree_cons (NULLT
, expr
, initlist
);
3820 return build_constructor (type
, nreverse (initlist
));
3823 /* struct objc_class {
3824 struct objc_class *isa;
3825 struct objc_class *super_class;
3830 struct objc_ivar_list *ivars;
3831 struct objc_method_list *methods;
3832 if (flag_next_runtime)
3833 struct objc_cache *cache;
3835 struct sarray *dtable;
3836 struct objc_class *subclass_list;
3837 struct objc_class *sibling_class;
3839 struct objc_protocol_list *protocols;
3843 build_shared_structure_initializer (type
, isa
, super
, name
, size
, status
,
3844 dispatch_table
, ivar_list
, protocol_list
)
3851 tree dispatch_table
;
3855 tree initlist
= NULLT
, expr
;
3858 initlist
= tree_cons (NULLT
, isa
, initlist
);
3861 initlist
= tree_cons (NULLT
, super
, initlist
);
3864 initlist
= tree_cons (NULLT
, default_conversion (name
), initlist
);
3867 initlist
= tree_cons (NULLT
, build_int_2 (0, 0), initlist
);
3870 initlist
= tree_cons (NULLT
, build_int_2 (status
, 0), initlist
);
3872 /* instance_size = */
3873 initlist
= tree_cons (NULLT
, size
, initlist
);
3875 /* objc_ivar_list = */
3877 initlist
= tree_cons (NULLT
, build_int_2 (0, 0), initlist
);
3880 expr
= build_unary_op (ADDR_EXPR
, ivar_list
, 0);
3881 initlist
= tree_cons (NULLT
, expr
, initlist
);
3884 /* objc_method_list = */
3885 if (!dispatch_table
)
3886 initlist
= tree_cons (NULLT
, build_int_2 (0, 0), initlist
);
3889 expr
= build_unary_op (ADDR_EXPR
, dispatch_table
, 0);
3890 initlist
= tree_cons (NULLT
, expr
, initlist
);
3893 if (flag_next_runtime
)
3894 /* method_cache = */
3895 initlist
= tree_cons (NULLT
, build_int_2 (0, 0), initlist
);
3899 initlist
= tree_cons (NULLT
, build_int_2 (0, 0), initlist
);
3901 /* subclass_list = */
3902 initlist
= tree_cons (NULLT
, build_int_2 (0, 0), initlist
);
3904 /* sibling_class = */
3905 initlist
= tree_cons (NULLT
, build_int_2 (0, 0), initlist
);
3908 /* protocol_list = */
3909 if (! protocol_list
)
3910 initlist
= tree_cons (NULLT
, build_int_2 (0, 0), initlist
);
3913 static tree cast_type2
;
3919 (build_tree_list (NULLT
,
3920 xref_tag (RECORD_TYPE
,
3921 get_identifier (UTAG_PROTOCOL
))),
3922 build1 (INDIRECT_REF
, NULLT
,
3923 build1 (INDIRECT_REF
, NULLT
, NULLT
))));
3925 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
3926 TREE_TYPE (expr
) = cast_type2
;
3927 initlist
= tree_cons (NULLT
, expr
, initlist
);
3930 return build_constructor (type
, nreverse (initlist
));
3933 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
3935 generate_category (cat
)
3938 tree sc_spec
, decl_specs
, decl
;
3939 tree initlist
, cat_name_expr
, class_name_expr
;
3940 tree protocol_decl
, category
;
3942 add_class_reference (CLASS_NAME (cat
));
3943 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
3945 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
3947 category
= CLASS_CATEGORY_LIST (implementation_template
);
3949 /* find the category interface from the class it is associated with */
3952 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
3954 category
= CLASS_CATEGORY_LIST (category
);
3957 if (category
&& CLASS_PROTOCOL_LIST (category
))
3959 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
3960 protocol_decl
= generate_protocol_list (category
);
3965 sc_spec
= tree_cons (NULLT
, ridpointers
[(int) RID_STATIC
], NULLT
);
3966 decl_specs
= tree_cons (NULLT
, objc_category_template
, sc_spec
);
3968 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
3969 implementation_context
),
3971 end_temporary_allocation ();
3973 initlist
= build_category_initializer (TREE_TYPE (decl
),
3974 cat_name_expr
, class_name_expr
,
3975 UOBJC_INSTANCE_METHODS_decl
,
3976 UOBJC_CLASS_METHODS_decl
,
3979 TREE_USED (decl
) = 1;
3980 finish_decl (decl
, initlist
, NULLT
);
3983 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
3984 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
3987 generate_shared_structures ()
3989 tree sc_spec
, decl_specs
, decl
;
3990 tree name_expr
, super_expr
, root_expr
;
3991 tree my_root_id
= NULLT
, my_super_id
= NULLT
;
3992 tree cast_type
, initlist
, protocol_decl
;
3994 my_super_id
= CLASS_SUPER_NAME (implementation_template
);
3997 add_class_reference (my_super_id
);
3999 /* Compute "my_root_id" - this is required for code generation.
4000 the "isa" for all meta class structures points to the root of
4001 the inheritance hierarchy (e.g. "__Object")... */
4002 my_root_id
= my_super_id
;
4005 tree my_root_int
= lookup_interface (my_root_id
);
4007 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
4008 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
4014 else /* no super class */
4016 my_root_id
= CLASS_NAME (implementation_template
);
4020 = groktypename (build_tree_list (build_tree_list (NULLT
,
4021 objc_class_template
),
4022 build1 (INDIRECT_REF
, NULLT
, NULLT
)));
4024 name_expr
= add_objc_string (CLASS_NAME (implementation_template
),
4027 /* install class `isa' and `super' pointers at runtime */
4030 super_expr
= add_objc_string (my_super_id
, class_names
);
4031 super_expr
= build_c_cast (cast_type
, super_expr
); /* cast! */
4034 super_expr
= build_int_2 (0, 0);
4036 root_expr
= add_objc_string (my_root_id
, class_names
);
4037 root_expr
= build_c_cast (cast_type
, root_expr
); /* cast! */
4039 if (CLASS_PROTOCOL_LIST (implementation_template
))
4041 generate_protocol_references (CLASS_PROTOCOL_LIST (implementation_template
));
4042 protocol_decl
= generate_protocol_list (implementation_template
);
4047 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4049 sc_spec
= build_tree_list (NULLT
, ridpointers
[(int) RID_STATIC
]);
4050 decl_specs
= tree_cons (NULLT
, objc_class_template
, sc_spec
);
4052 decl
= start_decl (DECL_NAME (UOBJC_METACLASS_decl
), decl_specs
, 1);
4053 end_temporary_allocation ();
4056 = build_shared_structure_initializer
4058 root_expr
, super_expr
, name_expr
,
4059 build_int_2 ((TREE_INT_CST_LOW (TYPE_SIZE (objc_class_template
))
4063 UOBJC_CLASS_METHODS_decl
,
4064 UOBJC_CLASS_VARIABLES_decl
,
4067 finish_decl (decl
, initlist
, NULLT
);
4069 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4071 decl
= start_decl (DECL_NAME (UOBJC_CLASS_decl
), decl_specs
, 1);
4072 end_temporary_allocation ();
4075 = build_shared_structure_initializer
4077 build_unary_op (ADDR_EXPR
, UOBJC_METACLASS_decl
, 0),
4078 super_expr
, name_expr
,
4079 build_int_2 ((TREE_INT_CST_LOW (TYPE_SIZE (CLASS_STATIC_TEMPLATE (implementation_template
)))
4083 UOBJC_INSTANCE_METHODS_decl
,
4084 UOBJC_INSTANCE_VARIABLES_decl
,
4087 finish_decl (decl
, initlist
, NULLT
);
4091 synth_id_with_class_suffix (preamble
, ctxt
)
4096 if (TREE_CODE (ctxt
) == CLASS_IMPLEMENTATION_TYPE
4097 || TREE_CODE (ctxt
) == CLASS_INTERFACE_TYPE
)
4100 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
4101 string
= (char *) alloca (strlen (preamble
) + strlen (class_name
) + 3);
4102 sprintf (string
, "%s_%s", preamble
,
4103 IDENTIFIER_POINTER (CLASS_NAME (ctxt
)));
4105 else if (TREE_CODE (ctxt
) == CATEGORY_IMPLEMENTATION_TYPE
4106 || TREE_CODE (ctxt
) == CATEGORY_INTERFACE_TYPE
)
4108 /* we have a category */
4110 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
4111 char *class_super_name
4112 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
));
4113 string
= (char *) alloca (strlen (preamble
)
4114 + strlen (class_name
)
4115 + strlen (class_super_name
)
4117 sprintf (string
, "%s_%s_%s", preamble
, class_name
, class_super_name
);
4119 else if (TREE_CODE (ctxt
) == PROTOCOL_INTERFACE_TYPE
)
4121 char *protocol_name
= IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt
));
4122 string
= (char *) alloca (strlen (preamble
) + strlen (protocol_name
) + 3);
4123 sprintf (string
, "%s_%s", preamble
, protocol_name
);
4125 return get_identifier (string
);
4129 is_objc_type_qualifier (node
)
4132 return (TREE_CODE (node
) == IDENTIFIER_NODE
4133 && (node
== ridpointers
[(int) RID_CONST
]
4134 || node
== ridpointers
[(int) RID_VOLATILE
]
4135 || node
== ridpointers
[(int) RID_IN
]
4136 || node
== ridpointers
[(int) RID_OUT
]
4137 || node
== ridpointers
[(int) RID_INOUT
]
4138 || node
== ridpointers
[(int) RID_BYCOPY
]
4139 || node
== ridpointers
[(int) RID_ONEWAY
]));
4142 /* If type is empty or only type qualifiers are present, add default
4143 type of id (otherwise grokdeclarator will default to int). */
4146 adjust_type_for_id_default (type
)
4149 tree declspecs
, chain
;
4152 return build_tree_list (build_tree_list (NULLT
, objc_object_reference
),
4153 build1 (INDIRECT_REF
, NULLT
, NULLT
));
4155 declspecs
= TREE_PURPOSE (type
);
4157 /* Determine if a typespec is present. */
4158 for (chain
= declspecs
;
4160 chain
= TREE_CHAIN (chain
))
4162 if (!is_objc_type_qualifier (TREE_VALUE (chain
)))
4166 return build_tree_list (tree_cons (NULLT
, objc_object_reference
, declspecs
),
4167 build1 (INDIRECT_REF
, NULLT
, NULLT
));
4172 selector ':' '(' typename ')' identifier
4175 transform an Objective-C keyword argument into
4176 the C equivalent parameter declarator.
4178 in: key_name, an "identifier_node" (optional).
4179 arg_type, a "tree_list" (optional).
4180 arg_name, an "identifier_node".
4182 note: it would be really nice to strongly type the preceding
4183 arguments in the function prototype; however, then i
4184 could not use the "accessor" macros defined in "tree.h".
4186 out: an instance of "keyword_decl". */
4189 build_keyword_decl (key_name
, arg_type
, arg_name
)
4196 /* if no type is specified, default to "id" */
4197 arg_type
= adjust_type_for_id_default (arg_type
);
4199 keyword_decl
= make_node (KEYWORD_DECL
);
4201 TREE_TYPE (keyword_decl
) = arg_type
;
4202 KEYWORD_ARG_NAME (keyword_decl
) = arg_name
;
4203 KEYWORD_KEY_NAME (keyword_decl
) = key_name
;
4205 return keyword_decl
;
4208 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4210 build_keyword_selector (selector
)
4214 tree key_chain
, key_name
;
4217 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4219 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4220 key_name
= KEYWORD_KEY_NAME (key_chain
);
4221 else if (TREE_CODE (selector
) == TREE_LIST
)
4222 key_name
= TREE_PURPOSE (key_chain
);
4225 len
+= IDENTIFIER_LENGTH (key_name
) + 1;
4226 else /* just a ':' arg */
4229 buf
= (char *)alloca (len
+ 1);
4230 bzero (buf
, len
+ 1);
4232 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4234 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4235 key_name
= KEYWORD_KEY_NAME (key_chain
);
4236 else if (TREE_CODE (selector
) == TREE_LIST
)
4237 key_name
= TREE_PURPOSE (key_chain
);
4240 strcat (buf
, IDENTIFIER_POINTER (key_name
));
4243 return get_identifier (buf
);
4246 /* used for declarations and definitions */
4249 build_method_decl (code
, ret_type
, selector
, add_args
)
4250 enum tree_code code
;
4257 /* if no type is specified, default to "id" */
4258 ret_type
= adjust_type_for_id_default (ret_type
);
4260 method_decl
= make_node (code
);
4261 TREE_TYPE (method_decl
) = ret_type
;
4263 /* If we have a keyword selector, create an identifier_node that
4264 represents the full selector name (`:' included)... */
4265 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4267 METHOD_SEL_NAME (method_decl
) = build_keyword_selector (selector
);
4268 METHOD_SEL_ARGS (method_decl
) = selector
;
4269 METHOD_ADD_ARGS (method_decl
) = add_args
;
4273 METHOD_SEL_NAME (method_decl
) = selector
;
4274 METHOD_SEL_ARGS (method_decl
) = NULLT
;
4275 METHOD_ADD_ARGS (method_decl
) = NULLT
;
4281 #define METHOD_DEF 0
4282 #define METHOD_REF 1
4284 /* Used by `build_message_expr' and `comp_method_types'. Return an
4285 argument list for method METH. CONTEXT is either METHOD_DEF or
4286 METHOD_REF, saying whether we are trying to define a method or call
4287 one. SUPERFLAG says this is for a send to super; this makes a
4288 difference for the NeXT calling sequence in which the lookup and
4289 the method call are done together. */
4292 get_arg_type_list (meth
, context
, superflag
)
4300 if (flag_next_runtime
&& superflag
)
4301 arglist
= build_tree_list (NULLT
, super_type
);
4302 else if (context
== METHOD_DEF
)
4303 arglist
= build_tree_list (NULLT
, TREE_TYPE (self_decl
));
4305 arglist
= build_tree_list (NULLT
, id_type
);
4307 /* selector type - will eventually change to `int' */
4308 chainon (arglist
, build_tree_list (NULLT
, selector_type
));
4310 /* build a list of argument types */
4311 for (akey
= METHOD_SEL_ARGS (meth
); akey
; akey
= TREE_CHAIN (akey
))
4313 tree arg_decl
= groktypename_in_parm_context (TREE_TYPE (akey
));
4314 chainon (arglist
, build_tree_list (NULLT
, TREE_TYPE (arg_decl
)));
4317 if (METHOD_ADD_ARGS (meth
) == (tree
)1)
4318 /* We have a `, ...' immediately following the selector,
4319 finalize the arglist...simulate get_parm_info (0). */
4321 else if (METHOD_ADD_ARGS (meth
))
4323 /* we have a variable length selector */
4324 tree add_arg_list
= TREE_CHAIN (METHOD_ADD_ARGS (meth
));
4325 chainon (arglist
, add_arg_list
);
4328 /* finalize the arglist...simulate get_parm_info (1) */
4329 chainon (arglist
, build_tree_list (NULLT
, void_type_node
));
4335 check_duplicates (hsh
)
4346 /* we have two methods with the same name and different types */
4348 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
) ? '-' : '+';
4350 warning ("multiple declarations for method `%s'",
4351 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
4353 warn_with_method ("using", type
, meth
);
4354 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
4355 warn_with_method ("also found", type
, loop
->value
);
4361 /* If RECEIVER is a class reference, return the identifier node for the
4362 referenced class. RECEIVER is created by get_class_reference, so we
4363 check the exact form created depending on which runtimes are used. */
4366 receiver_is_class_object (receiver
)
4369 tree chain
, exp
, arg
;
4370 if (flag_next_runtime
)
4372 /* The receiver is a variable created by build_class_reference_decl. */
4373 if (TREE_CODE (receiver
) == VAR_DECL
4374 && TREE_TYPE (receiver
) == objc_class_type
)
4375 /* Look up the identifier. */
4376 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
4377 if (TREE_PURPOSE (chain
) == receiver
)
4378 return TREE_VALUE (chain
);
4382 /* The receiver is a function call that returns an id. Check if
4383 it is a call to objc_getClass, if so, pick up the class name. */
4384 if ((exp
= TREE_OPERAND (receiver
, 0))
4385 && TREE_CODE (exp
) == ADDR_EXPR
4386 && (exp
= TREE_OPERAND (exp
, 0))
4387 && TREE_CODE (exp
) == FUNCTION_DECL
4388 && exp
== objc_get_class_decl
4389 /* we have a call to objc_getClass! */
4390 && (arg
= TREE_OPERAND (receiver
, 1))
4391 && TREE_CODE (arg
) == TREE_LIST
4392 && (arg
= TREE_VALUE (arg
)))
4395 if (TREE_CODE (arg
) == ADDR_EXPR
4396 && (arg
= TREE_OPERAND (arg
, 0))
4397 && TREE_CODE (arg
) == STRING_CST
)
4398 /* finally, we have the class name */
4399 return get_identifier (TREE_STRING_POINTER (arg
));
4405 /* If we are currently building a message expr, this holds
4406 the identifier of the selector of the message. This is
4407 used when printing warnings about argument mismatches. */
4409 static tree building_objc_message_expr
= 0;
4412 maybe_building_objc_message_expr ()
4414 return building_objc_message_expr
;
4417 /* Construct an expression for sending a message.
4418 MESS has the object to send to in TREE_PURPOSE
4419 and the argument list (including selector) in TREE_VALUE.
4421 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4422 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4425 build_message_expr (mess
)
4428 tree receiver
= TREE_PURPOSE (mess
);
4429 tree selector
, self_object
;
4430 tree rtype
, sel_name
;
4431 tree args
= TREE_VALUE (mess
);
4432 tree method_params
= NULLT
;
4433 tree method_prototype
= NULLT
;
4435 int statically_typed
= 0, statically_allocated
= 0;
4436 tree class_ident
= 0;
4438 /* 1 if this is sending to the superclass. */
4441 if (!doing_objc_thang
)
4444 if (TREE_CODE (receiver
) == ERROR_MARK
)
4445 return error_mark_node
;
4447 /* determine receiver type */
4448 rtype
= TREE_TYPE (receiver
);
4449 super
= IS_SUPER (rtype
);
4453 if (TREE_STATIC_TEMPLATE (rtype
))
4454 statically_allocated
= 1;
4455 else if (TREE_CODE (rtype
) == POINTER_TYPE
4456 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype
)))
4457 statically_typed
= 1;
4458 else if ((flag_next_runtime
4459 || (TREE_CODE (receiver
) == CALL_EXPR
&& IS_ID (rtype
)))
4460 && (class_ident
= receiver_is_class_object (receiver
)))
4462 else if (! IS_ID (rtype
)
4463 /* Allow any type that matches objc_class_type. */
4464 && ! comptypes (rtype
, objc_class_type
))
4466 bzero (errbuf
, BUFSIZE
);
4467 warning ("invalid receiver type `%s'",
4468 gen_declaration (rtype
, errbuf
));
4470 if (statically_allocated
)
4471 receiver
= build_unary_op (ADDR_EXPR
, receiver
, 0);
4473 /* Don't evaluate the receiver twice. */
4474 receiver
= save_expr (receiver
);
4475 self_object
= receiver
;
4478 /* If sending to `super', use current self as the object. */
4479 self_object
= self_decl
;
4481 /* Obtain the full selector name. */
4483 if (TREE_CODE (args
) == IDENTIFIER_NODE
)
4484 /* a unary selector */
4486 else if (TREE_CODE (args
) == TREE_LIST
)
4487 sel_name
= build_keyword_selector (args
);
4489 /* Build the parameter list to give to the method. */
4491 method_params
= NULLT
;
4492 if (TREE_CODE (args
) == TREE_LIST
)
4494 tree chain
= args
, prev
= NULLT
;
4496 /* We have a keyword selector--check for comma expressions. */
4499 tree element
= TREE_VALUE (chain
);
4501 /* We have a comma expression, must collapse... */
4502 if (TREE_CODE (element
) == TREE_LIST
)
4505 TREE_CHAIN (prev
) = element
;
4510 chain
= TREE_CHAIN (chain
);
4512 method_params
= args
;
4515 /* Determine operation return type. */
4517 if (IS_SUPER (rtype
))
4521 if (CLASS_SUPER_NAME (implementation_template
))
4523 iface
= lookup_interface (CLASS_SUPER_NAME (implementation_template
));
4525 if (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
)
4526 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4528 method_prototype
= lookup_class_method_static (iface
, sel_name
);
4530 if (iface
&& !method_prototype
)
4531 warning ("`%s' does not respond to `%s'",
4532 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template
)),
4533 IDENTIFIER_POINTER (sel_name
));
4537 error ("no super class declared in interface for `%s'",
4538 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
4539 return error_mark_node
;
4543 else if (statically_allocated
)
4545 tree ctype
= TREE_TYPE (rtype
);
4546 tree iface
= lookup_interface (TYPE_NAME (rtype
));
4549 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4552 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
4554 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
4557 if (!method_prototype
)
4558 warning ("`%s' does not respond to `%s'",
4559 IDENTIFIER_POINTER (TYPE_NAME (rtype
)),
4560 IDENTIFIER_POINTER (sel_name
));
4562 else if (statically_typed
)
4564 tree ctype
= TREE_TYPE (rtype
);
4566 /* `self' is now statically_typed...all methods should be visible
4567 within the context of the implementation... */
4568 if (implementation_context
4569 && CLASS_NAME (implementation_context
) == TYPE_NAME (ctype
))
4571 method_prototype
= lookup_instance_method_static (implementation_template
, sel_name
);
4574 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
4576 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
4579 if (! method_prototype
4580 && implementation_template
!= implementation_context
)
4581 /* the method is not published in the interface...check locally */
4583 = lookup_method (CLASS_NST_METHODS (implementation_context
),
4590 if ((iface
= lookup_interface (TYPE_NAME (ctype
))))
4591 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4593 if (! method_prototype
)
4595 tree protocol_list
= TYPE_PROTOCOL_LIST (ctype
);
4598 = lookup_method_in_protocol_list (protocol_list
, sel_name
, 0);
4602 if (!method_prototype
)
4603 warning ("`%s' does not respond to `%s'",
4604 IDENTIFIER_POINTER (TYPE_NAME (ctype
)),
4605 IDENTIFIER_POINTER (sel_name
));
4607 else if (class_ident
)
4609 if (implementation_context
4610 && CLASS_NAME (implementation_context
) == class_ident
)
4613 = lookup_class_method_static (implementation_template
, sel_name
);
4615 if (!method_prototype
4616 && implementation_template
!= implementation_context
)
4617 /* the method is not published in the interface...check locally */
4619 = lookup_method (CLASS_CLS_METHODS (implementation_context
),
4626 if ((iface
= lookup_interface (class_ident
)))
4627 method_prototype
= lookup_class_method_static (iface
, sel_name
);
4630 if (!method_prototype
)
4632 warning ("cannot find class (factory) method.");
4633 warning ("return type for `%s' defaults to id",
4634 IDENTIFIER_POINTER (sel_name
));
4637 else if (IS_PROTOCOL_QUALIFIED_ID (rtype
))
4639 /* An anonymous object that has been qualified with a protocol. */
4641 tree protocol_list
= TYPE_PROTOCOL_LIST (rtype
);
4643 method_prototype
= lookup_method_in_protocol_list (protocol_list
,
4646 if (!method_prototype
)
4650 warning ("method `%s' not implemented by protocol.",
4651 IDENTIFIER_POINTER (sel_name
));
4653 /* try and find the method signiture in the global pools! */
4655 if (!(hsh
= hash_lookup (nst_method_hash_list
, sel_name
)))
4656 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
4658 if (!(method_prototype
= check_duplicates (hsh
)))
4659 warning ("return type defaults to id");
4666 /* we think we have an instance...loophole: extern id Object; */
4667 hsh
= hash_lookup (nst_method_hash_list
, sel_name
);
4669 /* for various loopholes...like sending messages to self in a
4670 factory context... */
4671 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
4673 method_prototype
= check_duplicates (hsh
);
4674 if (!method_prototype
)
4676 warning ("cannot find method.");
4677 warning ("return type for `%s' defaults to id",
4678 IDENTIFIER_POINTER (sel_name
));
4682 /* Save the selector name for printing error messages. */
4683 building_objc_message_expr
= sel_name
;
4685 /* Build the parameters list for looking up the method.
4686 These are the object itself and the selector. */
4688 if (flag_typed_selectors
)
4689 selector
= build_typed_selector_reference (sel_name
, method_prototype
);
4691 selector
= build_selector_reference (sel_name
);
4693 retval
= build_objc_method_call (super
, method_prototype
,
4694 receiver
, self_object
,
4695 selector
, method_params
);
4697 building_objc_message_expr
= 0;
4702 /* Build a tree expression to send OBJECT the operation SELECTOR,
4703 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
4704 assuming the method has prototype METHOD_PROTOTYPE.
4705 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
4706 Use METHOD_PARAMS as list of args to pass to the method.
4707 If SUPER_FLAG is nonzero, we look up the superclass's method. */
4710 build_objc_method_call (super_flag
, method_prototype
, lookup_object
, object
,
4711 selector
, method_params
)
4713 tree method_prototype
, lookup_object
, object
, selector
, method_params
;
4715 tree sender
= (super_flag
? umsg_super_decl
: umsg_decl
);
4716 tree rcv_p
= (super_flag
4717 ? build_pointer_type (xref_tag (RECORD_TYPE
,
4718 get_identifier (TAG_SUPER
)))
4721 if (flag_next_runtime
)
4723 if (! method_prototype
)
4725 method_params
= tree_cons (NULLT
, lookup_object
,
4726 tree_cons (NULLT
, selector
,
4728 assemble_external (sender
);
4729 return build_function_call (sender
, method_params
);
4733 /* This is a real kludge, but it is used only for the Next.
4734 Clobber the data type of SENDER temporarily to accept
4735 all the arguments for this operation, and to return
4736 whatever this operation returns. */
4737 tree arglist
= NULLT
;
4740 /* Save the proper contents of SENDER's data type. */
4741 tree savarg
= TYPE_ARG_TYPES (TREE_TYPE (sender
));
4742 tree savret
= TREE_TYPE (TREE_TYPE (sender
));
4744 /* Install this method's argument types. */
4745 arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
4747 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = arglist
;
4749 /* Install this method's return type. */
4750 TREE_TYPE (TREE_TYPE (sender
))
4751 = groktypename (TREE_TYPE (method_prototype
));
4753 /* Call SENDER with all the parameters. This will do type
4754 checking using the arg types for this method. */
4755 method_params
= tree_cons (NULLT
, lookup_object
,
4756 tree_cons (NULLT
, selector
,
4758 assemble_external (sender
);
4759 retval
= build_function_call (sender
, method_params
);
4761 /* Restore SENDER's return/argument types. */
4762 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = savarg
;
4763 TREE_TYPE (TREE_TYPE (sender
)) = savret
;
4769 /* This is the portable way.
4770 First call the lookup function to get a pointer to the method,
4771 then cast the pointer, then call it with the method arguments. */
4774 /* Avoid trouble since we may evaluate each of these twice. */
4775 object
= save_expr (object
);
4776 selector
= save_expr (selector
);
4778 lookup_object
= build_c_cast (rcv_p
, lookup_object
); /* cast! */
4780 assemble_external (sender
);
4782 = build_function_call (sender
,
4783 tree_cons (NULLT
, lookup_object
,
4784 tree_cons (NULLT
, selector
, NULLT
)));
4786 /* If we have a method prototype, construct the data type this
4787 method needs, and cast what we got from SENDER into a pointer
4789 if (method_prototype
)
4791 tree arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
4793 tree valtype
= groktypename (TREE_TYPE (method_prototype
));
4794 tree fake_function_type
= build_function_type (valtype
, arglist
);
4795 TREE_TYPE (method
) = build_pointer_type (fake_function_type
);
4799 = build_pointer_type (build_function_type (ptr_type_node
, NULLT
));
4801 /* Pass the object to the method. */
4802 assemble_external (method
);
4803 return build_function_call (method
,
4804 tree_cons (NULLT
, object
,
4805 tree_cons (NULLT
, selector
,
4811 build_protocol_reference (p
)
4814 tree decl
, ident
, ptype
;
4815 struct obstack
*save_current_obstack
= current_obstack
;
4816 struct obstack
*save_rtl_obstack
= rtl_obstack
;
4818 rtl_obstack
= current_obstack
= &permanent_obstack
;
4820 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
4822 ident
= synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
);
4824 = groktypename (build_tree_list (build_tree_list (NULLT
,
4825 objc_protocol_template
),
4828 if (IDENTIFIER_GLOBAL_VALUE (ident
))
4829 decl
= IDENTIFIER_GLOBAL_VALUE (ident
); /* Set by pushdecl. */
4832 decl
= build_decl (VAR_DECL
, ident
, ptype
);
4833 DECL_EXTERNAL (decl
) = 1;
4834 TREE_PUBLIC (decl
) = 1;
4835 TREE_USED (decl
) = 1;
4837 /* usually called from `rest_of_decl_compilation' */
4838 make_decl_rtl (decl
, 0, 1);
4839 /* our `extended/custom' pushdecl in c-decl.c */
4840 pushdecl_top_level (decl
);
4842 current_obstack
= save_current_obstack
;
4843 rtl_obstack
= save_rtl_obstack
;
4845 PROTOCOL_FORWARD_DECL (p
) = decl
;
4849 build_protocol_expr (protoname
)
4855 if (!doing_objc_thang
)
4858 p
= lookup_protocol (protoname
);
4862 error ("Cannot find protocol declaration for `%s'",
4863 IDENTIFIER_POINTER (protoname
));
4864 return error_mark_node
;
4867 if (!PROTOCOL_FORWARD_DECL (p
))
4868 build_protocol_reference (p
);
4870 expr
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
4872 TREE_TYPE (expr
) = protocol_type
;
4878 build_selector_expr (selnamelist
)
4883 if (!doing_objc_thang
)
4886 /* obtain the full selector name */
4887 if (TREE_CODE (selnamelist
) == IDENTIFIER_NODE
)
4888 /* a unary selector */
4889 selname
= selnamelist
;
4890 else if (TREE_CODE (selnamelist
) == TREE_LIST
)
4891 selname
= build_keyword_selector (selnamelist
);
4893 if (flag_typed_selectors
)
4894 return build_typed_selector_reference (selname
, 0);
4896 return build_selector_reference (selname
);
4900 build_encode_expr (type
)
4906 if (!doing_objc_thang
)
4909 encode_type (type
, obstack_object_size (&util_obstack
),
4910 OBJC_ENCODE_INLINE_DEFS
);
4911 obstack_1grow (&util_obstack
, 0); /* null terminate string */
4912 string
= obstack_finish (&util_obstack
);
4914 /* synthesize a string that represents the encoded struct/union */
4915 result
= my_build_string (strlen (string
) + 1, string
);
4916 obstack_free (&util_obstack
, util_firstobj
);
4921 build_ivar_reference (id
)
4924 if (TREE_CODE (method_context
) == CLASS_METHOD_DECL
)
4926 /* Historically, a class method that produced objects (factory
4927 method) would assign `self' to the instance that it
4928 allocated. This would effectively turn the class method into
4929 an instance method. Following this assignment, the instance
4930 variables could be accessed. That practice, while safe,
4931 violates the simple rule that a class method should not refer
4932 to an instance variable. It's better to catch the cases
4933 where this is done unknowingly than to support the above
4935 warning ("instance variable `%s' accessed in class method",
4936 IDENTIFIER_POINTER (id
));
4937 TREE_TYPE (self_decl
) = instance_type
; /* cast */
4940 return build_component_ref (build_indirect_ref (self_decl
, "->"), id
);
4943 #define HASH_ALLOC_LIST_SIZE 170
4944 #define ATTR_ALLOC_LIST_SIZE 170
4945 #define SIZEHASHTABLE 257
4948 #define HASHFUNCTION(key) ((HOST_WIDE_INT) key & 0x7fffffff)
4953 nst_method_hash_list
= (hash
*)xmalloc (SIZEHASHTABLE
* sizeof (hash
));
4954 cls_method_hash_list
= (hash
*)xmalloc (SIZEHASHTABLE
* sizeof (hash
));
4956 if (!nst_method_hash_list
|| !cls_method_hash_list
)
4957 perror ("unable to allocate space in objc-tree.c");
4962 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
4964 nst_method_hash_list
[i
] = 0;
4965 cls_method_hash_list
[i
] = 0;
4971 hash_enter (hashlist
, method
)
4975 static hash hash_alloc_list
= 0;
4976 static int hash_alloc_index
= 0;
4978 int slot
= HASHFUNCTION (METHOD_SEL_NAME (method
)) % SIZEHASHTABLE
;
4980 if (! hash_alloc_list
|| hash_alloc_index
>= HASH_ALLOC_LIST_SIZE
)
4982 hash_alloc_index
= 0;
4983 hash_alloc_list
= (hash
) xmalloc (sizeof (struct hashed_entry
)
4984 * HASH_ALLOC_LIST_SIZE
);
4985 if (! hash_alloc_list
)
4986 perror ("unable to allocate in objc-tree.c");
4988 obj
= &hash_alloc_list
[hash_alloc_index
++];
4990 obj
->next
= hashlist
[slot
];
4993 hashlist
[slot
] = obj
; /* append to front */
4997 hash_lookup (hashlist
, sel_name
)
5003 target
= hashlist
[HASHFUNCTION (sel_name
) % SIZEHASHTABLE
];
5007 if (sel_name
== METHOD_SEL_NAME (target
->key
))
5010 target
= target
->next
;
5016 hash_add_attr (entry
, value
)
5020 static attr attr_alloc_list
= 0;
5021 static int attr_alloc_index
= 0;
5024 if (! attr_alloc_list
|| attr_alloc_index
>= ATTR_ALLOC_LIST_SIZE
)
5026 attr_alloc_index
= 0;
5027 attr_alloc_list
= (attr
) xmalloc (sizeof (struct hashed_attribute
)
5028 * ATTR_ALLOC_LIST_SIZE
);
5029 if (! attr_alloc_list
)
5030 perror ("unable to allocate in objc-tree.c");
5032 obj
= &attr_alloc_list
[attr_alloc_index
++];
5033 obj
->next
= entry
->list
;
5036 entry
->list
= obj
; /* append to front */
5040 lookup_method (mchain
, method
)
5046 if (TREE_CODE (method
) == IDENTIFIER_NODE
)
5049 key
= METHOD_SEL_NAME (method
);
5053 if (METHOD_SEL_NAME (mchain
) == key
)
5055 mchain
= TREE_CHAIN (mchain
);
5061 lookup_instance_method_static (interface
, ident
)
5065 tree inter
= interface
;
5066 tree chain
= CLASS_NST_METHODS (inter
);
5071 if ((meth
= lookup_method (chain
, ident
)))
5074 if (CLASS_CATEGORY_LIST (inter
))
5076 tree category
= CLASS_CATEGORY_LIST (inter
);
5077 chain
= CLASS_NST_METHODS (category
);
5081 if ((meth
= lookup_method (chain
, ident
)))
5085 /* Check for instance methods in protocols in categories. */
5086 if (CLASS_PROTOCOL_LIST (category
))
5088 if ((meth
= (lookup_method_in_protocol_list
5089 (CLASS_PROTOCOL_LIST (category
), ident
, 0))))
5093 if ((category
= CLASS_CATEGORY_LIST (category
)))
5094 chain
= CLASS_NST_METHODS (category
);
5099 if (CLASS_PROTOCOL_LIST (inter
))
5101 if ((meth
= (lookup_method_in_protocol_list
5102 (CLASS_PROTOCOL_LIST (inter
), ident
, 0))))
5106 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5107 chain
= CLASS_NST_METHODS (inter
);
5115 lookup_class_method_static (interface
, ident
)
5119 tree inter
= interface
;
5120 tree chain
= CLASS_CLS_METHODS (inter
);
5122 tree root_inter
= NULLT
;
5126 if ((meth
= lookup_method (chain
, ident
)))
5129 if (CLASS_CATEGORY_LIST (inter
))
5131 tree category
= CLASS_CATEGORY_LIST (inter
);
5132 chain
= CLASS_CLS_METHODS (category
);
5136 if ((meth
= lookup_method (chain
, ident
)))
5140 /* Check for class methods in protocols in categories. */
5141 if (CLASS_PROTOCOL_LIST (category
))
5143 if ((meth
= (lookup_method_in_protocol_list
5144 (CLASS_PROTOCOL_LIST (category
), ident
, 1))))
5148 if ((category
= CLASS_CATEGORY_LIST (category
)))
5149 chain
= CLASS_CLS_METHODS (category
);
5155 /* Check for class methods in protocols. */
5156 if (CLASS_PROTOCOL_LIST (inter
))
5158 if ((meth
= (lookup_method_in_protocol_list
5159 (CLASS_PROTOCOL_LIST (inter
), ident
, 1))))
5164 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5165 chain
= CLASS_CLS_METHODS (inter
);
5170 /* Simulate wrap around. */
5171 return lookup_instance_method_static (root_inter
, ident
);
5175 add_class_method (class, method
)
5182 /* We will have allocated the method parameter declarations on the
5183 maybepermanent_obstack. Need to make sure they stick around! */
5186 if (!(mth
= lookup_method (CLASS_CLS_METHODS (class), method
)))
5188 /* put method on list in reverse order */
5189 TREE_CHAIN (method
) = CLASS_CLS_METHODS (class);
5190 CLASS_CLS_METHODS (class) = method
;
5194 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5195 error ("duplicate definition of class method `%s'.",
5196 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5199 /* check types, if different complain */
5200 if (!comp_proto_with_proto (method
, mth
))
5201 error ("duplicate declaration of class method `%s'.",
5202 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5206 if (!(hsh
= hash_lookup (cls_method_hash_list
, METHOD_SEL_NAME (method
))))
5208 /* install on a global chain */
5209 hash_enter (cls_method_hash_list
, method
);
5213 /* check types, if different add to a list */
5214 if (!comp_proto_with_proto (method
, hsh
->key
))
5215 hash_add_attr (hsh
, method
);
5221 add_instance_method (class, method
)
5228 /* We will have allocated the method parameter declarations on the
5229 maybepermanent_obstack. Need to make sure they stick around! */
5232 if (!(mth
= lookup_method (CLASS_NST_METHODS (class), method
)))
5234 /* put method on list in reverse order */
5235 TREE_CHAIN (method
) = CLASS_NST_METHODS (class);
5236 CLASS_NST_METHODS (class) = method
;
5240 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5241 error ("duplicate definition of instance method `%s'.",
5242 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5245 /* check types, if different complain */
5246 if (!comp_proto_with_proto (method
, mth
))
5247 error ("duplicate declaration of instance method `%s'.",
5248 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5252 if (!(hsh
= hash_lookup (nst_method_hash_list
, METHOD_SEL_NAME (method
))))
5254 /* install on a global chain */
5255 hash_enter (nst_method_hash_list
, method
);
5259 /* check types, if different add to a list */
5260 if (!comp_proto_with_proto (method
, hsh
->key
))
5261 hash_add_attr (hsh
, method
);
5270 /* put interfaces on list in reverse order */
5271 TREE_CHAIN (class) = interface_chain
;
5272 interface_chain
= class;
5273 return interface_chain
;
5277 add_category (class, category
)
5281 /* put categories on list in reverse order */
5283 tree cat
= CLASS_CATEGORY_LIST (class);
5286 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
5287 warning ("duplicate interface declaration for category `%s(%s)'",
5288 IDENTIFIER_POINTER (CLASS_NAME (class)),
5289 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category
)));
5290 cat
= CLASS_CATEGORY_LIST (cat
);
5293 CLASS_CATEGORY_LIST (category
) = CLASS_CATEGORY_LIST (class);
5294 CLASS_CATEGORY_LIST (class) = category
;
5297 /* Called after parsing each instance variable declaration. Necessary to
5298 preserve typedefs and implement public/private...
5300 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5303 add_instance_variable (class, public, declarator
, declspecs
, width
)
5310 tree field_decl
, raw_decl
;
5312 raw_decl
= build_tree_list (declspecs
/*purpose*/, declarator
/*value*/);
5314 if (CLASS_RAW_IVARS (class))
5315 chainon (CLASS_RAW_IVARS (class), raw_decl
);
5317 CLASS_RAW_IVARS (class) = raw_decl
;
5319 field_decl
= grokfield (input_filename
, lineno
,
5320 declarator
, declspecs
, width
);
5322 /* overload the public attribute, it is not used for FIELD_DECL's */
5326 TREE_PUBLIC (field_decl
) = 0;
5327 TREE_PRIVATE (field_decl
) = 0;
5328 TREE_PROTECTED (field_decl
) = 1;
5332 TREE_PUBLIC (field_decl
) = 1;
5333 TREE_PRIVATE (field_decl
) = 0;
5334 TREE_PROTECTED (field_decl
) = 0;
5338 TREE_PUBLIC (field_decl
) = 0;
5339 TREE_PRIVATE (field_decl
) = 1;
5340 TREE_PROTECTED (field_decl
) = 0;
5345 if (CLASS_IVARS (class))
5346 chainon (CLASS_IVARS (class), field_decl
);
5348 CLASS_IVARS (class) = field_decl
;
5354 is_ivar (decl_chain
, ident
)
5358 for ( ; decl_chain
; decl_chain
= TREE_CHAIN (decl_chain
))
5359 if (DECL_NAME (decl_chain
) == ident
)
5364 /* True if the ivar is private and we are not in its implementation. */
5370 if (TREE_PRIVATE (decl
)
5371 && ! is_ivar (CLASS_IVARS (implementation_template
), DECL_NAME (decl
)))
5373 error ("instance variable `%s' is declared private",
5374 IDENTIFIER_POINTER (DECL_NAME (decl
)));
5381 /* we have an instance variable reference, check to see if it is public...*/
5384 is_public (expr
, identifier
)
5388 tree basetype
= TREE_TYPE (expr
);
5389 enum tree_code code
= TREE_CODE (basetype
);
5392 if (code
== RECORD_TYPE
)
5394 if (TREE_STATIC_TEMPLATE (basetype
))
5396 if (!lookup_interface (TYPE_NAME (basetype
)))
5398 error ("Cannot find interface declaration for `%s'",
5399 IDENTIFIER_POINTER (TYPE_NAME (basetype
)));
5403 if ((decl
= is_ivar (TYPE_FIELDS (basetype
), identifier
)))
5405 if (TREE_PUBLIC (decl
))
5408 /* important difference between the Stepstone translator:
5409 all instance variables should be public within the context
5410 of the implementation. */
5411 if (implementation_context
5412 && (((TREE_CODE (implementation_context
)
5413 == CLASS_IMPLEMENTATION_TYPE
)
5414 || (TREE_CODE (implementation_context
)
5415 == CATEGORY_IMPLEMENTATION_TYPE
))
5416 && (CLASS_NAME (implementation_context
)
5417 == TYPE_NAME (basetype
))))
5418 return ! is_private (decl
);
5420 error ("instance variable `%s' is declared %s",
5421 IDENTIFIER_POINTER (identifier
),
5422 TREE_PRIVATE (decl
) ? "private" : "protected");
5426 else if (implementation_context
&& (basetype
== objc_object_reference
))
5428 TREE_TYPE (expr
) = uprivate_record
;
5429 warning ("static access to object of type `id'");
5435 /* implement @defs (<classname>) within struct bodies. */
5438 get_class_ivars (interface
)
5441 if (!doing_objc_thang
)
5444 return build_ivar_chain (interface
, 1);
5447 /* make sure all entries in "chain" are also in "list" */
5450 check_methods (chain
, list
, mtype
)
5459 if (!lookup_method (list
, chain
))
5463 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
5464 warning ("incomplete implementation of class `%s'",
5465 IDENTIFIER_POINTER (CLASS_NAME (implementation_context
)));
5466 else if (TREE_CODE (implementation_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
5467 warning ("incomplete implementation of category `%s'",
5468 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
5471 warning ("method definition for `%c%s' not found",
5472 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
5474 chain
= TREE_CHAIN (chain
);
5480 conforms_to_protocol (class, protocol
)
5486 tree p
= CLASS_PROTOCOL_LIST (class);
5487 while (p
&& TREE_VALUE (p
) != TREE_VALUE (protocol
))
5491 tree super
= (CLASS_SUPER_NAME (class)
5492 ? lookup_interface (CLASS_SUPER_NAME (class))
5494 int tmp
= super
? conforms_to_protocol (super
, protocol
) : 0;
5498 protocol
= TREE_CHAIN (protocol
);
5503 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5504 CONTEXT. This is one of two mechanisms to check protocol integrity
5508 check_methods_accessible (chain
, context
, mtype
)
5510 tree context
; /* implementation_context */
5515 tree base_context
= context
;
5519 context
= base_context
;
5523 list
= CLASS_CLS_METHODS (context
);
5525 list
= CLASS_NST_METHODS (context
);
5527 if (lookup_method (list
, chain
))
5530 else if (TREE_CODE (context
) == CLASS_IMPLEMENTATION_TYPE
5531 || TREE_CODE (context
) == CLASS_INTERFACE_TYPE
)
5532 context
= (CLASS_SUPER_NAME (context
)
5533 ? lookup_interface (CLASS_SUPER_NAME (context
))
5536 else if (TREE_CODE (context
) == CATEGORY_IMPLEMENTATION_TYPE
5537 || TREE_CODE (context
) == CATEGORY_INTERFACE_TYPE
)
5538 context
= (CLASS_NAME (context
)
5539 ? lookup_interface (CLASS_NAME (context
))
5545 if (context
== NULL_TREE
)
5549 if (TREE_CODE (implementation_context
)
5550 == CLASS_IMPLEMENTATION_TYPE
)
5551 warning ("incomplete implementation of class `%s'",
5553 (CLASS_NAME (implementation_context
)));
5554 else if (TREE_CODE (implementation_context
)
5555 == CATEGORY_IMPLEMENTATION_TYPE
)
5556 warning ("incomplete implementation of category `%s'",
5558 (CLASS_SUPER_NAME (implementation_context
)));
5561 warning ("method definition for `%c%s' not found",
5562 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
5565 chain
= TREE_CHAIN (chain
); /* next method... */
5571 check_protocols (proto_list
, type
, name
)
5576 for ( ; proto_list
; proto_list
= TREE_CHAIN (proto_list
))
5578 tree p
= TREE_VALUE (proto_list
);
5580 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
5584 /* Ensure that all protocols have bodies! */
5585 if (flag_warn_protocol
) {
5586 f1
= check_methods (PROTOCOL_CLS_METHODS (p
),
5587 CLASS_CLS_METHODS (implementation_context
),
5589 f2
= check_methods (PROTOCOL_NST_METHODS (p
),
5590 CLASS_NST_METHODS (implementation_context
),
5593 f1
= check_methods_accessible (PROTOCOL_CLS_METHODS (p
),
5594 implementation_context
,
5596 f2
= check_methods_accessible (PROTOCOL_NST_METHODS (p
),
5597 implementation_context
,
5602 warning ("%s `%s' does not fully implement the `%s' protocol",
5603 type
, name
, IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
5607 ; /* an identifier...if we could not find a protocol. */
5609 /* Check protocols recursively. */
5610 if (PROTOCOL_LIST (p
))
5613 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
5614 if (! conforms_to_protocol (super_class
, PROTOCOL_LIST (p
)))
5615 check_protocols (PROTOCOL_LIST (p
), type
, name
);
5620 /* Make sure that the class CLASS_NAME is defined
5621 CODE says which kind of thing CLASS_NAME ought to be.
5622 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
5623 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE.
5625 If CODE is CLASS_INTERFACE_TYPE, we also do a push_obstacks_nochange
5626 whose matching pop is in continue_class. */
5629 start_class (code
, class_name
, super_name
, protocol_list
)
5630 enum tree_code code
;
5637 if (code
== CLASS_INTERFACE_TYPE
)
5639 push_obstacks_nochange ();
5640 end_temporary_allocation ();
5643 if (!doing_objc_thang
)
5646 class = make_node (code
);
5647 TYPE_BINFO (class) = make_tree_vec (5);
5649 CLASS_NAME (class) = class_name
;
5650 CLASS_SUPER_NAME (class) = super_name
;
5651 CLASS_CLS_METHODS (class) = NULL_TREE
;
5653 if (! is_class_name (class_name
) && (decl
= lookup_name (class_name
)))
5655 error ("`%s' redeclared as different kind of symbol",
5656 IDENTIFIER_POINTER (class_name
));
5657 error_with_decl (decl
, "previous declaration of `%s'");
5660 if (code
== CLASS_IMPLEMENTATION_TYPE
)
5663 static tree implemented_classes
= 0;
5664 tree chain
= implemented_classes
;
5665 for (chain
= implemented_classes
; chain
; chain
= TREE_CHAIN (chain
))
5666 if (TREE_VALUE (chain
) == class_name
)
5668 error ("reimplementation of class `%s'",
5669 IDENTIFIER_POINTER (class_name
));
5670 return error_mark_node
;
5672 implemented_classes
= perm_tree_cons (NULLT
, class_name
,
5673 implemented_classes
);
5676 /* pre-build the following entities - for speed/convenience. */
5678 self_id
= get_identifier ("self");
5680 ucmd_id
= get_identifier ("_cmd");
5682 if (!objc_super_template
)
5683 objc_super_template
= build_super_template ();
5685 method_slot
= 0; /* reset for multiple classes per file */
5687 implementation_context
= class;
5689 /* lookup the interface for this implementation. */
5691 if (!(implementation_template
= lookup_interface (class_name
)))
5693 warning ("Cannot find interface declaration for `%s'",
5694 IDENTIFIER_POINTER (class_name
));
5695 add_class (implementation_template
= implementation_context
);
5698 /* if a super class has been specified in the implementation,
5699 insure it conforms to the one specified in the interface */
5702 && (super_name
!= CLASS_SUPER_NAME (implementation_template
)))
5704 tree previous_name
= CLASS_SUPER_NAME (implementation_template
);
5705 char *name
= previous_name
? IDENTIFIER_POINTER (previous_name
) : "";
5706 error ("conflicting super class name `%s'",
5707 IDENTIFIER_POINTER (super_name
));
5708 error ("previous declaration of `%s'", name
);
5710 else if (! super_name
)
5712 CLASS_SUPER_NAME (implementation_context
)
5713 = CLASS_SUPER_NAME (implementation_template
);
5716 else if (code
== CLASS_INTERFACE_TYPE
)
5718 if (lookup_interface (class_name
))
5719 warning ("duplicate interface declaration for class `%s'",
5720 IDENTIFIER_POINTER (class_name
));
5725 CLASS_PROTOCOL_LIST (class)
5726 = lookup_and_install_protocols (protocol_list
);
5728 else if (code
== CATEGORY_INTERFACE_TYPE
)
5730 tree class_category_is_assoc_with
;
5732 /* for a category, class_name is really the name of the class that
5733 the following set of methods will be associated with...we must
5734 find the interface so that can derive the objects template */
5736 if (!(class_category_is_assoc_with
= lookup_interface (class_name
)))
5738 error ("Cannot find interface declaration for `%s'",
5739 IDENTIFIER_POINTER (class_name
));
5743 add_category (class_category_is_assoc_with
, class);
5746 CLASS_PROTOCOL_LIST (class)
5747 = lookup_and_install_protocols (protocol_list
);
5749 else if (code
== CATEGORY_IMPLEMENTATION_TYPE
)
5751 /* pre-build the following entities - for speed/convenience. */
5753 self_id
= get_identifier ("self");
5755 ucmd_id
= get_identifier ("_cmd");
5757 if (!objc_super_template
)
5758 objc_super_template
= build_super_template ();
5760 method_slot
= 0; /* reset for multiple classes per file */
5762 implementation_context
= class;
5764 /* for a category, class_name is really the name of the class that
5765 the following set of methods will be associated with...we must
5766 find the interface so that can derive the objects template */
5768 if (!(implementation_template
= lookup_interface (class_name
)))
5770 error ("Cannot find interface declaration for `%s'",
5771 IDENTIFIER_POINTER (class_name
));
5779 continue_class (class)
5782 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
5783 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
5785 struct imp_entry
*imp_entry
;
5788 /* check consistency of the instance variables. */
5790 if (CLASS_IVARS (class))
5791 check_ivars (implementation_template
, class);
5793 /* code generation */
5795 ivar_context
= build_private_template (implementation_template
);
5797 if (!objc_class_template
)
5798 build_class_template ();
5800 if (!(imp_entry
= (struct imp_entry
*) xmalloc (sizeof (struct imp_entry
))))
5801 perror ("unable to allocate in objc-tree.c");
5803 imp_entry
->next
= imp_list
;
5804 imp_entry
->imp_context
= class;
5805 imp_entry
->imp_template
= implementation_template
;
5807 synth_forward_declarations ();
5808 imp_entry
->class_decl
= UOBJC_CLASS_decl
;
5809 imp_entry
->meta_decl
= UOBJC_METACLASS_decl
;
5811 /* append to front and increment count */
5812 imp_list
= imp_entry
;
5813 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5818 return ivar_context
;
5820 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
5822 tree record
= xref_tag (RECORD_TYPE
, CLASS_NAME (class));
5824 if (!TYPE_FIELDS (record
))
5826 finish_struct (record
, build_ivar_chain (class, 0));
5827 CLASS_STATIC_TEMPLATE (class) = record
;
5829 /* mark this record as a class template - for static typing */
5830 TREE_STATIC_TEMPLATE (record
) = 1;
5835 return error_mark_node
;
5838 /* This is called once we see the "@end" in an interface/implementation. */
5841 finish_class (class)
5844 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5846 /* all code generation is done in finish_objc */
5848 if (implementation_template
!= implementation_context
)
5850 /* ensure that all method listed in the interface contain bodies! */
5851 check_methods (CLASS_CLS_METHODS (implementation_template
),
5852 CLASS_CLS_METHODS (implementation_context
), '+');
5853 check_methods (CLASS_NST_METHODS (implementation_template
),
5854 CLASS_NST_METHODS (implementation_context
), '-');
5856 if (CLASS_PROTOCOL_LIST (implementation_template
))
5857 check_protocols (CLASS_PROTOCOL_LIST (implementation_template
),
5859 IDENTIFIER_POINTER (CLASS_NAME (implementation_context
)));
5862 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
5864 tree category
= CLASS_CATEGORY_LIST (implementation_template
);
5866 /* find the category interface from the class it is associated with */
5869 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category
))
5871 category
= CLASS_CATEGORY_LIST (category
);
5876 /* ensure that all method listed in the interface contain bodies! */
5877 check_methods (CLASS_CLS_METHODS (category
),
5878 CLASS_CLS_METHODS (implementation_context
), '+');
5879 check_methods (CLASS_NST_METHODS (category
),
5880 CLASS_NST_METHODS (implementation_context
), '-');
5882 if (CLASS_PROTOCOL_LIST (category
))
5883 check_protocols (CLASS_PROTOCOL_LIST (category
),
5885 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
5888 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
5891 char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (class));
5892 char *string
= (char *) alloca (strlen (class_name
) + 3);
5894 /* extern struct objc_object *_<my_name>; */
5896 sprintf (string
, "_%s", class_name
);
5898 decl_specs
= build_tree_list (NULLT
, ridpointers
[(int) RID_EXTERN
]);
5899 decl_specs
= tree_cons (NULLT
, objc_object_reference
, decl_specs
);
5900 define_decl (build1 (INDIRECT_REF
, NULLT
, get_identifier (string
)),
5906 add_protocol (protocol
)
5909 /* put protocol on list in reverse order */
5910 TREE_CHAIN (protocol
) = protocol_chain
;
5911 protocol_chain
= protocol
;
5912 return protocol_chain
;
5916 lookup_protocol (ident
)
5921 for (chain
= protocol_chain
; chain
; chain
= TREE_CHAIN (chain
))
5923 if (ident
== PROTOCOL_NAME (chain
))
5930 start_protocol (code
, name
, list
)
5931 enum tree_code code
;
5937 if (!doing_objc_thang
)
5940 /* This is as good a place as any. Need to invoke push_tag_toplevel. */
5941 if (!objc_protocol_template
)
5942 objc_protocol_template
= build_protocol_template ();
5944 protocol
= make_node (code
);
5945 TYPE_BINFO (protocol
) = make_tree_vec (2);
5947 PROTOCOL_NAME (protocol
) = name
;
5948 PROTOCOL_LIST (protocol
) = list
;
5950 lookup_and_install_protocols (list
);
5952 if (lookup_protocol (name
))
5953 warning ("duplicate declaration for protocol `%s'",
5954 IDENTIFIER_POINTER (name
));
5956 add_protocol (protocol
);
5958 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
5964 finish_protocol (protocol
)
5970 /* "Encode" a data type into a string, which grows in util_obstack.
5971 ??? What is the FORMAT? Someone please document this! */
5974 encode_type_qualifiers (declspecs
)
5979 for (spec
= declspecs
; spec
; spec
= TREE_CHAIN (spec
))
5981 if (ridpointers
[(int) RID_CONST
] == TREE_VALUE (spec
))
5982 obstack_1grow (&util_obstack
, 'r');
5983 else if (ridpointers
[(int) RID_IN
] == TREE_VALUE (spec
))
5984 obstack_1grow (&util_obstack
, 'n');
5985 else if (ridpointers
[(int) RID_INOUT
] == TREE_VALUE (spec
))
5986 obstack_1grow (&util_obstack
, 'N');
5987 else if (ridpointers
[(int) RID_OUT
] == TREE_VALUE (spec
))
5988 obstack_1grow (&util_obstack
, 'o');
5989 else if (ridpointers
[(int) RID_BYCOPY
] == TREE_VALUE (spec
))
5990 obstack_1grow (&util_obstack
, 'O');
5991 else if (ridpointers
[(int) RID_ONEWAY
] == TREE_VALUE (spec
))
5992 obstack_1grow (&util_obstack
, 'V');
5996 /* Encode a pointer type. */
5999 encode_pointer (type
, curtype
, format
)
6004 tree pointer_to
= TREE_TYPE (type
);
6006 if (TREE_CODE (pointer_to
) == RECORD_TYPE
)
6008 if (TYPE_NAME (pointer_to
)
6009 && TREE_CODE (TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
)
6011 char *name
= IDENTIFIER_POINTER (TYPE_NAME (pointer_to
));
6013 if (strcmp (name
, TAG_OBJECT
) == 0) /* '@' */
6015 obstack_1grow (&util_obstack
, '@');
6018 else if (TREE_STATIC_TEMPLATE (pointer_to
))
6020 if (generating_instance_variables
)
6022 obstack_1grow (&util_obstack
, '@');
6023 obstack_1grow (&util_obstack
, '"');
6024 obstack_grow (&util_obstack
, name
, strlen (name
));
6025 obstack_1grow (&util_obstack
, '"');
6030 obstack_1grow (&util_obstack
, '@');
6034 else if (strcmp (name
, TAG_CLASS
) == 0) /* '#' */
6036 obstack_1grow (&util_obstack
, '#');
6039 #ifndef OBJC_INT_SELECTORS
6040 else if (strcmp (name
, TAG_SELECTOR
) == 0) /* ':' */
6042 obstack_1grow (&util_obstack
, ':');
6045 #endif /* OBJC_INT_SELECTORS */
6048 else if (TREE_CODE (pointer_to
) == INTEGER_TYPE
6049 && TYPE_MODE (pointer_to
) == QImode
)
6051 obstack_1grow (&util_obstack
, '*');
6055 /* we have a type that does not get special treatment... */
6057 /* NeXT extension */
6058 obstack_1grow (&util_obstack
, '^');
6059 encode_type (pointer_to
, curtype
, format
);
6063 encode_array (type
, curtype
, format
)
6068 tree an_int_cst
= TYPE_SIZE (type
);
6069 tree array_of
= TREE_TYPE (type
);
6072 /* An incomplete array is treated like a pointer. */
6073 if (an_int_cst
== NULL
)
6075 /* split for obvious reasons. North-Keys 30 Mar 1991 */
6076 encode_pointer (type
, curtype
, format
);
6080 sprintf (buffer
, "[%d",
6081 (TREE_INT_CST_LOW (an_int_cst
)
6082 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
6083 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6084 encode_type (array_of
, curtype
, format
);
6085 obstack_1grow (&util_obstack
, ']');
6090 encode_aggregate (type
, curtype
, format
)
6095 enum tree_code code
= TREE_CODE (type
);
6101 if (obstack_object_size (&util_obstack
) > 0
6102 && *(obstack_next_free (&util_obstack
) - 1) == '^')
6104 tree name
= TYPE_NAME (type
);
6106 /* we have a reference - this is a NeXT extension */
6108 if (obstack_object_size (&util_obstack
) - curtype
== 1
6109 && format
== OBJC_ENCODE_INLINE_DEFS
)
6111 /* output format of struct for first level only! */
6113 tree fields
= TYPE_FIELDS (type
);
6115 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6117 obstack_1grow (&util_obstack
, '{');
6118 obstack_grow (&util_obstack
,
6119 IDENTIFIER_POINTER (name
),
6120 strlen (IDENTIFIER_POINTER (name
)));
6121 obstack_1grow (&util_obstack
, '=');
6124 obstack_grow (&util_obstack
, "{?=", 3);
6126 for ( ; fields
; fields
= TREE_CHAIN (fields
))
6127 encode_field_decl (fields
, curtype
, format
);
6128 obstack_1grow (&util_obstack
, '}');
6130 else if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6132 obstack_1grow (&util_obstack
, '{');
6133 obstack_grow (&util_obstack
,
6134 IDENTIFIER_POINTER (name
),
6135 strlen (IDENTIFIER_POINTER (name
)));
6136 obstack_1grow (&util_obstack
, '}');
6138 else /* we have an untagged structure or a typedef */
6139 obstack_grow (&util_obstack
, "{?}", 3);
6143 tree name
= TYPE_NAME (type
);
6144 tree fields
= TYPE_FIELDS (type
);
6146 if (format
== OBJC_ENCODE_INLINE_DEFS
6147 || generating_instance_variables
)
6149 obstack_1grow (&util_obstack
, '{');
6150 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6151 obstack_grow (&util_obstack
,
6152 IDENTIFIER_POINTER (name
),
6153 strlen (IDENTIFIER_POINTER (name
)));
6155 obstack_1grow (&util_obstack
, '?');
6157 obstack_1grow (&util_obstack
, '=');
6159 for (; fields
; fields
= TREE_CHAIN (fields
))
6161 if (generating_instance_variables
)
6163 tree fname
= DECL_NAME (fields
);
6165 obstack_1grow (&util_obstack
, '"');
6166 if (fname
&& TREE_CODE (fname
) == IDENTIFIER_NODE
)
6168 obstack_grow (&util_obstack
,
6169 IDENTIFIER_POINTER (fname
),
6170 strlen (IDENTIFIER_POINTER (fname
)));
6172 obstack_1grow (&util_obstack
, '"');
6174 encode_field_decl (fields
, curtype
, format
);
6176 obstack_1grow (&util_obstack
, '}');
6180 obstack_1grow (&util_obstack
, '{');
6181 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6182 obstack_grow (&util_obstack
,
6183 IDENTIFIER_POINTER (name
),
6184 strlen (IDENTIFIER_POINTER (name
)));
6185 else /* we have an untagged structure or a typedef */
6186 obstack_1grow (&util_obstack
, '?');
6187 obstack_1grow (&util_obstack
, '}');
6194 if (*obstack_next_free (&util_obstack
) == '^'
6195 || format
!= OBJC_ENCODE_INLINE_DEFS
)
6197 /* we have a reference - this is a NeXT extension--
6198 or we don't want the details. */
6199 if (TYPE_NAME (type
)
6200 && TREE_CODE (TYPE_NAME (type
)) == IDENTIFIER_NODE
)
6202 obstack_1grow (&util_obstack
, '(');
6203 obstack_grow (&util_obstack
,
6204 IDENTIFIER_POINTER (TYPE_NAME (type
)),
6205 strlen (IDENTIFIER_POINTER (TYPE_NAME (type
))));
6206 obstack_1grow (&util_obstack
, ')');
6208 else /* we have an untagged structure or a typedef */
6209 obstack_grow (&util_obstack
, "(?)", 3);
6213 tree fields
= TYPE_FIELDS (type
);
6214 obstack_1grow (&util_obstack
, '(');
6215 for ( ; fields
; fields
= TREE_CHAIN (fields
))
6216 encode_field_decl (fields
, curtype
, format
);
6217 obstack_1grow (&util_obstack
, ')');
6223 obstack_1grow (&util_obstack
, 'i');
6228 /* Support bitfields, the current version of Objective-C does not support
6229 them. the string will consist of one or more "b:n"'s where n is an
6230 integer describing the width of the bitfield. Currently, classes in
6231 the kit implement a method "-(char *)describeBitfieldStruct:" that
6232 simulates this...if they do not implement this method, the archiver
6233 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6234 according to the GNU compiler. After looking at the "kit", it appears
6235 that all classes currently rely on this default behavior, rather than
6236 hand generating this string (which is tedious). */
6239 encode_bitfield (width
, format
)
6244 sprintf (buffer
, "b%d", width
);
6245 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6248 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6251 encode_type (type
, curtype
, format
)
6256 enum tree_code code
= TREE_CODE (type
);
6258 if (code
== INTEGER_TYPE
)
6260 if (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type
)) == 0
6261 && TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type
)) == 0)
6263 /* unsigned integer types */
6265 if (TYPE_MODE (type
) == QImode
) /* 'C' */
6266 obstack_1grow (&util_obstack
, 'C');
6267 else if (TYPE_MODE (type
) == HImode
) /* 'S' */
6268 obstack_1grow (&util_obstack
, 'S');
6269 else if (TYPE_MODE (type
) == SImode
)
6271 if (type
== long_unsigned_type_node
)
6272 obstack_1grow (&util_obstack
, 'L'); /* 'L' */
6274 obstack_1grow (&util_obstack
, 'I'); /* 'I' */
6276 else if (TYPE_MODE (type
) == DImode
) /* 'Q' */
6277 obstack_1grow (&util_obstack
, 'Q');
6279 else /* signed integer types */
6281 if (TYPE_MODE (type
) == QImode
) /* 'c' */
6282 obstack_1grow (&util_obstack
, 'c');
6283 else if (TYPE_MODE (type
) == HImode
) /* 's' */
6284 obstack_1grow (&util_obstack
, 's');
6285 else if (TYPE_MODE (type
) == SImode
) /* 'i' */
6287 if (type
== long_integer_type_node
)
6288 obstack_1grow (&util_obstack
, 'l'); /* 'l' */
6290 obstack_1grow (&util_obstack
, 'i'); /* 'i' */
6292 else if (TYPE_MODE (type
) == DImode
) /* 'q' */
6293 obstack_1grow (&util_obstack
, 'q');
6296 else if (code
== REAL_TYPE
)
6298 /* floating point types */
6300 if (TYPE_MODE (type
) == SFmode
) /* 'f' */
6301 obstack_1grow (&util_obstack
, 'f');
6302 else if (TYPE_MODE (type
) == DFmode
6303 || TYPE_MODE (type
) == TFmode
) /* 'd' */
6304 obstack_1grow (&util_obstack
, 'd');
6307 else if (code
== VOID_TYPE
) /* 'v' */
6308 obstack_1grow (&util_obstack
, 'v');
6310 else if (code
== ARRAY_TYPE
)
6311 encode_array (type
, curtype
, format
);
6313 else if (code
== POINTER_TYPE
)
6314 encode_pointer (type
, curtype
, format
);
6316 else if (code
== RECORD_TYPE
|| code
== UNION_TYPE
|| code
== ENUMERAL_TYPE
)
6317 encode_aggregate (type
, curtype
, format
);
6319 else if (code
== FUNCTION_TYPE
) /* '?' */
6320 obstack_1grow (&util_obstack
, '?');
6324 encode_field_decl (field_decl
, curtype
, format
)
6331 /* If this field is obviously a bitfield, or is a bitfield that has been
6332 clobbered to look like a ordinary integer mode, go ahead and generate
6333 the bitfield typing information. */
6334 type
= TREE_TYPE (field_decl
);
6335 if (DECL_BIT_FIELD (field_decl
))
6336 encode_bitfield (DECL_FIELD_SIZE (field_decl
), format
);
6337 else if (TREE_CODE (TYPE_SIZE (type
)) == INTEGER_CST
6338 && DECL_FIELD_SIZE (field_decl
)
6339 && TYPE_MODE (type
) > DECL_MODE (field_decl
))
6340 encode_bitfield (DECL_FIELD_SIZE (field_decl
), format
);
6342 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6346 expr_last (complex_expr
)
6352 while ((next
= TREE_OPERAND (complex_expr
, 0)))
6353 complex_expr
= next
;
6354 return complex_expr
;
6357 /* The selector of the current method,
6358 or NULL if we aren't compiling a method. */
6361 maybe_objc_method_name (decl
)
6365 return METHOD_SEL_NAME (method_context
);
6370 /* Transform a method definition into a function definition as follows:
6371 - synthesize the first two arguments, "self" and "_cmd". */
6374 start_method_def (method
)
6379 /* Required to implement _msgSuper. */
6380 method_context
= method
;
6381 UOBJC_SUPER_decl
= NULLT
;
6383 pushlevel (0); /* Must be called BEFORE start_function. */
6385 /* Generate prototype declarations for arguments..."new-style". */
6387 if (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
)
6388 decl_specs
= build_tree_list (NULLT
, uprivate_record
);
6390 /* really a `struct objc_class *'...however we allow people to
6391 assign to self...which changes its type midstream. */
6392 decl_specs
= build_tree_list (NULLT
, objc_object_reference
);
6394 push_parm_decl (build_tree_list (decl_specs
,
6395 build1 (INDIRECT_REF
, NULLT
, self_id
)));
6397 #ifdef OBJC_INT_SELECTORS
6398 decl_specs
= build_tree_list (NULLT
, ridpointers
[(int) RID_UNSIGNED
]);
6399 decl_specs
= tree_cons (NULLT
, ridpointers
[(int) RID_INT
], decl_specs
);
6400 push_parm_decl (build_tree_list (decl_specs
, ucmd_id
));
6401 #else /* not OBJC_INT_SELECTORS */
6402 decl_specs
= build_tree_list (NULLT
,
6403 xref_tag (RECORD_TYPE
,
6404 get_identifier (TAG_SELECTOR
)));
6405 push_parm_decl (build_tree_list (decl_specs
,
6406 build1 (INDIRECT_REF
, NULLT
, ucmd_id
)));
6407 #endif /* not OBJC_INT_SELECTORS */
6409 /* generate argument declarations if a keyword_decl */
6410 if (METHOD_SEL_ARGS (method
))
6412 tree arglist
= METHOD_SEL_ARGS (method
);
6415 tree arg_spec
= TREE_PURPOSE (TREE_TYPE (arglist
));
6416 tree arg_decl
= TREE_VALUE (TREE_TYPE (arglist
));
6420 tree last_expr
= expr_last (arg_decl
);
6422 /* unite the abstract decl with its name */
6423 TREE_OPERAND (last_expr
, 0) = KEYWORD_ARG_NAME (arglist
);
6424 push_parm_decl (build_tree_list (arg_spec
, arg_decl
));
6425 /* unhook...restore the abstract declarator */
6426 TREE_OPERAND (last_expr
, 0) = NULLT
;
6429 push_parm_decl (build_tree_list (arg_spec
,
6430 KEYWORD_ARG_NAME (arglist
)));
6432 arglist
= TREE_CHAIN (arglist
);
6437 if (METHOD_ADD_ARGS (method
) > (tree
)1)
6439 /* we have a variable length selector - in "prototype" format */
6440 tree akey
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
6443 /* This must be done prior to calling pushdecl. pushdecl is
6444 going to change our chain on us. */
6445 tree nextkey
= TREE_CHAIN (akey
);
6453 warn_with_method (message
, mtype
, method
)
6458 if (count_error (1) == 0)
6461 report_error_function (DECL_SOURCE_FILE (method
));
6463 fprintf (stderr
, "%s:%d: warning: ",
6464 DECL_SOURCE_FILE (method
), DECL_SOURCE_LINE (method
));
6465 bzero (errbuf
, BUFSIZE
);
6466 fprintf (stderr
, "%s `%c%s'\n",
6467 message
, mtype
, gen_method_decl (method
, errbuf
));
6470 /* return 1 if `method' is consistent with `proto' */
6473 comp_method_with_proto (method
, proto
)
6476 static tree function_type
= 0;
6478 /* create a function_type node once */
6481 struct obstack
*ambient_obstack
= current_obstack
;
6483 current_obstack
= &permanent_obstack
;
6484 function_type
= make_node (FUNCTION_TYPE
);
6485 current_obstack
= ambient_obstack
;
6488 /* Install argument types - normally set by build_function_type. */
6489 TYPE_ARG_TYPES (function_type
) = get_arg_type_list (proto
, METHOD_DEF
, 0);
6491 /* install return type */
6492 TREE_TYPE (function_type
) = groktypename (TREE_TYPE (proto
));
6494 return comptypes (TREE_TYPE (METHOD_DEFINITION (method
)), function_type
);
6497 /* return 1 if `proto1' is consistent with `proto2' */
6500 comp_proto_with_proto (proto1
, proto2
)
6501 tree proto1
, proto2
;
6503 static tree function_type1
= 0, function_type2
= 0;
6505 /* create a couple function_type node's once */
6506 if (!function_type1
)
6508 struct obstack
*ambient_obstack
= current_obstack
;
6510 current_obstack
= &permanent_obstack
;
6511 function_type1
= make_node (FUNCTION_TYPE
);
6512 function_type2
= make_node (FUNCTION_TYPE
);
6513 current_obstack
= ambient_obstack
;
6516 /* Install argument types - normally set by build_function_type. */
6517 TYPE_ARG_TYPES (function_type1
) = get_arg_type_list (proto1
, METHOD_REF
, 0);
6518 TYPE_ARG_TYPES (function_type2
) = get_arg_type_list (proto2
, METHOD_REF
, 0);
6520 /* install return type */
6521 TREE_TYPE (function_type1
) = groktypename (TREE_TYPE (proto1
));
6522 TREE_TYPE (function_type2
) = groktypename (TREE_TYPE (proto2
));
6524 return comptypes (function_type1
, function_type2
);
6527 /* - generate an identifier for the function. the format is "_n_cls",
6528 where 1 <= n <= nMethods, and cls is the name the implementation we
6530 - install the return type from the method declaration.
6531 - if we have a prototype, check for type consistency. */
6534 really_start_method (method
, parmlist
)
6535 tree method
, parmlist
;
6537 tree sc_spec
, ret_spec
, ret_decl
, decl_specs
;
6538 tree method_decl
, method_id
;
6539 char *buf
, *sel_name
, *class_name
, *cat_name
;
6541 /* synth the storage class & assemble the return type */
6542 sc_spec
= tree_cons (NULLT
, ridpointers
[(int) RID_STATIC
], NULLT
);
6543 ret_spec
= TREE_PURPOSE (TREE_TYPE (method
));
6544 decl_specs
= chainon (sc_spec
, ret_spec
);
6546 sel_name
= IDENTIFIER_POINTER (METHOD_SEL_NAME (method
));
6547 class_name
= IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
6548 cat_name
= ((TREE_CODE (implementation_context
)
6549 == CLASS_IMPLEMENTATION_TYPE
)
6551 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
6553 /* Make sure this is big enough for any plausible method label. */
6554 buf
= (char *) alloca (50 + strlen (sel_name
) + strlen (class_name
)
6555 + (cat_name
? strlen (cat_name
) : 0));
6557 OBJC_GEN_METHOD_LABEL (buf
, TREE_CODE (method
) == INSTANCE_METHOD_DECL
,
6558 class_name
, cat_name
, sel_name
, method_slot
);
6560 method_id
= get_identifier (buf
);
6562 method_decl
= build_nt (CALL_EXPR
, method_id
, parmlist
, NULLT
);
6564 /* check the declarator portion of the return type for the method */
6565 if ((ret_decl
= TREE_VALUE (TREE_TYPE (method
))))
6567 /* unite the complex decl (specified in the abstract decl) with the
6568 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
6569 tree save_expr
= expr_last (ret_decl
);
6571 TREE_OPERAND (save_expr
, 0) = method_decl
;
6572 method_decl
= ret_decl
;
6573 /* fool the parser into thinking it is starting a function */
6574 start_function (decl_specs
, method_decl
, 0);
6575 /* unhook...this has the effect of restoring the abstract declarator */
6576 TREE_OPERAND (save_expr
, 0) = NULLT
;
6580 TREE_VALUE (TREE_TYPE (method
)) = method_decl
;
6581 /* fool the parser into thinking it is starting a function */
6582 start_function (decl_specs
, method_decl
, 0);
6583 /* unhook...this has the effect of restoring the abstract declarator */
6584 TREE_VALUE (TREE_TYPE (method
)) = NULLT
;
6587 METHOD_DEFINITION (method
) = current_function_decl
;
6589 /* Check consistency...start_function, pushdecl, duplicate_decls. */
6591 if (implementation_template
!= implementation_context
)
6595 if (TREE_CODE (method
) == INSTANCE_METHOD_DECL
)
6596 proto
= lookup_instance_method_static (implementation_template
,
6597 METHOD_SEL_NAME (method
));
6599 proto
= lookup_class_method_static (implementation_template
,
6600 METHOD_SEL_NAME (method
));
6602 if (proto
&& ! comp_method_with_proto (method
, proto
))
6604 char type
= (TREE_CODE (method
) == INSTANCE_METHOD_DECL
? '-' : '+');
6606 warn_with_method ("conflicting types for", type
, method
);
6607 warn_with_method ("previous declaration of", type
, proto
);
6612 /* The following routine is always called...this "architecture" is to
6613 accommodate "old-style" variable length selectors.
6615 - a:a b:b // prototype ; id c; id d; // old-style. */
6618 continue_method_def ()
6622 if (METHOD_ADD_ARGS (method_context
) == (tree
)1)
6623 /* We have a `, ...' immediately following the selector. */
6624 parmlist
= get_parm_info (0);
6626 parmlist
= get_parm_info (1); /* place a `void_at_end' */
6628 /* Set self_decl from the first argument...this global is used by
6629 build_ivar_reference calling build_indirect_ref. */
6630 self_decl
= TREE_PURPOSE (parmlist
);
6632 poplevel (0, 0, 0); /* must be called BEFORE start_function. */
6634 really_start_method (method_context
, parmlist
);
6636 store_parm_decls (); /* must be called AFTER start_function. */
6639 /* Called by the parser, from the `pushlevel' production. */
6644 if (!UOBJC_SUPER_decl
)
6646 UOBJC_SUPER_decl
= start_decl (get_identifier (UTAG_SUPER
),
6647 build_tree_list (NULLT
,
6648 objc_super_template
),
6651 finish_decl (UOBJC_SUPER_decl
, NULLT
, NULLT
);
6653 /* this prevents `unused variable' warnings when compiling with -Wall. */
6654 DECL_IN_SYSTEM_HEADER (UOBJC_SUPER_decl
) = 1;
6658 /* _n_Method (id self, SEL sel, ...)
6660 struct objc_super _S;
6661 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
6665 get_super_receiver ()
6669 tree super_expr
, super_expr_list
;
6671 /* set receiver to self */
6672 super_expr
= build_component_ref (UOBJC_SUPER_decl
, self_id
);
6673 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, self_decl
);
6674 super_expr_list
= build_tree_list (NULLT
, super_expr
);
6676 /* set class to begin searching */
6677 super_expr
= build_component_ref (UOBJC_SUPER_decl
,
6678 get_identifier ("class"));
6680 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
6682 /* [_cls, __cls]Super are "pre-built" in
6683 synth_forward_declarations. */
6685 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
,
6686 ((TREE_CODE (method_context
)
6687 == INSTANCE_METHOD_DECL
)
6689 : uucls_super_ref
));
6691 else /* we have a category... */
6693 tree super_name
= CLASS_SUPER_NAME (implementation_template
);
6696 if (!super_name
) /* Barf if super used in a category of Object. */
6698 error ("no super class declared in interface for `%s'",
6699 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
6700 return error_mark_node
;
6703 if (flag_next_runtime
)
6705 super_class
= get_class_reference (super_name
);
6706 if (TREE_CODE (method_context
) == CLASS_METHOD_DECL
)
6708 = build_component_ref (build_indirect_ref (super_class
, "->"),
6709 get_identifier ("isa"));
6713 add_class_reference (super_name
);
6714 super_class
= (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
6715 ? objc_get_class_decl
: objc_get_meta_class_decl
);
6716 assemble_external (super_class
);
6718 = build_function_call
6720 build_tree_list (NULLT
,
6721 my_build_string (IDENTIFIER_LENGTH (super_name
) + 1,
6722 IDENTIFIER_POINTER (super_name
))));
6726 TREE_TYPE (super_class
) = TREE_TYPE (ucls_super_ref
);
6727 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, super_class
);
6729 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
6731 super_expr
= build_unary_op (ADDR_EXPR
, UOBJC_SUPER_decl
, 0);
6732 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
6734 return build_compound_expr (super_expr_list
);
6738 error ("[super ...] must appear in a method context");
6739 return error_mark_node
;
6744 encode_method_def (func_decl
)
6749 int max_parm_end
= 0;
6754 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
6755 obstack_object_size (&util_obstack
),
6756 OBJC_ENCODE_INLINE_DEFS
);
6758 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
6759 parms
= TREE_CHAIN (parms
))
6761 int parm_end
= (forwarding_offset (parms
)
6762 + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms
)))
6765 if (!offset_is_register
&& parm_end
> max_parm_end
)
6766 max_parm_end
= parm_end
;
6769 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
6771 sprintf (buffer
, "%d", stack_size
);
6772 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6774 /* argument types */
6775 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
6776 parms
= TREE_CHAIN (parms
))
6779 encode_type (TREE_TYPE (parms
),
6780 obstack_object_size (&util_obstack
),
6781 OBJC_ENCODE_INLINE_DEFS
);
6783 /* compute offset */
6784 sprintf (buffer
, "%d", forwarding_offset (parms
));
6786 /* indicate register */
6787 if (offset_is_register
)
6788 obstack_1grow (&util_obstack
, '+');
6790 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6793 obstack_1grow (&util_obstack
, 0); /* null terminate string */
6794 result
= get_identifier (obstack_finish (&util_obstack
));
6795 obstack_free (&util_obstack
, util_firstobj
);
6800 finish_method_def ()
6802 METHOD_ENCODING (method_context
) = encode_method_def (current_function_decl
);
6804 finish_function (0);
6806 /* this must be done AFTER finish_function, since the optimizer may
6807 find "may be used before set" errors. */
6808 method_context
= NULLT
; /* required to implement _msgSuper. */
6812 lang_report_error_function (decl
)
6817 fprintf (stderr
, "In method `%s'\n",
6818 IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context
)));
6826 is_complex_decl (type
)
6829 return (TREE_CODE (type
) == ARRAY_TYPE
6830 || TREE_CODE (type
) == FUNCTION_TYPE
6831 || (TREE_CODE (type
) == POINTER_TYPE
&& ! IS_ID (type
)));
6835 /* Code to convert a decl node into text for a declaration in C. */
6837 static char tmpbuf
[256];
6840 adorn_decl (decl
, str
)
6844 enum tree_code code
= TREE_CODE (decl
);
6846 if (code
== ARRAY_REF
)
6848 tree an_int_cst
= TREE_OPERAND (decl
, 1);
6850 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_CST
)
6851 sprintf (str
+ strlen (str
), "[%d]", TREE_INT_CST_LOW (an_int_cst
));
6855 else if (code
== ARRAY_TYPE
)
6857 tree an_int_cst
= TYPE_SIZE (decl
);
6858 tree array_of
= TREE_TYPE (decl
);
6860 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_TYPE
)
6861 sprintf (str
+ strlen (str
), "[%d]",
6862 (TREE_INT_CST_LOW (an_int_cst
)
6863 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
6867 else if (code
== CALL_EXPR
)
6869 tree chain
= TREE_PURPOSE (TREE_OPERAND (decl
, 1));
6874 gen_declaration (chain
, str
);
6875 chain
= TREE_CHAIN (chain
);
6881 else if (code
== FUNCTION_TYPE
)
6883 tree chain
= TYPE_ARG_TYPES (decl
); /* a list of types */
6886 while (chain
&& TREE_VALUE (chain
) != void_type_node
)
6888 gen_declaration (TREE_VALUE (chain
), str
);
6889 chain
= TREE_CHAIN (chain
);
6890 if (chain
&& TREE_VALUE (chain
) != void_type_node
)
6895 else if (code
== INDIRECT_REF
)
6897 strcpy (tmpbuf
, "*");
6898 if (TREE_TYPE (decl
) && TREE_CODE (TREE_TYPE (decl
)) == TREE_LIST
)
6902 for (chain
= nreverse (copy_list (TREE_TYPE (decl
)));
6904 chain
= TREE_CHAIN (chain
))
6906 if (TREE_CODE (TREE_VALUE (chain
)) == IDENTIFIER_NODE
)
6908 strcat (tmpbuf
, " ");
6909 strcat (tmpbuf
, IDENTIFIER_POINTER (TREE_VALUE (chain
)));
6913 strcat (tmpbuf
, " ");
6915 strcat (tmpbuf
, str
);
6916 strcpy (str
, tmpbuf
);
6918 else if (code
== POINTER_TYPE
)
6920 strcpy (tmpbuf
, "*");
6921 if (TREE_READONLY (decl
) || TYPE_VOLATILE (decl
))
6923 if (TREE_READONLY (decl
))
6924 strcat (tmpbuf
, " const");
6925 if (TYPE_VOLATILE (decl
))
6926 strcat (tmpbuf
, " volatile");
6928 strcat (tmpbuf
, " ");
6930 strcat (tmpbuf
, str
);
6931 strcpy (str
, tmpbuf
);
6936 gen_declarator (decl
, buf
, name
)
6943 enum tree_code code
= TREE_CODE (decl
);
6953 op
= TREE_OPERAND (decl
, 0);
6955 /* we have a pointer to a function or array...(*)(), (*)[] */
6956 if ((code
== ARRAY_REF
|| code
== CALL_EXPR
)
6957 && op
&& TREE_CODE (op
) == INDIRECT_REF
)
6960 str
= gen_declarator (op
, buf
, name
);
6964 strcpy (tmpbuf
, "(");
6965 strcat (tmpbuf
, str
);
6966 strcat (tmpbuf
, ")");
6967 strcpy (str
, tmpbuf
);
6970 adorn_decl (decl
, str
);
6979 /* this clause is done iteratively...rather than recursively */
6982 op
= (is_complex_decl (TREE_TYPE (decl
))
6983 ? TREE_TYPE (decl
) : NULLT
);
6985 adorn_decl (decl
, str
);
6987 /* we have a pointer to a function or array...(*)(), (*)[] */
6988 if (code
== POINTER_TYPE
6989 && op
&& (TREE_CODE (op
) == FUNCTION_TYPE
6990 || TREE_CODE (op
) == ARRAY_TYPE
))
6992 strcpy (tmpbuf
, "(");
6993 strcat (tmpbuf
, str
);
6994 strcat (tmpbuf
, ")");
6995 strcpy (str
, tmpbuf
);
6998 decl
= (is_complex_decl (TREE_TYPE (decl
))
6999 ? TREE_TYPE (decl
) : NULLT
);
7001 while (decl
&& (code
= TREE_CODE (decl
)));
7005 case IDENTIFIER_NODE
:
7006 /* will only happen if we are processing a "raw" expr-decl. */
7007 strcpy (buf
, IDENTIFIER_POINTER (decl
));
7013 else /* we have an abstract declarator or a _DECL node */
7021 gen_declspecs (declspecs
, buf
, raw
)
7030 for (chain
= nreverse (copy_list (declspecs
));
7031 chain
; chain
= TREE_CHAIN (chain
))
7033 tree aspec
= TREE_VALUE (chain
);
7035 if (TREE_CODE (aspec
) == IDENTIFIER_NODE
)
7036 strcat (buf
, IDENTIFIER_POINTER (aspec
));
7037 else if (TREE_CODE (aspec
) == RECORD_TYPE
)
7039 if (TYPE_NAME (aspec
))
7041 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7043 if (! TREE_STATIC_TEMPLATE (aspec
))
7044 strcat (buf
, "struct ");
7045 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7050 tree chain
= protocol_list
;
7055 strcat (buf
, IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (chain
))));
7056 chain
= TREE_CHAIN (chain
);
7064 strcat (buf
, "untagged struct");
7066 else if (TREE_CODE (aspec
) == UNION_TYPE
)
7068 if (TYPE_NAME (aspec
))
7070 if (! TREE_STATIC_TEMPLATE (aspec
))
7071 strcat (buf
, "union ");
7072 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7075 strcat (buf
, "untagged union");
7077 else if (TREE_CODE (aspec
) == ENUMERAL_TYPE
)
7079 if (TYPE_NAME (aspec
))
7081 if (! TREE_STATIC_TEMPLATE (aspec
))
7082 strcat (buf
, "enum ");
7083 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7086 strcat (buf
, "untagged enum");
7088 else if (TREE_CODE (aspec
) == TYPE_DECL
&& DECL_NAME (aspec
))
7090 strcat (buf
, IDENTIFIER_POINTER (DECL_NAME (aspec
)));
7093 else if (IS_ID (aspec
))
7095 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7100 tree chain
= protocol_list
;
7105 strcat (buf
, IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (chain
))));
7106 chain
= TREE_CHAIN (chain
);
7113 if (TREE_CHAIN (chain
))
7119 /* type qualifiers */
7121 if (TREE_READONLY (declspecs
))
7122 strcat (buf
, "const ");
7123 if (TYPE_VOLATILE (declspecs
))
7124 strcat (buf
, "volatile ");
7126 switch (TREE_CODE (declspecs
))
7128 /* type specifiers */
7130 case INTEGER_TYPE
: /* signed integer types */
7131 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7133 if (declspecs
== short_integer_type_node
) /* 's' */
7134 strcat (buf
, "short int ");
7135 else if (declspecs
== integer_type_node
) /* 'i' */
7136 strcat (buf
, "int ");
7137 else if (declspecs
== long_integer_type_node
) /* 'l' */
7138 strcat (buf
, "long int ");
7139 else if (declspecs
== long_long_integer_type_node
) /* 'l' */
7140 strcat (buf
, "long long int ");
7141 else if (declspecs
== signed_char_type_node
/* 'c' */
7142 || declspecs
== char_type_node
)
7143 strcat (buf
, "char ");
7145 /* unsigned integer types */
7147 else if (declspecs
== short_unsigned_type_node
) /* 'S' */
7148 strcat (buf
, "unsigned short ");
7149 else if (declspecs
== unsigned_type_node
) /* 'I' */
7150 strcat (buf
, "unsigned int ");
7151 else if (declspecs
== long_unsigned_type_node
) /* 'L' */
7152 strcat (buf
, "unsigned long ");
7153 else if (declspecs
== long_long_unsigned_type_node
) /* 'L' */
7154 strcat (buf
, "unsigned long long ");
7155 else if (declspecs
== unsigned_char_type_node
) /* 'C' */
7156 strcat (buf
, "unsigned char ");
7159 case REAL_TYPE
: /* floating point types */
7160 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7162 if (declspecs
== float_type_node
) /* 'f' */
7163 strcat (buf
, "float ");
7164 else if (declspecs
== double_type_node
) /* 'd' */
7165 strcat (buf
, "double ");
7166 else if (declspecs
== long_double_type_node
) /* 'd' */
7167 strcat (buf
, "long double ");
7171 if (TYPE_NAME (declspecs
)
7172 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7174 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7176 if (! TREE_STATIC_TEMPLATE (declspecs
))
7177 strcat (buf
, "struct ");
7178 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7182 tree chain
= protocol_list
;
7187 strcat (buf
, IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (chain
))));
7188 chain
= TREE_CHAIN (chain
);
7196 strcat (buf
, "untagged struct");
7202 if (TYPE_NAME (declspecs
)
7203 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7205 strcat (buf
, "union ");
7206 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7210 strcat (buf
, "untagged union ");
7214 if (TYPE_NAME (declspecs
)
7215 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7217 strcat (buf
, "enum ");
7218 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7222 strcat (buf
, "untagged enum ");
7226 strcat (buf
, "void ");
7232 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7237 tree chain
= protocol_list
;
7242 strcat (buf
, IDENTIFIER_POINTER (PROTOCOL_NAME (TREE_VALUE (chain
))));
7243 chain
= TREE_CHAIN (chain
);
7255 gen_declaration (atype_or_adecl
, buf
)
7256 tree atype_or_adecl
;
7261 if (TREE_CODE (atype_or_adecl
) == TREE_LIST
)
7263 tree declspecs
; /* "identifier_node", "record_type" */
7264 tree declarator
; /* "array_ref", "indirect_ref", "call_expr"... */
7266 /* we have a "raw", abstract declarator (typename) */
7267 declarator
= TREE_VALUE (atype_or_adecl
);
7268 declspecs
= TREE_PURPOSE (atype_or_adecl
);
7270 gen_declspecs (declspecs
, buf
, 1);
7274 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7280 tree declspecs
; /* "integer_type", "real_type", "record_type"... */
7281 tree declarator
; /* "array_type", "function_type", "pointer_type". */
7283 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7284 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7285 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7286 atype
= TREE_TYPE (atype_or_adecl
);
7288 atype
= atype_or_adecl
; /* assume we have a *_type node */
7290 if (is_complex_decl (atype
))
7294 /* get the declaration specifier...it is at the end of the list */
7295 declarator
= chain
= atype
;
7297 chain
= TREE_TYPE (chain
); /* not TREE_CHAIN (chain); */
7298 while (is_complex_decl (chain
));
7307 gen_declspecs (declspecs
, buf
, 0);
7309 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7310 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7311 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7313 char *decl_name
= (DECL_NAME (atype_or_adecl
)
7314 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl
))
7320 strcat (buf
, gen_declarator (declarator
, declbuf
, decl_name
));
7322 else if (decl_name
[0])
7325 strcat (buf
, decl_name
);
7328 else if (declarator
)
7331 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7337 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7340 gen_method_decl (method
, buf
)
7346 if (RAW_TYPESPEC (method
) != objc_object_reference
)
7349 gen_declaration (TREE_TYPE (method
), buf
);
7353 chain
= METHOD_SEL_ARGS (method
);
7355 { /* we have a chain of keyword_decls */
7358 if (KEYWORD_KEY_NAME (chain
))
7359 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain
)));
7362 if (RAW_TYPESPEC (chain
) != objc_object_reference
)
7365 gen_declaration (TREE_TYPE (chain
), buf
);
7368 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain
)));
7369 if ((chain
= TREE_CHAIN (chain
)))
7374 if (METHOD_ADD_ARGS (method
) == (tree
)1)
7375 strcat (buf
, ", ...");
7376 else if (METHOD_ADD_ARGS (method
))
7378 /* we have a tree list node as generate by get_parm_info. */
7379 chain
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
7380 /* know we have a chain of parm_decls */
7384 gen_declaration (chain
, buf
);
7385 chain
= TREE_CHAIN (chain
);
7389 else /* we have a unary selector */
7390 strcat (buf
, IDENTIFIER_POINTER (METHOD_SEL_NAME (method
)));
7398 dump_interface (fp
, chain
)
7402 char *buf
= (char *)xmalloc (256);
7403 char *my_name
= IDENTIFIER_POINTER (CLASS_NAME (chain
));
7404 tree ivar_decls
= CLASS_RAW_IVARS (chain
);
7405 tree nst_methods
= CLASS_NST_METHODS (chain
);
7406 tree cls_methods
= CLASS_CLS_METHODS (chain
);
7408 fprintf (fp
, "\n@interface %s", my_name
);
7410 if (CLASS_SUPER_NAME (chain
))
7412 char *super_name
= IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain
));
7413 fprintf (fp
, " : %s\n", super_name
);
7420 fprintf (fp
, "{\n");
7424 fprintf (fp
, "\t%s;\n", gen_declaration (ivar_decls
, buf
));
7425 ivar_decls
= TREE_CHAIN (ivar_decls
);
7428 fprintf (fp
, "}\n");
7434 fprintf (fp
, "- %s;\n", gen_method_decl (nst_methods
, buf
));
7435 nst_methods
= TREE_CHAIN (nst_methods
);
7441 fprintf (fp
, "+ %s;\n", gen_method_decl (cls_methods
, buf
));
7442 cls_methods
= TREE_CHAIN (cls_methods
);
7444 fprintf (fp
, "\n@end");
7450 /* Add the special tree codes of Objective C to the tables. */
7452 #define LAST_CODE LAST_AND_UNUSED_TREE_CODE
7454 gcc_obstack_init (&util_obstack
);
7455 util_firstobj
= (char *) obstack_finish (&util_obstack
);
7458 = (char **) xrealloc (tree_code_type
,
7459 sizeof (char *) * LAST_OBJC_TREE_CODE
);
7461 = (int *) xrealloc (tree_code_length
,
7462 sizeof (int) * LAST_OBJC_TREE_CODE
);
7464 = (char **) xrealloc (tree_code_name
,
7465 sizeof (char *) * LAST_OBJC_TREE_CODE
);
7466 bcopy ((char *) objc_tree_code_type
,
7467 (char *) (tree_code_type
+ (int) LAST_CODE
),
7468 (((int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
)
7469 * sizeof (char *)));
7470 bcopy ((char *) objc_tree_code_length
,
7471 (char *) (tree_code_length
+ (int) LAST_CODE
),
7472 (((int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
)
7474 bcopy ((char *) objc_tree_code_name
,
7475 (char *) (tree_code_name
+ (int) LAST_CODE
),
7476 (((int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
)
7477 * sizeof (char *)));
7479 errbuf
= (char *)xmalloc (BUFSIZE
);
7481 synth_module_prologue ();
7487 struct imp_entry
*impent
;
7489 /* The internally generated initializers appear to have missing braces.
7490 Don't warn about this. */
7491 int save_warn_missing_braces
= warn_missing_braces
;
7492 warn_missing_braces
= 0;
7494 generate_forward_declaration_to_string_table ();
7496 #ifdef OBJC_PROLOGUE
7500 if (implementation_context
|| class_names_chain
7501 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
7502 generate_objc_symtab_decl ();
7504 for (impent
= imp_list
; impent
; impent
= impent
->next
)
7506 implementation_context
= impent
->imp_context
;
7507 implementation_template
= impent
->imp_template
;
7509 UOBJC_CLASS_decl
= impent
->class_decl
;
7510 UOBJC_METACLASS_decl
= impent
->meta_decl
;
7512 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
7514 /* all of the following reference the string pool... */
7515 generate_ivar_lists ();
7516 generate_dispatch_tables ();
7517 generate_shared_structures ();
7521 generate_dispatch_tables ();
7522 generate_category (implementation_context
);
7526 /* If we are using an array of selectors, we must always
7527 finish up the array decl even if no selectors were used. */
7528 if (! flag_next_runtime
|| sel_ref_chain
)
7529 build_selector_translation_table ();
7532 generate_protocols ();
7534 if (implementation_context
|| class_names_chain
7535 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
7537 /* Arrange for Objc data structures to be initialized at run time. */
7538 char *init_name
= build_module_descriptor ();
7540 assemble_constructor (init_name
);
7543 /* dump the class references...this forces the appropriate classes
7544 to be linked into the executable image, preserving unix archive
7545 semantics...this can be removed when we move to a more dynamically
7546 linked environment. */
7547 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
7549 handle_class_ref (chain
);
7550 if (TREE_PURPOSE (chain
))
7551 generate_classref_translation_entry (chain
);
7554 for (impent
= imp_list
; impent
; impent
= impent
->next
)
7555 handle_impent (impent
);
7557 /* dump the string table last */
7559 generate_strings ();
7561 if (flag_gen_declaration
)
7563 add_class (implementation_context
);
7564 dump_interface (gen_declaration_file
, implementation_context
);
7572 /* Run through the selector hash tables and print a warning for any
7573 selector which has multiple methods. */
7575 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
7576 for (hsh
= cls_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
7579 tree meth
= hsh
->key
;
7580 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
7584 warning ("potential selector conflict for method `%s'",
7585 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
7586 warn_with_method ("found", type
, meth
);
7587 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
7588 warn_with_method ("found", type
, loop
->value
);
7591 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
7592 for (hsh
= nst_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
7595 tree meth
= hsh
->key
;
7596 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
7600 warning ("potential selector conflict for method `%s'",
7601 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
7602 warn_with_method ("found", type
, meth
);
7603 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
7604 warn_with_method ("found", type
, loop
->value
);
7608 warn_missing_braces
= save_warn_missing_braces
;
7611 /* Subroutines of finish_objc. */
7614 generate_classref_translation_entry (chain
)
7617 tree expr
, name
, decl_specs
, decl
, sc_spec
;
7620 type
= TREE_TYPE (TREE_PURPOSE (chain
));
7622 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
7623 expr
= build_c_cast (type
, expr
); /* cast! */
7625 name
= DECL_NAME (TREE_PURPOSE (chain
));
7627 sc_spec
= build_tree_list (NULLT
, ridpointers
[(int) RID_STATIC
]);
7629 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
7630 decl_specs
= tree_cons (NULLT
, type
, sc_spec
);
7632 /* the `decl' that is returned from start_decl is the one that we
7633 forward declared in `build_class_reference'. */
7634 decl
= start_decl (name
, decl_specs
, 1);
7635 end_temporary_allocation ();
7636 finish_decl (decl
, expr
, NULLT
);
7641 handle_class_ref (chain
)
7644 char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
7645 if (! flag_next_runtime
)
7648 char *string
= (char *) alloca (strlen (name
) + 30);
7651 sprintf (string
, "%sobjc_class_name_%s",
7652 (flag_next_runtime
? "." : "__"), name
);
7654 /* Make a decl for this name, so we can use its address in a tree. */
7655 decl
= build_decl (VAR_DECL
, get_identifier (string
), char_type_node
);
7656 DECL_EXTERNAL (decl
) = 1;
7657 TREE_PUBLIC (decl
) = 1;
7660 rest_of_decl_compilation (decl
, 0, 0, 0);
7662 /* Make following constant read-only (why not)? */
7663 readonly_data_section ();
7665 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
7667 /* Align the section properly. */
7668 assemble_constant_align (exp
);
7670 /* Inform the assembler about this new external thing. */
7671 assemble_external (decl
);
7673 /* Output a constant to reference this address. */
7674 output_constant (exp
, int_size_in_bytes (string_type_node
));
7678 /* This overreliance on our assembler (i.e. lack of portability)
7679 should be dealt with at some point. The GNU strategy (above)
7680 won't work either, but it is a start. */
7681 char *string
= (char *) alloca (strlen (name
) + 30);
7682 sprintf (string
, ".reference .objc_class_name_%s", name
);
7683 assemble_asm (my_build_string (strlen (string
) + 1, string
));
7688 handle_impent (impent
)
7689 struct imp_entry
*impent
;
7691 implementation_context
= impent
->imp_context
;
7692 implementation_template
= impent
->imp_template
;
7694 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
7696 char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
7697 char *string
= (char *) alloca (strlen (class_name
) + 30);
7699 if (flag_next_runtime
)
7701 /* Grossly unportable.
7702 People should know better than to assume
7703 such things about assembler syntax! */
7704 sprintf (string
, ".objc_class_name_%s=0", class_name
);
7705 assemble_asm (my_build_string (strlen (string
) + 1, string
));
7707 sprintf (string
, ".globl .objc_class_name_%s", class_name
);
7708 assemble_asm (my_build_string (strlen (string
) + 1, string
));
7712 sprintf (string
, "%sobjc_class_name_%s",
7713 (flag_next_runtime
? "." : "__"), class_name
);
7714 assemble_global (string
);
7715 assemble_label (string
);
7718 else if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
7720 char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
7721 char *class_super_name
7722 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
7723 char *string
= (char *) alloca (strlen (class_name
)
7724 + strlen (class_super_name
) + 30);
7726 /* Do the same for categories. Even though no references to these
7727 symbols are generated automatically by the compiler, it gives
7728 you a handle to pull them into an archive by hand. */
7729 if (flag_next_runtime
)
7731 /* Grossly unportable. */
7732 sprintf (string
, ".objc_category_name_%s_%s=0",
7733 class_name
, class_super_name
);
7734 assemble_asm (my_build_string (strlen (string
) + 1, string
));
7736 sprintf (string
, ".globl .objc_category_name_%s_%s",
7737 class_name
, class_super_name
);
7738 assemble_asm (my_build_string (strlen (string
) + 1, string
));
7742 sprintf (string
, "%sobjc_category_name_%s_%s",
7743 (flag_next_runtime
? "." : "__"),
7744 class_name
, class_super_name
);
7745 assemble_global (string
);
7746 assemble_label (string
);
7757 char *buf
= (char *)xmalloc (256);
7759 { /* dump function prototypes */
7760 tree loop
= UOBJC_MODULES_decl
;
7762 fprintf (fp
, "\n\nfunction prototypes:\n");
7765 if (TREE_CODE (loop
) == FUNCTION_DECL
&& DECL_INITIAL (loop
))
7767 /* we have a function definition - generate prototype */
7768 bzero (errbuf
, BUFSIZE
);
7769 gen_declaration (loop
, errbuf
);
7770 fprintf (fp
, "%s;\n", errbuf
);
7772 loop
= TREE_CHAIN (loop
);
7775 { /* dump global chains */
7777 int i
, index
= 0, offset
= 0;
7780 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
7782 if (hashlist
= nst_method_hash_list
[i
])
7784 fprintf (fp
, "\n\nnst_method_hash_list[%d]:\n", i
);
7788 fprintf (fp
, "-%s;\n", gen_method_decl (hashlist
->key
, buf
));
7789 hashlist
= hashlist
->next
;
7794 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
7796 if (hashlist
= cls_method_hash_list
[i
])
7798 fprintf (fp
, "\n\ncls_method_hash_list[%d]:\n", i
);
7802 fprintf (fp
, "-%s;\n", gen_method_decl (hashlist
->key
, buf
));
7803 hashlist
= hashlist
->next
;
7808 fprintf (fp
, "\nsel_refdef_chain:\n");
7809 for (loop
= sel_refdef_chain
; loop
; loop
= TREE_CHAIN (loop
))
7811 fprintf (fp
, "(index: %4d offset: %4d) %s\n", index
, offset
,
7812 IDENTIFIER_POINTER (TREE_VALUE (loop
)));
7814 /* add one for the '\0' character */
7815 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (loop
)) + 1;
7817 fprintf (fp
, "\n (max_selector_index: %4d.\n", max_selector_index
);
7823 print_lang_statistics ()