1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002
3 Free Software Foundation, Inc.
4 Contributed by Steve Naroff.
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* Purpose: This module implements the Objective-C 4.0 language.
25 compatibility issues (with the Stepstone translator):
27 - does not recognize the following 3.3 constructs.
28 @requires, @classes, @messages, = (...)
29 - methods with variable arguments must conform to ANSI standard.
30 - tagged structure definitions that appear in BOTH the interface
31 and implementation are not allowed.
32 - public/private: all instance variables are public within the
33 context of the implementation...I consider this to be a bug in
35 - statically allocated objects are not supported. the user will
36 receive an error if this service is requested.
38 code generation `options':
62 /* This is the default way of generating a method name. */
63 /* I am not sure it is really correct.
64 Perhaps there's a danger that it will make name conflicts
65 if method names contain underscores. -- rms. */
66 #ifndef OBJC_GEN_METHOD_LABEL
67 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
70 sprintf ((BUF), "_%s_%s_%s_%s", \
71 ((IS_INST) ? "i" : "c"), \
73 ((CAT_NAME)? (CAT_NAME) : ""), \
75 for (temp = (BUF); *temp; temp++) \
76 if (*temp == ':') *temp = '_'; \
80 /* These need specifying. */
81 #ifndef OBJC_FORWARDING_STACK_OFFSET
82 #define OBJC_FORWARDING_STACK_OFFSET 0
85 #ifndef OBJC_FORWARDING_MIN_OFFSET
86 #define OBJC_FORWARDING_MIN_OFFSET 0
89 /* Define the special tree codes that we use. */
91 /* Table indexed by tree code giving a string containing a character
92 classifying the tree code. */
94 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
96 static const char objc_tree_code_type
[] = {
98 #include "objc-tree.def"
102 /* Table indexed by tree code giving number of expression
103 operands beyond the fixed part of the node structure.
104 Not used for types or decls. */
106 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
108 static const int objc_tree_code_length
[] = {
110 #include "objc-tree.def"
114 /* Names of tree components.
115 Used for printing out the tree and error messages. */
116 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
118 static const char * const objc_tree_code_name
[] = {
120 #include "objc-tree.def"
124 /* Set up for use of obstacks. */
128 #define obstack_chunk_alloc xmalloc
129 #define obstack_chunk_free free
131 /* This obstack is used to accumulate the encoding of a data type. */
132 static struct obstack util_obstack
;
133 /* This points to the beginning of obstack contents,
134 so we can free the whole contents. */
137 /* for encode_method_def */
140 /* The version identifies which language generation and runtime
141 the module (file) was compiled for, and is recorded in the
142 module descriptor. */
144 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
145 #define PROTOCOL_VERSION 2
147 /* (Decide if these can ever be validly changed.) */
148 #define OBJC_ENCODE_INLINE_DEFS 0
149 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
151 /*** Private Interface (procedures) ***/
153 /* Used by compile_file. */
155 static void init_objc
PARAMS ((void));
156 static void finish_objc
PARAMS ((void));
158 /* Code generation. */
160 static void synth_module_prologue
PARAMS ((void));
161 static tree build_constructor
PARAMS ((tree
, tree
));
162 static rtx build_module_descriptor
PARAMS ((void));
163 static tree init_module_descriptor
PARAMS ((tree
));
164 static tree build_objc_method_call
PARAMS ((int, tree
, tree
,
166 static void generate_strings
PARAMS ((void));
167 static tree get_proto_encoding
PARAMS ((tree
));
168 static void build_selector_translation_table
PARAMS ((void));
169 static tree build_ivar_chain
PARAMS ((tree
, int));
171 static tree objc_add_static_instance
PARAMS ((tree
, tree
));
173 static tree build_ivar_template
PARAMS ((void));
174 static tree build_method_template
PARAMS ((void));
175 static tree build_private_template
PARAMS ((tree
));
176 static void build_class_template
PARAMS ((void));
177 static void build_selector_template
PARAMS ((void));
178 static void build_category_template
PARAMS ((void));
179 static tree build_super_template
PARAMS ((void));
180 static tree build_category_initializer
PARAMS ((tree
, tree
, tree
,
182 static tree build_protocol_initializer
PARAMS ((tree
, tree
, tree
,
185 static void synth_forward_declarations
PARAMS ((void));
186 static void generate_ivar_lists
PARAMS ((void));
187 static void generate_dispatch_tables
PARAMS ((void));
188 static void generate_shared_structures
PARAMS ((void));
189 static tree generate_protocol_list
PARAMS ((tree
));
190 static void generate_forward_declaration_to_string_table
PARAMS ((void));
191 static void build_protocol_reference
PARAMS ((tree
));
193 static tree build_keyword_selector
PARAMS ((tree
));
194 static tree synth_id_with_class_suffix
PARAMS ((const char *, tree
));
196 static void generate_static_references
PARAMS ((void));
197 static int check_methods_accessible
PARAMS ((tree
, tree
,
199 static void encode_aggregate_within
PARAMS ((tree
, int, int,
201 static const char *objc_demangle
PARAMS ((const char *));
202 static const char *objc_printable_name
PARAMS ((tree
, int));
203 static void objc_expand_function_end
PARAMS ((void));
205 /* Hash tables to manage the global pool of method prototypes. */
207 hash
*nst_method_hash_list
= 0;
208 hash
*cls_method_hash_list
= 0;
210 static size_t hash_func
PARAMS ((tree
));
211 static void hash_init
PARAMS ((void));
212 static void hash_enter
PARAMS ((hash
*, tree
));
213 static hash hash_lookup
PARAMS ((hash
*, tree
));
214 static void hash_add_attr
PARAMS ((hash
, tree
));
215 static tree lookup_method
PARAMS ((tree
, tree
));
216 static tree lookup_instance_method_static
PARAMS ((tree
, tree
));
217 static tree lookup_class_method_static
PARAMS ((tree
, tree
));
218 static tree add_class
PARAMS ((tree
));
219 static void add_category
PARAMS ((tree
, tree
));
223 class_names
, /* class, category, protocol, module names */
224 meth_var_names
, /* method and variable names */
225 meth_var_types
/* method and variable type descriptors */
228 static tree add_objc_string
PARAMS ((tree
,
229 enum string_section
));
230 static tree get_objc_string_decl
PARAMS ((tree
,
231 enum string_section
));
232 static tree build_objc_string_decl
PARAMS ((enum string_section
));
233 static tree build_selector_reference_decl
PARAMS ((void));
235 /* Protocol additions. */
237 static tree add_protocol
PARAMS ((tree
));
238 static tree lookup_protocol
PARAMS ((tree
));
239 static void check_protocol_recursively
PARAMS ((tree
, tree
));
240 static tree lookup_and_install_protocols
PARAMS ((tree
));
244 static void encode_type_qualifiers
PARAMS ((tree
));
245 static void encode_pointer
PARAMS ((tree
, int, int));
246 static void encode_array
PARAMS ((tree
, int, int));
247 static void encode_aggregate
PARAMS ((tree
, int, int));
248 static void encode_bitfield
PARAMS ((int));
249 static void encode_type
PARAMS ((tree
, int, int));
250 static void encode_field_decl
PARAMS ((tree
, int, int));
252 static void really_start_method
PARAMS ((tree
, tree
));
253 static int comp_method_with_proto
PARAMS ((tree
, tree
));
254 static int comp_proto_with_proto
PARAMS ((tree
, tree
));
255 static tree get_arg_type_list
PARAMS ((tree
, int, int));
256 static tree expr_last
PARAMS ((tree
));
258 /* Utilities for debugging and error diagnostics. */
260 static void warn_with_method
PARAMS ((const char *, int, tree
));
261 static void error_with_ivar
PARAMS ((const char *, tree
, tree
));
262 static char *gen_method_decl
PARAMS ((tree
, char *));
263 static char *gen_declaration
PARAMS ((tree
, char *));
264 static void gen_declaration_1
PARAMS ((tree
, char *));
265 static char *gen_declarator
PARAMS ((tree
, char *,
267 static int is_complex_decl
PARAMS ((tree
));
268 static void adorn_decl
PARAMS ((tree
, char *));
269 static void dump_interface
PARAMS ((FILE *, tree
));
271 /* Everything else. */
273 static void add_objc_tree_codes
PARAMS ((void));
274 static tree define_decl
PARAMS ((tree
, tree
));
275 static tree lookup_method_in_protocol_list
PARAMS ((tree
, tree
, int));
276 static tree lookup_protocol_in_reflist
PARAMS ((tree
, tree
));
277 static tree create_builtin_decl
PARAMS ((enum tree_code
,
278 tree
, const char *));
279 static void setup_string_decl
PARAMS ((void));
280 static void build_string_class_template
PARAMS ((void));
281 static tree my_build_string
PARAMS ((int, const char *));
282 static void build_objc_symtab_template
PARAMS ((void));
283 static tree init_def_list
PARAMS ((tree
));
284 static tree init_objc_symtab
PARAMS ((tree
));
285 static void forward_declare_categories
PARAMS ((void));
286 static void generate_objc_symtab_decl
PARAMS ((void));
287 static tree build_selector
PARAMS ((tree
));
288 static tree build_typed_selector_reference
PARAMS ((tree
, tree
));
289 static tree build_selector_reference
PARAMS ((tree
));
290 static tree build_class_reference_decl
PARAMS ((void));
291 static void add_class_reference
PARAMS ((tree
));
292 static tree objc_copy_list
PARAMS ((tree
, tree
*));
293 static tree build_protocol_template
PARAMS ((void));
294 static tree build_descriptor_table_initializer
PARAMS ((tree
, tree
));
295 static tree build_method_prototype_list_template
PARAMS ((tree
, int));
296 static tree build_method_prototype_template
PARAMS ((void));
297 static int forwarding_offset
PARAMS ((tree
));
298 static tree encode_method_prototype
PARAMS ((tree
, tree
));
299 static tree generate_descriptor_table
PARAMS ((tree
, const char *,
301 static void generate_method_descriptors
PARAMS ((tree
));
302 static tree build_tmp_function_decl
PARAMS ((void));
303 static void hack_method_prototype
PARAMS ((tree
, tree
));
304 static void generate_protocol_references
PARAMS ((tree
));
305 static void generate_protocols
PARAMS ((void));
306 static void check_ivars
PARAMS ((tree
, tree
));
307 static tree build_ivar_list_template
PARAMS ((tree
, int));
308 static tree build_method_list_template
PARAMS ((tree
, int));
309 static tree build_ivar_list_initializer
PARAMS ((tree
, tree
));
310 static tree generate_ivars_list
PARAMS ((tree
, const char *,
312 static tree build_dispatch_table_initializer
PARAMS ((tree
, tree
));
313 static tree generate_dispatch_table
PARAMS ((tree
, const char *,
315 static tree build_shared_structure_initializer
PARAMS ((tree
, tree
, tree
, tree
,
316 tree
, int, tree
, tree
,
318 static void generate_category
PARAMS ((tree
));
319 static int is_objc_type_qualifier
PARAMS ((tree
));
320 static tree adjust_type_for_id_default
PARAMS ((tree
));
321 static tree check_duplicates
PARAMS ((hash
));
322 static tree receiver_is_class_object
PARAMS ((tree
));
323 static int check_methods
PARAMS ((tree
, tree
, int));
324 static int conforms_to_protocol
PARAMS ((tree
, tree
));
325 static void check_protocol
PARAMS ((tree
, const char *,
327 static void check_protocols
PARAMS ((tree
, const char *,
329 static tree encode_method_def
PARAMS ((tree
));
330 static void gen_declspecs
PARAMS ((tree
, char *, int));
331 static void generate_classref_translation_entry
PARAMS ((tree
));
332 static void handle_class_ref
PARAMS ((tree
));
333 static void generate_struct_by_value_array
PARAMS ((void))
335 static void objc_act_parse_init
PARAMS ((void));
336 static void ggc_mark_imp_list
PARAMS ((void *));
337 static void ggc_mark_hash_table
PARAMS ((void *));
339 /*** Private Interface (data) ***/
341 /* Reserved tag definitions. */
344 #define TAG_OBJECT "objc_object"
345 #define TAG_CLASS "objc_class"
346 #define TAG_SUPER "objc_super"
347 #define TAG_SELECTOR "objc_selector"
349 #define UTAG_CLASS "_objc_class"
350 #define UTAG_IVAR "_objc_ivar"
351 #define UTAG_IVAR_LIST "_objc_ivar_list"
352 #define UTAG_METHOD "_objc_method"
353 #define UTAG_METHOD_LIST "_objc_method_list"
354 #define UTAG_CATEGORY "_objc_category"
355 #define UTAG_MODULE "_objc_module"
356 #define UTAG_STATICS "_objc_statics"
357 #define UTAG_SYMTAB "_objc_symtab"
358 #define UTAG_SUPER "_objc_super"
359 #define UTAG_SELECTOR "_objc_selector"
361 #define UTAG_PROTOCOL "_objc_protocol"
362 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
363 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
364 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
366 /* Note that the string object global name is only needed for the
368 #define STRING_OBJECT_GLOBAL_NAME "_NSConstantStringClassReference"
370 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
372 static const char *constant_string_class_name
= NULL
;
374 static const char *TAG_GETCLASS
;
375 static const char *TAG_GETMETACLASS
;
376 static const char *TAG_MSGSEND
;
377 static const char *TAG_MSGSENDSUPER
;
378 static const char *TAG_EXECCLASS
;
379 static const char *default_constant_string_class_name
;
381 /* The OCTI_... enumeration itself is in objc/objc-act.h. */
382 tree objc_global_trees
[OCTI_MAX
];
384 int objc_receiver_context
;
386 static void handle_impent
PARAMS ((struct imp_entry
*));
388 struct imp_entry
*imp_list
= 0;
389 int imp_count
= 0; /* `@implementation' */
390 int cat_count
= 0; /* `@category' */
392 static int method_slot
= 0; /* Used by start_method_def, */
396 static char *errbuf
; /* Buffer for error diagnostics */
398 /* Data imported from tree.c. */
400 extern enum debug_info_type write_symbols
;
402 /* Data imported from toplev.c. */
404 extern const char *dump_base_name
;
406 /* Generate code for GNU or NeXT runtime environment. */
408 #ifdef NEXT_OBJC_RUNTIME
409 int flag_next_runtime
= 1;
411 int flag_next_runtime
= 0;
414 int flag_typed_selectors
;
416 /* Open and close the file for outputting class declarations, if requested. */
418 int flag_gen_declaration
= 0;
420 FILE *gen_declaration_file
;
422 /* Warn if multiple methods are seen for the same selector, but with
423 different argument types. */
425 int warn_selector
= 0;
427 /* Warn if methods required by a protocol are not implemented in the
428 class adopting it. When turned off, methods inherited to that
429 class are also considered implemented */
431 int flag_warn_protocol
= 1;
433 /* Tells "encode_pointer/encode_aggregate" whether we are generating
434 type descriptors for instance variables (as opposed to methods).
435 Type descriptors for instance variables contain more information
436 than methods (for static typing and embedded structures). */
438 static int generating_instance_variables
= 0;
440 /* Tells the compiler that this is a special run. Do not perform any
441 compiling, instead we are to test some platform dependent features
442 and output a C header file with appropriate definitions. */
444 static int print_struct_values
= 0;
446 /* Some platforms pass small structures through registers versus
447 through an invisible pointer. Determine at what size structure is
448 the transition point between the two possibilities. */
451 generate_struct_by_value_array ()
454 tree field_decl
, field_decl_chain
;
456 int aggregate_in_mem
[32];
459 /* Presumably no platform passes 32 byte structures in a register. */
460 for (i
= 1; i
< 32; i
++)
464 /* Create an unnamed struct that has `i' character components */
465 type
= start_struct (RECORD_TYPE
, NULL_TREE
);
467 strcpy (buffer
, "c1");
468 field_decl
= create_builtin_decl (FIELD_DECL
,
471 field_decl_chain
= field_decl
;
473 for (j
= 1; j
< i
; j
++)
475 sprintf (buffer
, "c%d", j
+ 1);
476 field_decl
= create_builtin_decl (FIELD_DECL
,
479 chainon (field_decl_chain
, field_decl
);
481 finish_struct (type
, field_decl_chain
, NULL_TREE
);
483 aggregate_in_mem
[i
] = aggregate_value_p (type
);
484 if (!aggregate_in_mem
[i
])
488 /* We found some structures that are returned in registers instead of memory
489 so output the necessary data. */
492 for (i
= 31; i
>= 0; i
--)
493 if (!aggregate_in_mem
[i
])
495 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i
);
497 /* The first member of the structure is always 0 because we don't handle
498 structures with 0 members */
499 printf ("static int struct_forward_array[] = {\n 0");
501 for (j
= 1; j
<= i
; j
++)
502 printf (", %d", aggregate_in_mem
[j
]);
511 const char *filename
;
513 filename
= c_objc_common_init (filename
);
514 add_objc_tree_codes ();
516 decl_printable_name
= objc_printable_name
;
518 /* Force the line number back to 0; check_newline will have
519 raised it to 1, which will make the builtin functions appear
520 not to be built in. */
523 /* If gen_declaration desired, open the output file. */
524 if (flag_gen_declaration
)
526 register char * const dumpname
= concat (dump_base_name
, ".decl", NULL
);
527 gen_declaration_file
= fopen (dumpname
, "w");
528 if (gen_declaration_file
== 0)
529 fatal_io_error ("can't open %s", dumpname
);
533 if (flag_next_runtime
)
535 TAG_GETCLASS
= "objc_getClass";
536 TAG_GETMETACLASS
= "objc_getMetaClass";
537 TAG_MSGSEND
= "objc_msgSend";
538 TAG_MSGSENDSUPER
= "objc_msgSendSuper";
539 TAG_EXECCLASS
= "__objc_execClass";
540 default_constant_string_class_name
= "NSConstantString";
544 TAG_GETCLASS
= "objc_get_class";
545 TAG_GETMETACLASS
= "objc_get_meta_class";
546 TAG_MSGSEND
= "objc_msg_lookup";
547 TAG_MSGSENDSUPER
= "objc_msg_lookup_super";
548 TAG_EXECCLASS
= "__objc_exec_class";
549 default_constant_string_class_name
= "NXConstantString";
550 flag_typed_selectors
= 1;
553 objc_ellipsis_node
= make_node (ERROR_MARK
);
557 if (print_struct_values
)
558 generate_struct_by_value_array ();
560 objc_act_parse_init ();
568 c_objc_common_finish_file ();
570 finish_objc (); /* Objective-C finalization */
572 if (gen_declaration_file
)
573 fclose (gen_declaration_file
);
577 objc_decode_option (argc
, argv
)
581 const char *p
= argv
[0];
583 if (!strcmp (p
, "-gen-decls"))
584 flag_gen_declaration
= 1;
585 else if (!strcmp (p
, "-Wselector"))
587 else if (!strcmp (p
, "-Wno-selector"))
589 else if (!strcmp (p
, "-Wprotocol"))
590 flag_warn_protocol
= 1;
591 else if (!strcmp (p
, "-Wno-protocol"))
592 flag_warn_protocol
= 0;
593 else if (!strcmp (p
, "-fgnu-runtime"))
594 flag_next_runtime
= 0;
595 else if (!strcmp (p
, "-fno-next-runtime"))
596 flag_next_runtime
= 0;
597 else if (!strcmp (p
, "-fno-gnu-runtime"))
598 flag_next_runtime
= 1;
599 else if (!strcmp (p
, "-fnext-runtime"))
600 flag_next_runtime
= 1;
601 else if (!strcmp (p
, "-print-objc-runtime-info"))
602 print_struct_values
= 1;
603 #define CSTSTRCLASS "-fconstant-string-class="
604 else if (!strncmp (p
, CSTSTRCLASS
, sizeof(CSTSTRCLASS
) - 2)) {
605 if (strlen (argv
[0]) <= strlen (CSTSTRCLASS
))
606 error ("no class name specified as argument to -fconstant-string-class");
607 constant_string_class_name
= xstrdup(argv
[0] + sizeof(CSTSTRCLASS
) - 1);
611 return c_decode_option (argc
, argv
);
618 define_decl (declarator
, declspecs
)
622 tree decl
= start_decl (declarator
, declspecs
, 0, NULL_TREE
);
623 finish_decl (decl
, NULL_TREE
, NULL_TREE
);
627 /* Return 1 if LHS and RHS are compatible types for assignment or
628 various other operations. Return 0 if they are incompatible, and
629 return -1 if we choose to not decide. When the operation is
630 REFLEXIVE, check for compatibility in either direction.
632 For statically typed objects, an assignment of the form `a' = `b'
636 `a' and `b' are the same class type, or
637 `a' and `b' are of class types A and B such that B is a descendant of A. */
640 maybe_objc_comptypes (lhs
, rhs
, reflexive
)
644 return objc_comptypes (lhs
, rhs
, reflexive
);
648 lookup_method_in_protocol_list (rproto_list
, sel_name
, class_meth
)
656 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
658 p
= TREE_VALUE (rproto
);
660 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
662 if ((fnd
= lookup_method (class_meth
663 ? PROTOCOL_CLS_METHODS (p
)
664 : PROTOCOL_NST_METHODS (p
), sel_name
)))
666 else if (PROTOCOL_LIST (p
))
667 fnd
= lookup_method_in_protocol_list (PROTOCOL_LIST (p
),
668 sel_name
, class_meth
);
672 ; /* An identifier...if we could not find a protocol. */
683 lookup_protocol_in_reflist (rproto_list
, lproto
)
689 /* Make sure the protocol is supported by the object on the rhs. */
690 if (TREE_CODE (lproto
) == PROTOCOL_INTERFACE_TYPE
)
693 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
695 p
= TREE_VALUE (rproto
);
697 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
702 else if (PROTOCOL_LIST (p
))
703 fnd
= lookup_protocol_in_reflist (PROTOCOL_LIST (p
), lproto
);
712 ; /* An identifier...if we could not find a protocol. */
718 /* Return 1 if LHS and RHS are compatible types for assignment
719 or various other operations. Return 0 if they are incompatible,
720 and return -1 if we choose to not decide. When the operation
721 is REFLEXIVE, check for compatibility in either direction. */
724 objc_comptypes (lhs
, rhs
, reflexive
)
729 /* New clause for protocols. */
731 if (TREE_CODE (lhs
) == POINTER_TYPE
732 && TREE_CODE (TREE_TYPE (lhs
)) == RECORD_TYPE
733 && TREE_CODE (rhs
) == POINTER_TYPE
734 && TREE_CODE (TREE_TYPE (rhs
)) == RECORD_TYPE
)
736 int lhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (lhs
);
737 int rhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (rhs
);
741 tree lproto
, lproto_list
= TYPE_PROTOCOL_LIST (lhs
);
742 tree rproto
, rproto_list
;
747 rproto_list
= TYPE_PROTOCOL_LIST (rhs
);
749 /* Make sure the protocol is supported by the object
751 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
753 p
= TREE_VALUE (lproto
);
754 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
757 warning ("object does not conform to the `%s' protocol",
758 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
761 else if (TYPED_OBJECT (TREE_TYPE (rhs
)))
763 tree rname
= TYPE_NAME (TREE_TYPE (rhs
));
766 /* Make sure the protocol is supported by the object
768 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
770 p
= TREE_VALUE (lproto
);
772 rinter
= lookup_interface (rname
);
774 while (rinter
&& !rproto
)
778 rproto_list
= CLASS_PROTOCOL_LIST (rinter
);
779 /* If the underlying ObjC class does not have
780 protocols attached to it, perhaps there are
781 "one-off" protocols attached to the rhs?
782 E.g., 'id<MyProt> foo;'. */
784 rproto_list
= TYPE_PROTOCOL_LIST (TREE_TYPE (rhs
));
785 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
787 /* Check for protocols adopted by categories. */
788 cat
= CLASS_CATEGORY_LIST (rinter
);
789 while (cat
&& !rproto
)
791 rproto_list
= CLASS_PROTOCOL_LIST (cat
);
792 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
794 cat
= CLASS_CATEGORY_LIST (cat
);
797 rinter
= lookup_interface (CLASS_SUPER_NAME (rinter
));
801 warning ("class `%s' does not implement the `%s' protocol",
802 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs
))),
803 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
807 /* May change...based on whether there was any mismatch */
810 else if (rhs_is_proto
)
811 /* Lhs is not a protocol...warn if it is statically typed */
812 return (TYPED_OBJECT (TREE_TYPE (lhs
)) != 0);
815 /* Defer to comptypes. */
819 else if (TREE_CODE (lhs
) == RECORD_TYPE
&& TREE_CODE (rhs
) == RECORD_TYPE
)
820 ; /* Fall thru. This is the case we have been handling all along */
822 /* Defer to comptypes. */
825 /* `id' = `<class> *', `<class> *' = `id' */
827 if ((TYPE_NAME (lhs
) == objc_object_id
&& TYPED_OBJECT (rhs
))
828 || (TYPE_NAME (rhs
) == objc_object_id
&& TYPED_OBJECT (lhs
)))
831 /* `id' = `Class', `Class' = `id' */
833 else if ((TYPE_NAME (lhs
) == objc_object_id
834 && TYPE_NAME (rhs
) == objc_class_id
)
835 || (TYPE_NAME (lhs
) == objc_class_id
836 && TYPE_NAME (rhs
) == objc_object_id
))
839 /* `<class> *' = `<class> *' */
841 else if (TYPED_OBJECT (lhs
) && TYPED_OBJECT (rhs
))
843 tree lname
= TYPE_NAME (lhs
);
844 tree rname
= TYPE_NAME (rhs
);
850 /* If the left hand side is a super class of the right hand side,
852 for (inter
= lookup_interface (rname
); inter
;
853 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
854 if (lname
== CLASS_SUPER_NAME (inter
))
857 /* Allow the reverse when reflexive. */
859 for (inter
= lookup_interface (lname
); inter
;
860 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
861 if (rname
== CLASS_SUPER_NAME (inter
))
867 /* Defer to comptypes. */
871 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
874 objc_check_decl (decl
)
877 tree type
= TREE_TYPE (decl
);
879 if (TREE_CODE (type
) == RECORD_TYPE
880 && TREE_STATIC_TEMPLATE (type
)
881 && type
!= constant_string_type
)
882 error_with_decl (decl
, "`%s' cannot be statically allocated");
886 maybe_objc_check_decl (decl
)
889 objc_check_decl (decl
);
892 /* Implement static typing. At this point, we know we have an interface. */
895 get_static_reference (interface
, protocols
)
899 tree type
= xref_tag (RECORD_TYPE
, interface
);
903 tree t
, m
= TYPE_MAIN_VARIANT (type
);
905 t
= copy_node (type
);
906 TYPE_BINFO (t
) = make_tree_vec (2);
908 /* Add this type to the chain of variants of TYPE. */
909 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
910 TYPE_NEXT_VARIANT (m
) = t
;
912 /* Look up protocols and install in lang specific list. Note
913 that the protocol list can have a different lifetime than T! */
914 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
916 /* This forces a new pointer type to be created later
917 (in build_pointer_type)...so that the new template
918 we just created will actually be used...what a hack! */
919 if (TYPE_POINTER_TO (t
))
920 TYPE_POINTER_TO (t
) = NULL_TREE
;
929 get_object_reference (protocols
)
932 tree type_decl
= lookup_name (objc_id_id
);
935 if (type_decl
&& TREE_CODE (type_decl
) == TYPE_DECL
)
937 type
= TREE_TYPE (type_decl
);
938 if (TYPE_MAIN_VARIANT (type
) != id_type
)
939 warning ("unexpected type for `id' (%s)",
940 gen_declaration (type
, errbuf
));
944 error ("undefined type `id', please import <objc/objc.h>");
945 return error_mark_node
;
948 /* This clause creates a new pointer type that is qualified with
949 the protocol specification...this info is used later to do more
950 elaborate type checking. */
954 tree t
, m
= TYPE_MAIN_VARIANT (type
);
956 t
= copy_node (type
);
957 TYPE_BINFO (t
) = make_tree_vec (2);
959 /* Add this type to the chain of variants of TYPE. */
960 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
961 TYPE_NEXT_VARIANT (m
) = t
;
963 /* Look up protocols...and install in lang specific list */
964 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
966 /* This forces a new pointer type to be created later
967 (in build_pointer_type)...so that the new template
968 we just created will actually be used...what a hack! */
969 if (TYPE_POINTER_TO (t
))
970 TYPE_POINTER_TO (t
) = NULL_TREE
;
977 /* Check for circular dependencies in protocols. The arguments are
978 PROTO, the protocol to check, and LIST, a list of protocol it
982 check_protocol_recursively (proto
, list
)
988 for (p
= list
; p
; p
= TREE_CHAIN (p
))
990 tree pp
= TREE_VALUE (p
);
992 if (TREE_CODE (pp
) == IDENTIFIER_NODE
)
993 pp
= lookup_protocol (pp
);
996 fatal_error ("protocol `%s' has circular dependency",
997 IDENTIFIER_POINTER (PROTOCOL_NAME (pp
)));
999 check_protocol_recursively (proto
, PROTOCOL_LIST (pp
));
1004 lookup_and_install_protocols (protocols
)
1009 tree return_value
= protocols
;
1011 for (proto
= protocols
; proto
; proto
= TREE_CHAIN (proto
))
1013 tree ident
= TREE_VALUE (proto
);
1014 tree p
= lookup_protocol (ident
);
1018 error ("cannot find protocol declaration for `%s'",
1019 IDENTIFIER_POINTER (ident
));
1021 TREE_CHAIN (prev
) = TREE_CHAIN (proto
);
1023 return_value
= TREE_CHAIN (proto
);
1027 /* Replace identifier with actual protocol node. */
1028 TREE_VALUE (proto
) = p
;
1033 return return_value
;
1036 /* Create and push a decl for a built-in external variable or field NAME.
1038 TYPE is its data type. */
1041 create_builtin_decl (code
, type
, name
)
1042 enum tree_code code
;
1046 tree decl
= build_decl (code
, get_identifier (name
), type
);
1048 if (code
== VAR_DECL
)
1050 TREE_STATIC (decl
) = 1;
1051 make_decl_rtl (decl
, 0);
1055 DECL_ARTIFICIAL (decl
) = 1;
1059 /* Find the decl for the constant string class. */
1062 setup_string_decl ()
1064 if (!string_class_decl
)
1066 if (!constant_string_global_id
)
1067 constant_string_global_id
= get_identifier (STRING_OBJECT_GLOBAL_NAME
);
1068 string_class_decl
= lookup_name (constant_string_global_id
);
1072 /* Purpose: "play" parser, creating/installing representations
1073 of the declarations that are required by Objective-C.
1077 type_spec--------->sc_spec
1078 (tree_list) (tree_list)
1081 identifier_node identifier_node */
1084 synth_module_prologue ()
1089 /* Defined in `objc.h' */
1090 objc_object_id
= get_identifier (TAG_OBJECT
);
1092 objc_object_reference
= xref_tag (RECORD_TYPE
, objc_object_id
);
1094 id_type
= build_pointer_type (objc_object_reference
);
1096 objc_id_id
= get_identifier (TYPE_ID
);
1097 objc_class_id
= get_identifier (TAG_CLASS
);
1099 objc_class_type
= build_pointer_type (xref_tag (RECORD_TYPE
, objc_class_id
));
1100 protocol_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
1101 get_identifier (PROTOCOL_OBJECT_CLASS_NAME
)));
1103 /* Declare type of selector-objects that represent an operation name. */
1105 /* `struct objc_selector *' */
1107 = build_pointer_type (xref_tag (RECORD_TYPE
,
1108 get_identifier (TAG_SELECTOR
)));
1110 /* Forward declare type, or else the prototype for msgSendSuper will
1113 super_p
= build_pointer_type (xref_tag (RECORD_TYPE
,
1114 get_identifier (TAG_SUPER
)));
1117 /* id objc_msgSend (id, SEL, ...); */
1120 = build_function_type (id_type
,
1121 tree_cons (NULL_TREE
, id_type
,
1122 tree_cons (NULL_TREE
, selector_type
,
1125 if (! flag_next_runtime
)
1127 umsg_decl
= build_decl (FUNCTION_DECL
,
1128 get_identifier (TAG_MSGSEND
), temp_type
);
1129 DECL_EXTERNAL (umsg_decl
) = 1;
1130 TREE_PUBLIC (umsg_decl
) = 1;
1131 DECL_INLINE (umsg_decl
) = 1;
1132 DECL_ARTIFICIAL (umsg_decl
) = 1;
1134 if (flag_traditional
&& TAG_MSGSEND
[0] != '_')
1135 DECL_BUILT_IN_NONANSI (umsg_decl
) = 1;
1137 make_decl_rtl (umsg_decl
, NULL
);
1138 pushdecl (umsg_decl
);
1141 umsg_decl
= builtin_function (TAG_MSGSEND
, temp_type
, 0, NOT_BUILT_IN
, 0);
1143 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1146 = build_function_type (id_type
,
1147 tree_cons (NULL_TREE
, super_p
,
1148 tree_cons (NULL_TREE
, selector_type
,
1151 umsg_super_decl
= builtin_function (TAG_MSGSENDSUPER
,
1152 temp_type
, 0, NOT_BUILT_IN
, 0);
1154 /* id objc_getClass (const char *); */
1156 temp_type
= build_function_type (id_type
,
1157 tree_cons (NULL_TREE
,
1158 const_string_type_node
,
1159 tree_cons (NULL_TREE
, void_type_node
,
1163 = builtin_function (TAG_GETCLASS
, temp_type
, 0, NOT_BUILT_IN
, 0);
1165 /* id objc_getMetaClass (const char *); */
1167 objc_get_meta_class_decl
1168 = builtin_function (TAG_GETMETACLASS
, temp_type
, 0, NOT_BUILT_IN
, 0);
1170 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1172 if (! flag_next_runtime
)
1174 if (flag_typed_selectors
)
1176 /* Suppress outputting debug symbols, because
1177 dbxout_init hasn'r been called yet. */
1178 enum debug_info_type save_write_symbols
= write_symbols
;
1179 struct gcc_debug_hooks
*save_hooks
= debug_hooks
;
1180 write_symbols
= NO_DEBUG
;
1181 debug_hooks
= &do_nothing_debug_hooks
;
1183 build_selector_template ();
1184 temp_type
= build_array_type (objc_selector_template
, NULL_TREE
);
1186 write_symbols
= save_write_symbols
;
1187 debug_hooks
= save_hooks
;
1190 temp_type
= build_array_type (selector_type
, NULL_TREE
);
1192 layout_type (temp_type
);
1193 UOBJC_SELECTOR_TABLE_decl
1194 = create_builtin_decl (VAR_DECL
, temp_type
,
1195 "_OBJC_SELECTOR_TABLE");
1197 /* Avoid warning when not sending messages. */
1198 TREE_USED (UOBJC_SELECTOR_TABLE_decl
) = 1;
1201 generate_forward_declaration_to_string_table ();
1203 /* Forward declare constant_string_id and constant_string_type. */
1204 if (!constant_string_class_name
)
1205 constant_string_class_name
= default_constant_string_class_name
;
1207 constant_string_id
= get_identifier (constant_string_class_name
);
1208 constant_string_type
= xref_tag (RECORD_TYPE
, constant_string_id
);
1211 /* Predefine the following data type:
1213 struct STRING_OBJECT_CLASS_NAME
1217 unsigned int length;
1221 build_string_class_template ()
1223 tree field_decl
, field_decl_chain
;
1225 field_decl
= create_builtin_decl (FIELD_DECL
, id_type
, "isa");
1226 field_decl_chain
= field_decl
;
1228 field_decl
= create_builtin_decl (FIELD_DECL
,
1229 build_pointer_type (char_type_node
),
1231 chainon (field_decl_chain
, field_decl
);
1233 field_decl
= create_builtin_decl (FIELD_DECL
, unsigned_type_node
, "length");
1234 chainon (field_decl_chain
, field_decl
);
1236 finish_struct (constant_string_type
, field_decl_chain
, NULL_TREE
);
1239 /* Custom build_string which sets TREE_TYPE! */
1242 my_build_string (len
, str
)
1247 tree a_string
= build_string (len
, str
);
1249 /* Some code from combine_strings, which is local to c-parse.y. */
1250 if (TREE_TYPE (a_string
) == int_array_type_node
)
1253 TREE_TYPE (a_string
)
1254 = build_array_type (wide_flag
? integer_type_node
: char_type_node
,
1255 build_index_type (build_int_2 (len
- 1, 0)));
1257 TREE_CONSTANT (a_string
) = 1; /* Puts string in the readonly segment */
1258 TREE_STATIC (a_string
) = 1;
1263 /* Given a chain of STRING_CST's, build a static instance of
1264 NXConstantString which points at the concatenation of those strings.
1265 We place the string object in the __string_objects section of the
1266 __OBJC segment. The Objective-C runtime will initialize the isa
1267 pointers of the string objects to point at the NXConstantString
1271 build_objc_string_object (strings
)
1274 tree string
, initlist
, constructor
;
1277 if (lookup_interface (constant_string_id
) == NULL_TREE
)
1279 error ("cannot find interface declaration for `%s'",
1280 IDENTIFIER_POINTER (constant_string_id
));
1281 return error_mark_node
;
1284 add_class_reference (constant_string_id
);
1286 string
= combine_strings (strings
);
1287 TREE_SET_CODE (string
, STRING_CST
);
1288 length
= TREE_STRING_LENGTH (string
) - 1;
1290 /* We could not properly create NXConstantString in synth_module_prologue,
1291 because that's called before debugging is initialized. Do it now. */
1292 if (TYPE_FIELDS (constant_string_type
) == NULL_TREE
)
1293 build_string_class_template ();
1295 /* & ((NXConstantString) { NULL, string, length }) */
1297 if (flag_next_runtime
)
1299 /* For the NeXT runtime, we can generate a literal reference
1300 to the string class, don't need to run a constructor. */
1301 setup_string_decl ();
1302 if (string_class_decl
== NULL_TREE
)
1304 error ("cannot find reference tag for class `%s'",
1305 IDENTIFIER_POINTER (constant_string_id
));
1306 return error_mark_node
;
1308 initlist
= build_tree_list
1310 copy_node (build_unary_op (ADDR_EXPR
, string_class_decl
, 0)));
1314 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1318 = tree_cons (NULL_TREE
, copy_node (build_unary_op (ADDR_EXPR
, string
, 1)),
1320 initlist
= tree_cons (NULL_TREE
, build_int_2 (length
, 0), initlist
);
1321 constructor
= build_constructor (constant_string_type
, nreverse (initlist
));
1323 if (!flag_next_runtime
)
1326 = objc_add_static_instance (constructor
, constant_string_type
);
1329 return (build_unary_op (ADDR_EXPR
, constructor
, 1));
1332 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1335 objc_add_static_instance (constructor
, class_decl
)
1336 tree constructor
, class_decl
;
1338 static int num_static_inst
;
1342 /* Find the list of static instances for the CLASS_DECL. Create one if
1344 for (chain
= &objc_static_instances
;
1345 *chain
&& TREE_VALUE (*chain
) != class_decl
;
1346 chain
= &TREE_CHAIN (*chain
));
1349 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
1350 add_objc_string (TYPE_NAME (class_decl
), class_names
);
1353 sprintf (buf
, "_OBJC_INSTANCE_%d", num_static_inst
++);
1354 decl
= build_decl (VAR_DECL
, get_identifier (buf
), class_decl
);
1355 DECL_COMMON (decl
) = 1;
1356 TREE_STATIC (decl
) = 1;
1357 DECL_ARTIFICIAL (decl
) = 1;
1358 DECL_INITIAL (decl
) = constructor
;
1360 /* We may be writing something else just now.
1361 Postpone till end of input. */
1362 DECL_DEFER_OUTPUT (decl
) = 1;
1363 pushdecl_top_level (decl
);
1364 rest_of_decl_compilation (decl
, 0, 1, 0);
1366 /* Add the DECL to the head of this CLASS' list. */
1367 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
1372 /* Build a static constant CONSTRUCTOR
1373 with type TYPE and elements ELTS. */
1376 build_constructor (type
, elts
)
1379 tree constructor
, f
, e
;
1381 /* ??? Most of the places that we build constructors, we don't fill in
1382 the type of integers properly. Convert them all en masse. */
1383 if (TREE_CODE (type
) == ARRAY_TYPE
)
1385 f
= TREE_TYPE (type
);
1386 if (TREE_CODE (f
) == POINTER_TYPE
|| TREE_CODE (f
) == INTEGER_TYPE
)
1387 for (e
= elts
; e
; e
= TREE_CHAIN (e
))
1388 TREE_VALUE (e
) = convert (f
, TREE_VALUE (e
));
1392 f
= TYPE_FIELDS (type
);
1393 for (e
= elts
; e
; e
= TREE_CHAIN (e
), f
= TREE_CHAIN (f
))
1394 if (TREE_CODE (TREE_TYPE (f
)) == POINTER_TYPE
1395 || TREE_CODE (TREE_TYPE (f
)) == INTEGER_TYPE
)
1396 TREE_VALUE (e
) = convert (TREE_TYPE (f
), TREE_VALUE (e
));
1399 constructor
= build (CONSTRUCTOR
, type
, NULL_TREE
, elts
);
1400 TREE_CONSTANT (constructor
) = 1;
1401 TREE_STATIC (constructor
) = 1;
1402 TREE_READONLY (constructor
) = 1;
1407 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1409 /* Predefine the following data type:
1417 void *defs[cls_def_cnt + cat_def_cnt];
1421 build_objc_symtab_template ()
1423 tree field_decl
, field_decl_chain
, index
;
1425 objc_symtab_template
1426 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SYMTAB
));
1428 /* long sel_ref_cnt; */
1430 field_decl
= create_builtin_decl (FIELD_DECL
,
1431 long_integer_type_node
,
1433 field_decl_chain
= field_decl
;
1437 field_decl
= create_builtin_decl (FIELD_DECL
,
1438 build_pointer_type (selector_type
),
1440 chainon (field_decl_chain
, field_decl
);
1442 /* short cls_def_cnt; */
1444 field_decl
= create_builtin_decl (FIELD_DECL
,
1445 short_integer_type_node
,
1447 chainon (field_decl_chain
, field_decl
);
1449 /* short cat_def_cnt; */
1451 field_decl
= create_builtin_decl (FIELD_DECL
,
1452 short_integer_type_node
,
1454 chainon (field_decl_chain
, field_decl
);
1456 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1458 if (!flag_next_runtime
)
1459 index
= build_index_type (build_int_2 (imp_count
+ cat_count
, 0));
1461 index
= build_index_type (build_int_2 (imp_count
+ cat_count
- 1,
1462 imp_count
== 0 && cat_count
== 0
1464 field_decl
= create_builtin_decl (FIELD_DECL
,
1465 build_array_type (ptr_type_node
, index
),
1467 chainon (field_decl_chain
, field_decl
);
1469 finish_struct (objc_symtab_template
, field_decl_chain
, NULL_TREE
);
1472 /* Create the initial value for the `defs' field of _objc_symtab.
1473 This is a CONSTRUCTOR. */
1476 init_def_list (type
)
1479 tree expr
, initlist
= NULL_TREE
;
1480 struct imp_entry
*impent
;
1483 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1485 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
1487 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1488 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1493 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1495 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1497 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1498 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1502 if (!flag_next_runtime
)
1504 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1507 if (static_instances_decl
)
1508 expr
= build_unary_op (ADDR_EXPR
, static_instances_decl
, 0);
1510 expr
= build_int_2 (0, 0);
1512 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1515 return build_constructor (type
, nreverse (initlist
));
1518 /* Construct the initial value for all of _objc_symtab. */
1521 init_objc_symtab (type
)
1526 /* sel_ref_cnt = { ..., 5, ... } */
1528 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1530 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1532 if (flag_next_runtime
|| ! sel_ref_chain
)
1533 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1535 initlist
= tree_cons (NULL_TREE
,
1536 build_unary_op (ADDR_EXPR
,
1537 UOBJC_SELECTOR_TABLE_decl
, 1),
1540 /* cls_def_cnt = { ..., 5, ... } */
1542 initlist
= tree_cons (NULL_TREE
, build_int_2 (imp_count
, 0), initlist
);
1544 /* cat_def_cnt = { ..., 5, ... } */
1546 initlist
= tree_cons (NULL_TREE
, build_int_2 (cat_count
, 0), initlist
);
1548 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1550 if (imp_count
|| cat_count
|| static_instances_decl
)
1553 tree field
= TYPE_FIELDS (type
);
1554 field
= TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field
))));
1556 initlist
= tree_cons (NULL_TREE
, init_def_list (TREE_TYPE (field
)),
1560 return build_constructor (type
, nreverse (initlist
));
1563 /* Push forward-declarations of all the categories so that
1564 init_def_list can use them in a CONSTRUCTOR. */
1567 forward_declare_categories ()
1569 struct imp_entry
*impent
;
1570 tree sav
= objc_implementation_context
;
1572 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1574 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1576 /* Set an invisible arg to synth_id_with_class_suffix. */
1577 objc_implementation_context
= impent
->imp_context
;
1579 = create_builtin_decl (VAR_DECL
, objc_category_template
,
1580 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", objc_implementation_context
)));
1583 objc_implementation_context
= sav
;
1586 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1587 and initialized appropriately. */
1590 generate_objc_symtab_decl ()
1594 if (!objc_category_template
)
1595 build_category_template ();
1597 /* forward declare categories */
1599 forward_declare_categories ();
1601 if (!objc_symtab_template
)
1602 build_objc_symtab_template ();
1604 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
1606 UOBJC_SYMBOLS_decl
= start_decl (get_identifier ("_OBJC_SYMBOLS"),
1607 tree_cons (NULL_TREE
,
1608 objc_symtab_template
, sc_spec
),
1612 TREE_USED (UOBJC_SYMBOLS_decl
) = 1;
1613 DECL_IGNORED_P (UOBJC_SYMBOLS_decl
) = 1;
1614 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl
) = 1;
1615 finish_decl (UOBJC_SYMBOLS_decl
,
1616 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)),
1621 init_module_descriptor (type
)
1624 tree initlist
, expr
;
1626 /* version = { 1, ... } */
1628 expr
= build_int_2 (OBJC_VERSION
, 0);
1629 initlist
= build_tree_list (NULL_TREE
, expr
);
1631 /* size = { ..., sizeof (struct objc_module), ... } */
1633 expr
= size_in_bytes (objc_module_template
);
1634 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1636 /* name = { ..., "foo.m", ... } */
1638 expr
= add_objc_string (get_identifier (input_filename
), class_names
);
1639 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1641 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1643 if (UOBJC_SYMBOLS_decl
)
1644 expr
= build_unary_op (ADDR_EXPR
, UOBJC_SYMBOLS_decl
, 0);
1646 expr
= build_int_2 (0, 0);
1647 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1649 return build_constructor (type
, nreverse (initlist
));
1652 /* Write out the data structures to describe Objective C classes defined.
1653 If appropriate, compile and output a setup function to initialize them.
1654 Return a symbol_ref to the function to call to initialize the Objective C
1655 data structures for this file (and perhaps for other files also).
1657 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1660 build_module_descriptor ()
1662 tree decl_specs
, field_decl
, field_decl_chain
;
1664 objc_module_template
1665 = start_struct (RECORD_TYPE
, get_identifier (UTAG_MODULE
));
1669 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1670 field_decl
= get_identifier ("version");
1672 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1673 field_decl_chain
= field_decl
;
1677 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1678 field_decl
= get_identifier ("size");
1680 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1681 chainon (field_decl_chain
, field_decl
);
1685 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
1686 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
1688 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1689 chainon (field_decl_chain
, field_decl
);
1691 /* struct objc_symtab *symtab; */
1693 decl_specs
= get_identifier (UTAG_SYMTAB
);
1694 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
1695 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("symtab"));
1697 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1698 chainon (field_decl_chain
, field_decl
);
1700 finish_struct (objc_module_template
, field_decl_chain
, NULL_TREE
);
1702 /* Create an instance of "objc_module". */
1704 decl_specs
= tree_cons (NULL_TREE
, objc_module_template
,
1705 build_tree_list (NULL_TREE
,
1706 ridpointers
[(int) RID_STATIC
]));
1708 UOBJC_MODULES_decl
= start_decl (get_identifier ("_OBJC_MODULES"),
1709 decl_specs
, 1, NULL_TREE
);
1711 DECL_ARTIFICIAL (UOBJC_MODULES_decl
) = 1;
1712 DECL_IGNORED_P (UOBJC_MODULES_decl
) = 1;
1713 DECL_CONTEXT (UOBJC_MODULES_decl
) = NULL_TREE
;
1715 finish_decl (UOBJC_MODULES_decl
,
1716 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl
)),
1719 /* Mark the decl to avoid "defined but not used" warning. */
1720 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl
) = 1;
1722 /* Generate a constructor call for the module descriptor.
1723 This code was generated by reading the grammar rules
1724 of c-parse.in; Therefore, it may not be the most efficient
1725 way of generating the requisite code. */
1727 if (flag_next_runtime
)
1731 tree parms
, execclass_decl
, decelerator
, void_list_node_1
;
1732 tree init_function_name
, init_function_decl
;
1734 /* Declare void __objc_execClass (void *); */
1736 void_list_node_1
= build_tree_list (NULL_TREE
, void_type_node
);
1737 execclass_decl
= build_decl (FUNCTION_DECL
,
1738 get_identifier (TAG_EXECCLASS
),
1739 build_function_type (void_type_node
,
1740 tree_cons (NULL_TREE
, ptr_type_node
,
1741 void_list_node_1
)));
1742 DECL_EXTERNAL (execclass_decl
) = 1;
1743 DECL_ARTIFICIAL (execclass_decl
) = 1;
1744 TREE_PUBLIC (execclass_decl
) = 1;
1745 pushdecl (execclass_decl
);
1746 rest_of_decl_compilation (execclass_decl
, 0, 0, 0);
1747 assemble_external (execclass_decl
);
1749 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1751 init_function_name
= get_file_function_name ('I');
1752 start_function (void_list_node_1
,
1753 build_nt (CALL_EXPR
, init_function_name
,
1754 tree_cons (NULL_TREE
, NULL_TREE
,
1758 store_parm_decls ();
1760 init_function_decl
= current_function_decl
;
1761 TREE_PUBLIC (init_function_decl
) = ! targetm
.have_ctors_dtors
;
1762 TREE_USED (init_function_decl
) = 1;
1763 /* Don't let this one be deferred. */
1764 DECL_INLINE (init_function_decl
) = 0;
1765 DECL_UNINLINABLE (init_function_decl
) = 1;
1766 current_function_cannot_inline
1767 = "static constructors and destructors cannot be inlined";
1770 = build_tree_list (NULL_TREE
,
1771 build_unary_op (ADDR_EXPR
, UOBJC_MODULES_decl
, 0));
1772 decelerator
= build_function_call (execclass_decl
, parms
);
1774 c_expand_expr_stmt (decelerator
);
1776 finish_function (0);
1778 return XEXP (DECL_RTL (init_function_decl
), 0);
1782 /* extern const char _OBJC_STRINGS[]; */
1785 generate_forward_declaration_to_string_table ()
1787 tree sc_spec
, decl_specs
, expr_decl
;
1789 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_EXTERN
], NULL_TREE
);
1790 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1793 = build_nt (ARRAY_REF
, get_identifier ("_OBJC_STRINGS"), NULL_TREE
);
1795 UOBJC_STRINGS_decl
= define_decl (expr_decl
, decl_specs
);
1798 /* Return the DECL of the string IDENT in the SECTION. */
1801 get_objc_string_decl (ident
, section
)
1803 enum string_section section
;
1807 if (section
== class_names
)
1808 chain
= class_names_chain
;
1809 else if (section
== meth_var_names
)
1810 chain
= meth_var_names_chain
;
1811 else if (section
== meth_var_types
)
1812 chain
= meth_var_types_chain
;
1816 for (; chain
!= 0; chain
= TREE_VALUE (chain
))
1817 if (TREE_VALUE (chain
) == ident
)
1818 return (TREE_PURPOSE (chain
));
1824 /* Output references to all statically allocated objects. Return the DECL
1825 for the array built. */
1828 generate_static_references ()
1830 tree decls
= NULL_TREE
, ident
, decl_spec
, expr_decl
, expr
= NULL_TREE
;
1831 tree class_name
, class, decl
, initlist
;
1832 tree cl_chain
, in_chain
, type
;
1833 int num_inst
, num_class
;
1836 if (flag_next_runtime
)
1839 for (cl_chain
= objc_static_instances
, num_class
= 0;
1840 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
1842 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
1843 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
1845 sprintf (buf
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
1846 ident
= get_identifier (buf
);
1848 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1849 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1850 build_tree_list (NULL_TREE
,
1851 ridpointers
[(int) RID_STATIC
]));
1852 decl
= start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
);
1853 DECL_CONTEXT (decl
) = 0;
1854 DECL_ARTIFICIAL (decl
) = 1;
1856 /* Output {class_name, ...}. */
1857 class = TREE_VALUE (cl_chain
);
1858 class_name
= get_objc_string_decl (TYPE_NAME (class), class_names
);
1859 initlist
= build_tree_list (NULL_TREE
,
1860 build_unary_op (ADDR_EXPR
, class_name
, 1));
1862 /* Output {..., instance, ...}. */
1863 for (in_chain
= TREE_PURPOSE (cl_chain
);
1864 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
1866 expr
= build_unary_op (ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
1867 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1870 /* Output {..., NULL}. */
1871 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1873 expr
= build_constructor (TREE_TYPE (decl
), nreverse (initlist
));
1874 finish_decl (decl
, expr
, NULL_TREE
);
1875 TREE_USED (decl
) = 1;
1877 type
= build_array_type (build_pointer_type (void_type_node
), 0);
1878 decl
= build_decl (VAR_DECL
, ident
, type
);
1879 TREE_USED (decl
) = 1;
1880 TREE_STATIC (decl
) = 1;
1882 = tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, decl
, 1), decls
);
1885 decls
= tree_cons (NULL_TREE
, build_int_2 (0, 0), decls
);
1886 ident
= get_identifier ("_OBJC_STATIC_INSTANCES");
1887 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1888 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1889 build_tree_list (NULL_TREE
,
1890 ridpointers
[(int) RID_STATIC
]));
1891 static_instances_decl
1892 = start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
);
1893 TREE_USED (static_instances_decl
) = 1;
1894 DECL_CONTEXT (static_instances_decl
) = 0;
1895 DECL_ARTIFICIAL (static_instances_decl
) = 1;
1896 expr
= build_constructor (TREE_TYPE (static_instances_decl
),
1898 finish_decl (static_instances_decl
, expr
, NULL_TREE
);
1901 /* Output all strings. */
1906 tree sc_spec
, decl_specs
, expr_decl
;
1907 tree chain
, string_expr
;
1910 for (chain
= class_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1912 string
= TREE_VALUE (chain
);
1913 decl
= TREE_PURPOSE (chain
);
1915 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1916 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1917 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1918 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1919 DECL_CONTEXT (decl
) = NULL_TREE
;
1920 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1921 IDENTIFIER_POINTER (string
));
1922 finish_decl (decl
, string_expr
, NULL_TREE
);
1925 for (chain
= meth_var_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1927 string
= TREE_VALUE (chain
);
1928 decl
= TREE_PURPOSE (chain
);
1930 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1931 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1932 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1933 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1934 DECL_CONTEXT (decl
) = NULL_TREE
;
1935 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1936 IDENTIFIER_POINTER (string
));
1937 finish_decl (decl
, string_expr
, NULL_TREE
);
1940 for (chain
= meth_var_types_chain
; chain
; chain
= TREE_CHAIN (chain
))
1942 string
= TREE_VALUE (chain
);
1943 decl
= TREE_PURPOSE (chain
);
1945 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1946 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1947 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1948 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
1949 DECL_CONTEXT (decl
) = NULL_TREE
;
1950 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1951 IDENTIFIER_POINTER (string
));
1952 finish_decl (decl
, string_expr
, NULL_TREE
);
1957 build_selector_reference_decl ()
1963 sprintf (buf
, "_OBJC_SELECTOR_REFERENCES_%d", idx
++);
1965 ident
= get_identifier (buf
);
1967 decl
= build_decl (VAR_DECL
, ident
, selector_type
);
1968 DECL_EXTERNAL (decl
) = 1;
1969 TREE_PUBLIC (decl
) = 1;
1970 TREE_USED (decl
) = 1;
1971 TREE_READONLY (decl
) = 1;
1972 DECL_ARTIFICIAL (decl
) = 1;
1973 DECL_CONTEXT (decl
) = 0;
1975 make_decl_rtl (decl
, 0);
1976 pushdecl_top_level (decl
);
1981 /* Just a handy wrapper for add_objc_string. */
1984 build_selector (ident
)
1987 tree expr
= add_objc_string (ident
, meth_var_names
);
1988 if (flag_typed_selectors
)
1991 return build_c_cast (selector_type
, expr
); /* cast! */
1995 build_selector_translation_table ()
1997 tree sc_spec
, decl_specs
;
1998 tree chain
, initlist
= NULL_TREE
;
2000 tree decl
= NULL_TREE
, var_decl
, name
;
2002 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
2006 expr
= build_selector (TREE_VALUE (chain
));
2008 if (flag_next_runtime
)
2010 name
= DECL_NAME (TREE_PURPOSE (chain
));
2012 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
2014 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2015 decl_specs
= tree_cons (NULL_TREE
, selector_type
, sc_spec
);
2019 /* The `decl' that is returned from start_decl is the one that we
2020 forward declared in `build_selector_reference' */
2021 decl
= start_decl (var_decl
, decl_specs
, 1, NULL_TREE
);
2024 /* add one for the '\0' character */
2025 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (chain
)) + 1;
2027 if (flag_next_runtime
)
2028 finish_decl (decl
, expr
, NULL_TREE
);
2031 if (flag_typed_selectors
)
2033 tree eltlist
= NULL_TREE
;
2034 tree encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
2035 eltlist
= tree_cons (NULL_TREE
, expr
, NULL_TREE
);
2036 eltlist
= tree_cons (NULL_TREE
, encoding
, eltlist
);
2037 expr
= build_constructor (objc_selector_template
,
2038 nreverse (eltlist
));
2040 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2045 if (! flag_next_runtime
)
2047 /* Cause the variable and its initial value to be actually output. */
2048 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl
) = 0;
2049 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl
) = 1;
2050 /* NULL terminate the list and fix the decl for output. */
2051 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
2052 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl
) = objc_ellipsis_node
;
2053 initlist
= build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
2054 nreverse (initlist
));
2055 finish_decl (UOBJC_SELECTOR_TABLE_decl
, initlist
, NULL_TREE
);
2056 current_function_decl
= NULL_TREE
;
2061 get_proto_encoding (proto
)
2069 if (! METHOD_ENCODING (proto
))
2071 tmp_decl
= build_tmp_function_decl ();
2072 hack_method_prototype (proto
, tmp_decl
);
2073 encoding
= encode_method_prototype (proto
, tmp_decl
);
2074 METHOD_ENCODING (proto
) = encoding
;
2077 encoding
= METHOD_ENCODING (proto
);
2079 return add_objc_string (encoding
, meth_var_types
);
2082 return build_int_2 (0, 0);
2085 /* sel_ref_chain is a list whose "value" fields will be instances of
2086 identifier_node that represent the selector. */
2089 build_typed_selector_reference (ident
, proto
)
2092 tree
*chain
= &sel_ref_chain
;
2098 if (TREE_PURPOSE (*chain
) == ident
&& TREE_VALUE (*chain
) == proto
)
2099 goto return_at_index
;
2102 chain
= &TREE_CHAIN (*chain
);
2105 *chain
= tree_cons (proto
, ident
, NULL_TREE
);
2108 expr
= build_unary_op (ADDR_EXPR
,
2109 build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2110 build_int_2 (index
, 0)),
2112 return build_c_cast (selector_type
, expr
);
2116 build_selector_reference (ident
)
2119 tree
*chain
= &sel_ref_chain
;
2125 if (TREE_VALUE (*chain
) == ident
)
2126 return (flag_next_runtime
2127 ? TREE_PURPOSE (*chain
)
2128 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2129 build_int_2 (index
, 0)));
2132 chain
= &TREE_CHAIN (*chain
);
2135 expr
= build_selector_reference_decl ();
2137 *chain
= tree_cons (expr
, ident
, NULL_TREE
);
2139 return (flag_next_runtime
2141 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2142 build_int_2 (index
, 0)));
2146 build_class_reference_decl ()
2152 sprintf (buf
, "_OBJC_CLASS_REFERENCES_%d", idx
++);
2154 ident
= get_identifier (buf
);
2156 decl
= build_decl (VAR_DECL
, ident
, objc_class_type
);
2157 DECL_EXTERNAL (decl
) = 1;
2158 TREE_PUBLIC (decl
) = 1;
2159 TREE_USED (decl
) = 1;
2160 TREE_READONLY (decl
) = 1;
2161 DECL_CONTEXT (decl
) = 0;
2162 DECL_ARTIFICIAL (decl
) = 1;
2164 make_decl_rtl (decl
, 0);
2165 pushdecl_top_level (decl
);
2170 /* Create a class reference, but don't create a variable to reference
2174 add_class_reference (ident
)
2179 if ((chain
= cls_ref_chain
))
2184 if (ident
== TREE_VALUE (chain
))
2188 chain
= TREE_CHAIN (chain
);
2192 /* Append to the end of the list */
2193 TREE_CHAIN (tail
) = tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2196 cls_ref_chain
= tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2199 /* Get a class reference, creating it if necessary. Also create the
2200 reference variable. */
2203 get_class_reference (ident
)
2206 if (flag_next_runtime
)
2211 for (chain
= &cls_ref_chain
; *chain
; chain
= &TREE_CHAIN (*chain
))
2212 if (TREE_VALUE (*chain
) == ident
)
2214 if (! TREE_PURPOSE (*chain
))
2215 TREE_PURPOSE (*chain
) = build_class_reference_decl ();
2217 return TREE_PURPOSE (*chain
);
2220 decl
= build_class_reference_decl ();
2221 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2228 add_class_reference (ident
);
2230 params
= build_tree_list (NULL_TREE
,
2231 my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
2232 IDENTIFIER_POINTER (ident
)));
2234 assemble_external (objc_get_class_decl
);
2235 return build_function_call (objc_get_class_decl
, params
);
2239 /* For each string section we have a chain which maps identifier nodes
2240 to decls for the strings. */
2243 add_objc_string (ident
, section
)
2245 enum string_section section
;
2249 if (section
== class_names
)
2250 chain
= &class_names_chain
;
2251 else if (section
== meth_var_names
)
2252 chain
= &meth_var_names_chain
;
2253 else if (section
== meth_var_types
)
2254 chain
= &meth_var_types_chain
;
2260 if (TREE_VALUE (*chain
) == ident
)
2261 return build_unary_op (ADDR_EXPR
, TREE_PURPOSE (*chain
), 1);
2263 chain
= &TREE_CHAIN (*chain
);
2266 decl
= build_objc_string_decl (section
);
2268 *chain
= tree_cons (decl
, ident
, NULL_TREE
);
2270 return build_unary_op (ADDR_EXPR
, decl
, 1);
2274 build_objc_string_decl (section
)
2275 enum string_section section
;
2279 static int class_names_idx
= 0;
2280 static int meth_var_names_idx
= 0;
2281 static int meth_var_types_idx
= 0;
2283 if (section
== class_names
)
2284 sprintf (buf
, "_OBJC_CLASS_NAME_%d", class_names_idx
++);
2285 else if (section
== meth_var_names
)
2286 sprintf (buf
, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx
++);
2287 else if (section
== meth_var_types
)
2288 sprintf (buf
, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx
++);
2290 ident
= get_identifier (buf
);
2292 decl
= build_decl (VAR_DECL
, ident
, build_array_type (char_type_node
, 0));
2293 DECL_EXTERNAL (decl
) = 1;
2294 TREE_PUBLIC (decl
) = 1;
2295 TREE_USED (decl
) = 1;
2296 TREE_READONLY (decl
) = 1;
2297 TREE_CONSTANT (decl
) = 1;
2298 DECL_CONTEXT (decl
) = 0;
2299 DECL_ARTIFICIAL (decl
) = 1;
2301 make_decl_rtl (decl
, 0);
2302 pushdecl_top_level (decl
);
2309 objc_declare_alias (alias_ident
, class_ident
)
2313 if (is_class_name (class_ident
) != class_ident
)
2314 warning ("cannot find class `%s'", IDENTIFIER_POINTER (class_ident
));
2315 else if (is_class_name (alias_ident
))
2316 warning ("class `%s' already exists", IDENTIFIER_POINTER (alias_ident
));
2318 alias_chain
= tree_cons (class_ident
, alias_ident
, alias_chain
);
2322 objc_declare_class (ident_list
)
2327 for (list
= ident_list
; list
; list
= TREE_CHAIN (list
))
2329 tree ident
= TREE_VALUE (list
);
2332 if ((decl
= lookup_name (ident
)))
2334 error ("`%s' redeclared as different kind of symbol",
2335 IDENTIFIER_POINTER (ident
));
2336 error_with_decl (decl
, "previous declaration of `%s'");
2339 if (! is_class_name (ident
))
2341 tree record
= xref_tag (RECORD_TYPE
, ident
);
2342 TREE_STATIC_TEMPLATE (record
) = 1;
2343 class_chain
= tree_cons (NULL_TREE
, ident
, class_chain
);
2349 is_class_name (ident
)
2354 if (lookup_interface (ident
))
2357 for (chain
= class_chain
; chain
; chain
= TREE_CHAIN (chain
))
2359 if (ident
== TREE_VALUE (chain
))
2363 for (chain
= alias_chain
; chain
; chain
= TREE_CHAIN (chain
))
2365 if (ident
== TREE_VALUE (chain
))
2366 return TREE_PURPOSE (chain
);
2373 lookup_interface (ident
)
2378 for (chain
= interface_chain
; chain
; chain
= TREE_CHAIN (chain
))
2380 if (ident
== CLASS_NAME (chain
))
2387 objc_copy_list (list
, head
)
2391 tree newlist
= NULL_TREE
, tail
= NULL_TREE
;
2395 tail
= copy_node (list
);
2397 /* The following statement fixes a bug when inheriting instance
2398 variables that are declared to be bitfields. finish_struct
2399 expects to find the width of the bitfield in DECL_INITIAL. */
2400 if (DECL_BIT_FIELD (tail
) && DECL_INITIAL (tail
) == 0)
2401 DECL_INITIAL (tail
) = DECL_SIZE (tail
);
2403 newlist
= chainon (newlist
, tail
);
2404 list
= TREE_CHAIN (list
);
2411 /* Used by: build_private_template, get_class_ivars, and
2412 continue_class. COPY is 1 when called from @defs. In this case
2413 copy all fields. Otherwise don't copy leaf ivars since we rely on
2414 them being side-effected exactly once by finish_struct. */
2417 build_ivar_chain (interface
, copy
)
2421 tree my_name
, super_name
, ivar_chain
;
2423 my_name
= CLASS_NAME (interface
);
2424 super_name
= CLASS_SUPER_NAME (interface
);
2426 /* Possibly copy leaf ivars. */
2428 objc_copy_list (CLASS_IVARS (interface
), &ivar_chain
);
2430 ivar_chain
= CLASS_IVARS (interface
);
2435 tree super_interface
= lookup_interface (super_name
);
2437 if (!super_interface
)
2439 /* fatal did not work with 2 args...should fix */
2440 error ("cannot find interface declaration for `%s', superclass of `%s'",
2441 IDENTIFIER_POINTER (super_name
),
2442 IDENTIFIER_POINTER (my_name
));
2443 exit (FATAL_EXIT_CODE
);
2446 if (super_interface
== interface
)
2447 fatal_error ("circular inheritance in interface declaration for `%s'",
2448 IDENTIFIER_POINTER (super_name
));
2450 interface
= super_interface
;
2451 my_name
= CLASS_NAME (interface
);
2452 super_name
= CLASS_SUPER_NAME (interface
);
2454 op1
= CLASS_IVARS (interface
);
2457 tree head
, tail
= objc_copy_list (op1
, &head
);
2459 /* Prepend super class ivars...make a copy of the list, we
2460 do not want to alter the original. */
2461 TREE_CHAIN (tail
) = ivar_chain
;
2468 /* struct <classname> {
2469 struct objc_class *isa;
2474 build_private_template (class)
2479 if (CLASS_STATIC_TEMPLATE (class))
2481 uprivate_record
= CLASS_STATIC_TEMPLATE (class);
2482 ivar_context
= TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2486 uprivate_record
= start_struct (RECORD_TYPE
, CLASS_NAME (class));
2488 ivar_context
= build_ivar_chain (class, 0);
2490 finish_struct (uprivate_record
, ivar_context
, NULL_TREE
);
2492 CLASS_STATIC_TEMPLATE (class) = uprivate_record
;
2494 /* mark this record as class template - for class type checking */
2495 TREE_STATIC_TEMPLATE (uprivate_record
) = 1;
2499 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
2501 build1 (INDIRECT_REF
, NULL_TREE
,
2504 return ivar_context
;
2507 /* Begin code generation for protocols... */
2509 /* struct objc_protocol {
2510 char *protocol_name;
2511 struct objc_protocol **protocol_list;
2512 struct objc_method_desc *instance_methods;
2513 struct objc_method_desc *class_methods;
2517 build_protocol_template ()
2519 tree decl_specs
, field_decl
, field_decl_chain
;
2522 template = start_struct (RECORD_TYPE
, get_identifier (UTAG_PROTOCOL
));
2524 /* struct objc_class *isa; */
2526 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2527 get_identifier (UTAG_CLASS
)));
2528 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
2530 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2531 field_decl_chain
= field_decl
;
2533 /* char *protocol_name; */
2535 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
2537 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_name"));
2539 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2540 chainon (field_decl_chain
, field_decl
);
2542 /* struct objc_protocol **protocol_list; */
2544 decl_specs
= build_tree_list (NULL_TREE
, template);
2546 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
2547 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
2549 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2550 chainon (field_decl_chain
, field_decl
);
2552 /* struct objc_method_list *instance_methods; */
2555 = build_tree_list (NULL_TREE
,
2556 xref_tag (RECORD_TYPE
,
2557 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2559 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
2561 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2562 chainon (field_decl_chain
, field_decl
);
2564 /* struct objc_method_list *class_methods; */
2567 = build_tree_list (NULL_TREE
,
2568 xref_tag (RECORD_TYPE
,
2569 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2571 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
2573 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2574 chainon (field_decl_chain
, field_decl
);
2576 return finish_struct (template, field_decl_chain
, NULL_TREE
);
2580 build_descriptor_table_initializer (type
, entries
)
2584 tree initlist
= NULL_TREE
;
2588 tree eltlist
= NULL_TREE
;
2591 = tree_cons (NULL_TREE
,
2592 build_selector (METHOD_SEL_NAME (entries
)), NULL_TREE
);
2594 = tree_cons (NULL_TREE
,
2595 add_objc_string (METHOD_ENCODING (entries
),
2600 = tree_cons (NULL_TREE
,
2601 build_constructor (type
, nreverse (eltlist
)), initlist
);
2603 entries
= TREE_CHAIN (entries
);
2607 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
2610 /* struct objc_method_prototype_list {
2612 struct objc_method_prototype {
2619 build_method_prototype_list_template (list_type
, size
)
2623 tree objc_ivar_list_record
;
2624 tree decl_specs
, field_decl
, field_decl_chain
;
2626 /* Generate an unnamed struct definition. */
2628 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
2630 /* int method_count; */
2632 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
2633 field_decl
= get_identifier ("method_count");
2636 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2637 field_decl_chain
= field_decl
;
2639 /* struct objc_method method_list[]; */
2641 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
2642 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
2643 build_int_2 (size
, 0));
2646 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2647 chainon (field_decl_chain
, field_decl
);
2649 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
2651 return objc_ivar_list_record
;
2655 build_method_prototype_template ()
2658 tree decl_specs
, field_decl
, field_decl_chain
;
2661 = start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD_PROTOTYPE
));
2663 /* struct objc_selector *_cmd; */
2664 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
2665 get_identifier (TAG_SELECTOR
)), NULL_TREE
);
2666 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
2669 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2670 field_decl_chain
= field_decl
;
2672 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
2674 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_types"));
2676 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2677 chainon (field_decl_chain
, field_decl
);
2679 finish_struct (proto_record
, field_decl_chain
, NULL_TREE
);
2681 return proto_record
;
2684 /* True if last call to forwarding_offset yielded a register offset. */
2685 static int offset_is_register
;
2688 forwarding_offset (parm
)
2691 int offset_in_bytes
;
2693 if (GET_CODE (DECL_INCOMING_RTL (parm
)) == MEM
)
2695 rtx addr
= XEXP (DECL_INCOMING_RTL (parm
), 0);
2697 /* ??? Here we assume that the parm address is indexed
2698 off the frame pointer or arg pointer.
2699 If that is not true, we produce meaningless results,
2700 but do not crash. */
2701 if (GET_CODE (addr
) == PLUS
2702 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
2703 offset_in_bytes
= INTVAL (XEXP (addr
, 1));
2705 offset_in_bytes
= 0;
2707 offset_in_bytes
+= OBJC_FORWARDING_STACK_OFFSET
;
2708 offset_is_register
= 0;
2710 else if (GET_CODE (DECL_INCOMING_RTL (parm
)) == REG
)
2712 int regno
= REGNO (DECL_INCOMING_RTL (parm
));
2713 offset_in_bytes
= apply_args_register_offset (regno
);
2714 offset_is_register
= 1;
2719 /* This is the case where the parm is passed as an int or double
2720 and it is converted to a char, short or float and stored back
2721 in the parmlist. In this case, describe the parm
2722 with the variable's declared type, and adjust the address
2723 if the least significant bytes (which we are using) are not
2725 if (BYTES_BIG_ENDIAN
&& TREE_TYPE (parm
) != DECL_ARG_TYPE (parm
))
2726 offset_in_bytes
+= (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm
)))
2727 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm
))));
2729 return offset_in_bytes
;
2733 encode_method_prototype (method_decl
, func_decl
)
2740 HOST_WIDE_INT max_parm_end
= 0;
2744 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2745 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl
)));
2748 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
2749 obstack_object_size (&util_obstack
),
2750 OBJC_ENCODE_INLINE_DEFS
);
2753 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
2754 parms
= TREE_CHAIN (parms
))
2756 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
2757 + int_size_in_bytes (TREE_TYPE (parms
)));
2759 if (!offset_is_register
&& max_parm_end
< parm_end
)
2760 max_parm_end
= parm_end
;
2763 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
2765 sprintf (buf
, "%d", stack_size
);
2766 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2768 user_args
= METHOD_SEL_ARGS (method_decl
);
2770 /* Argument types. */
2771 for (parms
= DECL_ARGUMENTS (func_decl
), i
= 0; parms
;
2772 parms
= TREE_CHAIN (parms
), i
++)
2774 /* Process argument qualifiers for user supplied arguments. */
2777 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args
)));
2778 user_args
= TREE_CHAIN (user_args
);
2782 encode_type (TREE_TYPE (parms
),
2783 obstack_object_size (&util_obstack
),
2784 OBJC_ENCODE_INLINE_DEFS
);
2786 /* Compute offset. */
2787 sprintf (buf
, "%d", forwarding_offset (parms
));
2789 /* Indicate register. */
2790 if (offset_is_register
)
2791 obstack_1grow (&util_obstack
, '+');
2793 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2796 obstack_1grow (&util_obstack
, '\0');
2797 result
= get_identifier (obstack_finish (&util_obstack
));
2798 obstack_free (&util_obstack
, util_firstobj
);
2803 generate_descriptor_table (type
, name
, size
, list
, proto
)
2810 tree sc_spec
, decl_specs
, decl
, initlist
;
2812 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2813 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
2815 decl
= start_decl (synth_id_with_class_suffix (name
, proto
),
2816 decl_specs
, 1, NULL_TREE
);
2817 DECL_CONTEXT (decl
) = NULL_TREE
;
2819 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
2820 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
2822 finish_decl (decl
, build_constructor (type
, nreverse (initlist
)),
2829 generate_method_descriptors (protocol
)
2832 tree initlist
, chain
, method_list_template
;
2833 tree cast
, variable_length_type
;
2836 if (!objc_method_prototype_template
)
2837 objc_method_prototype_template
= build_method_prototype_template ();
2839 cast
= build_tree_list (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2840 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
))),
2842 variable_length_type
= groktypename (cast
);
2844 chain
= PROTOCOL_CLS_METHODS (protocol
);
2847 size
= list_length (chain
);
2849 method_list_template
2850 = build_method_prototype_list_template (objc_method_prototype_template
,
2854 = build_descriptor_table_initializer (objc_method_prototype_template
,
2857 UOBJC_CLASS_METHODS_decl
2858 = generate_descriptor_table (method_list_template
,
2859 "_OBJC_PROTOCOL_CLASS_METHODS",
2860 size
, initlist
, protocol
);
2861 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
2864 UOBJC_CLASS_METHODS_decl
= 0;
2866 chain
= PROTOCOL_NST_METHODS (protocol
);
2869 size
= list_length (chain
);
2871 method_list_template
2872 = build_method_prototype_list_template (objc_method_prototype_template
,
2875 = build_descriptor_table_initializer (objc_method_prototype_template
,
2878 UOBJC_INSTANCE_METHODS_decl
2879 = generate_descriptor_table (method_list_template
,
2880 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2881 size
, initlist
, protocol
);
2882 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
2885 UOBJC_INSTANCE_METHODS_decl
= 0;
2888 /* Generate a temporary FUNCTION_DECL node to be used in
2889 hack_method_prototype below. */
2892 build_tmp_function_decl ()
2894 tree decl_specs
, expr_decl
, parms
;
2898 /* struct objc_object *objc_xxx (id, SEL, ...); */
2900 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
2901 push_parm_decl (build_tree_list
2902 (build_tree_list (decl_specs
,
2903 build1 (INDIRECT_REF
, NULL_TREE
,
2907 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2908 get_identifier (TAG_SELECTOR
)));
2909 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
);
2911 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, expr_decl
),
2913 parms
= get_parm_info (0);
2916 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
2917 sprintf (buffer
, "__objc_tmp_%x", xxx
++);
2918 expr_decl
= build_nt (CALL_EXPR
, get_identifier (buffer
), parms
, NULL_TREE
);
2919 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
2921 return define_decl (expr_decl
, decl_specs
);
2924 /* Generate the prototypes for protocol methods. This is used to
2925 generate method encodings for these.
2927 NST_METHODS is the method to generate a _DECL node for TMP_DECL is
2928 a decl node to be used. This is also where the return value is
2932 hack_method_prototype (nst_methods
, tmp_decl
)
2939 /* Hack to avoid problem with static typing of self arg. */
2940 TREE_SET_CODE (nst_methods
, CLASS_METHOD_DECL
);
2941 start_method_def (nst_methods
);
2942 TREE_SET_CODE (nst_methods
, INSTANCE_METHOD_DECL
);
2944 if (METHOD_ADD_ARGS (nst_methods
) == objc_ellipsis_node
)
2945 parms
= get_parm_info (0); /* we have a `, ...' */
2947 parms
= get_parm_info (1); /* place a `void_at_end' */
2949 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
2951 /* Usually called from store_parm_decls -> init_function_start. */
2953 DECL_ARGUMENTS (tmp_decl
) = TREE_PURPOSE (parms
);
2955 if (current_function_decl
)
2957 current_function_decl
= tmp_decl
;
2960 /* Code taken from start_function. */
2961 tree restype
= TREE_TYPE (TREE_TYPE (tmp_decl
));
2962 /* Promote the value to int before returning it. */
2963 if (TREE_CODE (restype
) == INTEGER_TYPE
2964 && TYPE_PRECISION (restype
) < TYPE_PRECISION (integer_type_node
))
2965 restype
= integer_type_node
;
2966 DECL_RESULT (tmp_decl
) = build_decl (RESULT_DECL
, 0, restype
);
2969 for (parm
= DECL_ARGUMENTS (tmp_decl
); parm
; parm
= TREE_CHAIN (parm
))
2970 DECL_CONTEXT (parm
) = tmp_decl
;
2972 init_function_start (tmp_decl
, "objc-act", 0);
2974 /* Typically called from expand_function_start for function definitions. */
2975 assign_parms (tmp_decl
);
2977 /* install return type */
2978 TREE_TYPE (TREE_TYPE (tmp_decl
)) = groktypename (TREE_TYPE (nst_methods
));
2980 current_function_decl
= NULL
;
2984 generate_protocol_references (plist
)
2989 /* Forward declare protocols referenced. */
2990 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
2992 tree proto
= TREE_VALUE (lproto
);
2994 if (TREE_CODE (proto
) == PROTOCOL_INTERFACE_TYPE
2995 && PROTOCOL_NAME (proto
))
2997 if (! PROTOCOL_FORWARD_DECL (proto
))
2998 build_protocol_reference (proto
);
3000 if (PROTOCOL_LIST (proto
))
3001 generate_protocol_references (PROTOCOL_LIST (proto
));
3007 generate_protocols ()
3009 tree p
, tmp_decl
, encoding
;
3010 tree sc_spec
, decl_specs
, decl
;
3011 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
3014 tmp_decl
= build_tmp_function_decl ();
3016 if (! objc_protocol_template
)
3017 objc_protocol_template
= build_protocol_template ();
3019 /* If a protocol was directly referenced, pull in indirect references. */
3020 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3021 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
3022 generate_protocol_references (PROTOCOL_LIST (p
));
3024 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3026 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
3027 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
3029 /* If protocol wasn't referenced, don't generate any code. */
3030 if (! PROTOCOL_FORWARD_DECL (p
))
3033 /* Make sure we link in the Protocol class. */
3034 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
3038 if (! METHOD_ENCODING (nst_methods
))
3040 hack_method_prototype (nst_methods
, tmp_decl
);
3041 encoding
= encode_method_prototype (nst_methods
, tmp_decl
);
3042 METHOD_ENCODING (nst_methods
) = encoding
;
3044 nst_methods
= TREE_CHAIN (nst_methods
);
3049 if (! METHOD_ENCODING (cls_methods
))
3051 hack_method_prototype (cls_methods
, tmp_decl
);
3052 encoding
= encode_method_prototype (cls_methods
, tmp_decl
);
3053 METHOD_ENCODING (cls_methods
) = encoding
;
3056 cls_methods
= TREE_CHAIN (cls_methods
);
3058 generate_method_descriptors (p
);
3060 if (PROTOCOL_LIST (p
))
3061 refs_decl
= generate_protocol_list (p
);
3065 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3067 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
],
3069 decl_specs
= tree_cons (NULL_TREE
, objc_protocol_template
, sc_spec
);
3071 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
),
3072 decl_specs
, 1, NULL_TREE
);
3074 DECL_CONTEXT (decl
) = NULL_TREE
;
3076 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
3082 (build_tree_list (build_tree_list (NULL_TREE
,
3083 objc_protocol_template
),
3084 build1 (INDIRECT_REF
, NULL_TREE
,
3085 build1 (INDIRECT_REF
, NULL_TREE
,
3088 refs_expr
= build_unary_op (ADDR_EXPR
, refs_decl
, 0);
3089 TREE_TYPE (refs_expr
) = cast_type2
;
3092 refs_expr
= build_int_2 (0, 0);
3094 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3095 by generate_method_descriptors, which is called above. */
3096 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
3097 protocol_name_expr
, refs_expr
,
3098 UOBJC_INSTANCE_METHODS_decl
,
3099 UOBJC_CLASS_METHODS_decl
);
3100 finish_decl (decl
, initlist
, NULL_TREE
);
3102 /* Mark the decl as used to avoid "defined but not used" warning. */
3103 TREE_USED (decl
) = 1;
3108 build_protocol_initializer (type
, protocol_name
, protocol_list
,
3109 instance_methods
, class_methods
)
3113 tree instance_methods
;
3116 tree initlist
= NULL_TREE
, expr
;
3119 cast_type
= groktypename
3121 (build_tree_list (NULL_TREE
,
3122 xref_tag (RECORD_TYPE
,
3123 get_identifier (UTAG_CLASS
))),
3124 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
3126 /* Filling the "isa" in with one allows the runtime system to
3127 detect that the version change...should remove before final release. */
3129 expr
= build_int_2 (PROTOCOL_VERSION
, 0);
3130 TREE_TYPE (expr
) = cast_type
;
3131 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3132 initlist
= tree_cons (NULL_TREE
, protocol_name
, initlist
);
3133 initlist
= tree_cons (NULL_TREE
, protocol_list
, initlist
);
3135 if (!instance_methods
)
3136 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3139 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
3140 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3144 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3147 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
3148 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3151 return build_constructor (type
, nreverse (initlist
));
3154 /* struct objc_category {
3155 char *category_name;
3157 struct objc_method_list *instance_methods;
3158 struct objc_method_list *class_methods;
3159 struct objc_protocol_list *protocols;
3163 build_category_template ()
3165 tree decl_specs
, field_decl
, field_decl_chain
;
3167 objc_category_template
= start_struct (RECORD_TYPE
,
3168 get_identifier (UTAG_CATEGORY
));
3169 /* char *category_name; */
3171 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3173 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("category_name"));
3175 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3176 field_decl_chain
= field_decl
;
3178 /* char *class_name; */
3180 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3181 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_name"));
3183 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3184 chainon (field_decl_chain
, field_decl
);
3186 /* struct objc_method_list *instance_methods; */
3188 decl_specs
= build_tree_list (NULL_TREE
,
3189 xref_tag (RECORD_TYPE
,
3190 get_identifier (UTAG_METHOD_LIST
)));
3192 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
3194 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3195 chainon (field_decl_chain
, field_decl
);
3197 /* struct objc_method_list *class_methods; */
3199 decl_specs
= build_tree_list (NULL_TREE
,
3200 xref_tag (RECORD_TYPE
,
3201 get_identifier (UTAG_METHOD_LIST
)));
3203 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
3205 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3206 chainon (field_decl_chain
, field_decl
);
3208 /* struct objc_protocol **protocol_list; */
3210 decl_specs
= build_tree_list (NULL_TREE
,
3211 xref_tag (RECORD_TYPE
,
3212 get_identifier (UTAG_PROTOCOL
)));
3214 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3215 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3217 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3218 chainon (field_decl_chain
, field_decl
);
3220 finish_struct (objc_category_template
, field_decl_chain
, NULL_TREE
);
3223 /* struct objc_selector {
3229 build_selector_template ()
3232 tree decl_specs
, field_decl
, field_decl_chain
;
3234 objc_selector_template
3235 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SELECTOR
));
3239 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3240 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3242 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3243 field_decl_chain
= field_decl
;
3245 /* char *sel_type; */
3247 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3248 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_type"));
3250 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3251 chainon (field_decl_chain
, field_decl
);
3253 finish_struct (objc_selector_template
, field_decl_chain
, NULL_TREE
);
3256 /* struct objc_class {
3257 struct objc_class *isa;
3258 struct objc_class *super_class;
3263 struct objc_ivar_list *ivars;
3264 struct objc_method_list *methods;
3265 if (flag_next_runtime)
3266 struct objc_cache *cache;
3268 struct sarray *dtable;
3269 struct objc_class *subclass_list;
3270 struct objc_class *sibling_class;
3272 struct objc_protocol_list *protocols;
3273 void *gc_object_type;
3277 build_class_template ()
3279 tree decl_specs
, field_decl
, field_decl_chain
;
3282 = start_struct (RECORD_TYPE
, get_identifier (UTAG_CLASS
));
3284 /* struct objc_class *isa; */
3286 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3287 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
3289 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3290 field_decl_chain
= field_decl
;
3292 /* struct objc_class *super_class; */
3294 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3296 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("super_class"));
3298 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3299 chainon (field_decl_chain
, field_decl
);
3303 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3304 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
3306 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3307 chainon (field_decl_chain
, field_decl
);
3311 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3312 field_decl
= get_identifier ("version");
3314 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3315 chainon (field_decl_chain
, field_decl
);
3319 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3320 field_decl
= get_identifier ("info");
3322 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3323 chainon (field_decl_chain
, field_decl
);
3325 /* long instance_size; */
3327 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3328 field_decl
= get_identifier ("instance_size");
3330 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3331 chainon (field_decl_chain
, field_decl
);
3333 /* struct objc_ivar_list *ivars; */
3335 decl_specs
= build_tree_list (NULL_TREE
,
3336 xref_tag (RECORD_TYPE
,
3337 get_identifier (UTAG_IVAR_LIST
)));
3338 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivars"));
3340 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3341 chainon (field_decl_chain
, field_decl
);
3343 /* struct objc_method_list *methods; */
3345 decl_specs
= build_tree_list (NULL_TREE
,
3346 xref_tag (RECORD_TYPE
,
3347 get_identifier (UTAG_METHOD_LIST
)));
3348 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("methods"));
3350 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3351 chainon (field_decl_chain
, field_decl
);
3353 if (flag_next_runtime
)
3355 /* struct objc_cache *cache; */
3357 decl_specs
= build_tree_list (NULL_TREE
,
3358 xref_tag (RECORD_TYPE
,
3359 get_identifier ("objc_cache")));
3360 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("cache"));
3361 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3362 decl_specs
, NULL_TREE
);
3363 chainon (field_decl_chain
, field_decl
);
3367 /* struct sarray *dtable; */
3369 decl_specs
= build_tree_list (NULL_TREE
,
3370 xref_tag (RECORD_TYPE
,
3371 get_identifier ("sarray")));
3372 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("dtable"));
3373 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3374 decl_specs
, NULL_TREE
);
3375 chainon (field_decl_chain
, field_decl
);
3377 /* struct objc_class *subclass_list; */
3379 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3381 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("subclass_list"));
3382 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3383 decl_specs
, NULL_TREE
);
3384 chainon (field_decl_chain
, field_decl
);
3386 /* struct objc_class *sibling_class; */
3388 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3390 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sibling_class"));
3391 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3392 decl_specs
, NULL_TREE
);
3393 chainon (field_decl_chain
, field_decl
);
3396 /* struct objc_protocol **protocol_list; */
3398 decl_specs
= build_tree_list (NULL_TREE
,
3399 xref_tag (RECORD_TYPE
,
3400 get_identifier (UTAG_PROTOCOL
)));
3402 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3404 = build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3405 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3406 decl_specs
, NULL_TREE
);
3407 chainon (field_decl_chain
, field_decl
);
3411 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3412 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3414 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3415 chainon (field_decl_chain
, field_decl
);
3417 /* void *gc_object_type; */
3419 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3420 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("gc_object_type"));
3422 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3423 chainon (field_decl_chain
, field_decl
);
3425 finish_struct (objc_class_template
, field_decl_chain
, NULL_TREE
);
3428 /* Generate appropriate forward declarations for an implementation. */
3431 synth_forward_declarations ()
3433 tree sc_spec
, decl_specs
, an_id
;
3435 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3437 an_id
= synth_id_with_class_suffix ("_OBJC_CLASS", objc_implementation_context
);
3439 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
3440 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
3441 UOBJC_CLASS_decl
= define_decl (an_id
, decl_specs
);
3442 TREE_USED (UOBJC_CLASS_decl
) = 1;
3443 DECL_ARTIFICIAL (UOBJC_CLASS_decl
) = 1;
3445 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3447 an_id
= synth_id_with_class_suffix ("_OBJC_METACLASS",
3448 objc_implementation_context
);
3450 UOBJC_METACLASS_decl
= define_decl (an_id
, decl_specs
);
3451 TREE_USED (UOBJC_METACLASS_decl
) = 1;
3452 DECL_ARTIFICIAL(UOBJC_METACLASS_decl
) = 1;
3454 /* Pre-build the following entities - for speed/convenience. */
3456 an_id
= get_identifier ("super_class");
3457 ucls_super_ref
= build_component_ref (UOBJC_CLASS_decl
, an_id
);
3458 uucls_super_ref
= build_component_ref (UOBJC_METACLASS_decl
, an_id
);
3462 error_with_ivar (message
, decl
, rawdecl
)
3463 const char *message
;
3469 report_error_function (DECL_SOURCE_FILE (decl
));
3471 error_with_file_and_line (DECL_SOURCE_FILE (decl
),
3472 DECL_SOURCE_LINE (decl
),
3474 message
, gen_declaration (rawdecl
, errbuf
));
3478 #define USERTYPE(t) \
3479 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3480 || TREE_CODE (t) == ENUMERAL_TYPE)
3483 check_ivars (inter
, imp
)
3487 tree intdecls
= CLASS_IVARS (inter
);
3488 tree impdecls
= CLASS_IVARS (imp
);
3489 tree rawintdecls
= CLASS_RAW_IVARS (inter
);
3490 tree rawimpdecls
= CLASS_RAW_IVARS (imp
);
3496 if (intdecls
== 0 && impdecls
== 0)
3498 if (intdecls
== 0 || impdecls
== 0)
3500 error ("inconsistent instance variable specification");
3504 t1
= TREE_TYPE (intdecls
); t2
= TREE_TYPE (impdecls
);
3506 if (!comptypes (t1
, t2
))
3508 if (DECL_NAME (intdecls
) == DECL_NAME (impdecls
))
3510 error_with_ivar ("conflicting instance variable type",
3511 impdecls
, rawimpdecls
);
3512 error_with_ivar ("previous declaration of",
3513 intdecls
, rawintdecls
);
3515 else /* both the type and the name don't match */
3517 error ("inconsistent instance variable specification");
3522 else if (DECL_NAME (intdecls
) != DECL_NAME (impdecls
))
3524 error_with_ivar ("conflicting instance variable name",
3525 impdecls
, rawimpdecls
);
3526 error_with_ivar ("previous declaration of",
3527 intdecls
, rawintdecls
);
3530 intdecls
= TREE_CHAIN (intdecls
);
3531 impdecls
= TREE_CHAIN (impdecls
);
3532 rawintdecls
= TREE_CHAIN (rawintdecls
);
3533 rawimpdecls
= TREE_CHAIN (rawimpdecls
);
3537 /* Set super_type to the data type node for struct objc_super *,
3538 first defining struct objc_super itself.
3539 This needs to be done just once per compilation. */
3542 build_super_template ()
3544 tree record
, decl_specs
, field_decl
, field_decl_chain
;
3546 record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_SUPER
));
3548 /* struct objc_object *self; */
3550 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3551 field_decl
= get_identifier ("self");
3552 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3553 field_decl
= grokfield (input_filename
, lineno
,
3554 field_decl
, decl_specs
, NULL_TREE
);
3555 field_decl_chain
= field_decl
;
3557 /* struct objc_class *class; */
3559 decl_specs
= get_identifier (UTAG_CLASS
);
3560 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
3561 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class"));
3563 field_decl
= grokfield (input_filename
, lineno
,
3564 field_decl
, decl_specs
, NULL_TREE
);
3565 chainon (field_decl_chain
, field_decl
);
3567 finish_struct (record
, field_decl_chain
, NULL_TREE
);
3569 /* `struct objc_super *' */
3570 super_type
= groktypename (build_tree_list (build_tree_list (NULL_TREE
,
3572 build1 (INDIRECT_REF
,
3573 NULL_TREE
, NULL_TREE
)));
3577 /* struct objc_ivar {
3584 build_ivar_template ()
3586 tree objc_ivar_id
, objc_ivar_record
;
3587 tree decl_specs
, field_decl
, field_decl_chain
;
3589 objc_ivar_id
= get_identifier (UTAG_IVAR
);
3590 objc_ivar_record
= start_struct (RECORD_TYPE
, objc_ivar_id
);
3592 /* char *ivar_name; */
3594 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3595 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_name"));
3597 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3598 decl_specs
, NULL_TREE
);
3599 field_decl_chain
= field_decl
;
3601 /* char *ivar_type; */
3603 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3604 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_type"));
3606 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3607 decl_specs
, NULL_TREE
);
3608 chainon (field_decl_chain
, field_decl
);
3610 /* int ivar_offset; */
3612 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3613 field_decl
= get_identifier ("ivar_offset");
3615 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3616 decl_specs
, NULL_TREE
);
3617 chainon (field_decl_chain
, field_decl
);
3619 finish_struct (objc_ivar_record
, field_decl_chain
, NULL_TREE
);
3621 return objc_ivar_record
;
3626 struct objc_ivar ivar_list[ivar_count];
3630 build_ivar_list_template (list_type
, size
)
3634 tree objc_ivar_list_record
;
3635 tree decl_specs
, field_decl
, field_decl_chain
;
3637 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3639 /* int ivar_count; */
3641 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3642 field_decl
= get_identifier ("ivar_count");
3644 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3645 decl_specs
, NULL_TREE
);
3646 field_decl_chain
= field_decl
;
3648 /* struct objc_ivar ivar_list[]; */
3650 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3651 field_decl
= build_nt (ARRAY_REF
, get_identifier ("ivar_list"),
3652 build_int_2 (size
, 0));
3654 field_decl
= grokfield (input_filename
, lineno
,
3655 field_decl
, decl_specs
, NULL_TREE
);
3656 chainon (field_decl_chain
, field_decl
);
3658 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3660 return objc_ivar_list_record
;
3666 struct objc_method method_list[method_count];
3670 build_method_list_template (list_type
, size
)
3674 tree objc_ivar_list_record
;
3675 tree decl_specs
, field_decl
, field_decl_chain
;
3677 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3679 /* int method_next; */
3684 xref_tag (RECORD_TYPE
,
3685 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
3687 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_next"));
3688 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3689 decl_specs
, NULL_TREE
);
3690 field_decl_chain
= field_decl
;
3692 /* int method_count; */
3694 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3695 field_decl
= get_identifier ("method_count");
3697 field_decl
= grokfield (input_filename
, lineno
,
3698 field_decl
, decl_specs
, NULL_TREE
);
3699 chainon (field_decl_chain
, field_decl
);
3701 /* struct objc_method method_list[]; */
3703 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3704 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
3705 build_int_2 (size
, 0));
3707 field_decl
= grokfield (input_filename
, lineno
,
3708 field_decl
, decl_specs
, NULL_TREE
);
3709 chainon (field_decl_chain
, field_decl
);
3711 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3713 return objc_ivar_list_record
;
3717 build_ivar_list_initializer (type
, field_decl
)
3721 tree initlist
= NULL_TREE
;
3725 tree ivar
= NULL_TREE
;
3728 if (DECL_NAME (field_decl
))
3729 ivar
= tree_cons (NULL_TREE
,
3730 add_objc_string (DECL_NAME (field_decl
),
3734 /* Unnamed bit-field ivar (yuck). */
3735 ivar
= tree_cons (NULL_TREE
, build_int_2 (0, 0), ivar
);
3738 encode_field_decl (field_decl
,
3739 obstack_object_size (&util_obstack
),
3740 OBJC_ENCODE_DONT_INLINE_DEFS
);
3742 /* Null terminate string. */
3743 obstack_1grow (&util_obstack
, 0);
3747 add_objc_string (get_identifier (obstack_finish (&util_obstack
)),
3750 obstack_free (&util_obstack
, util_firstobj
);
3753 ivar
= tree_cons (NULL_TREE
, byte_position (field_decl
), ivar
);
3754 initlist
= tree_cons (NULL_TREE
,
3755 build_constructor (type
, nreverse (ivar
)),
3758 field_decl
= TREE_CHAIN (field_decl
);
3762 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3766 generate_ivars_list (type
, name
, size
, list
)
3772 tree sc_spec
, decl_specs
, decl
, initlist
;
3774 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3775 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
3777 decl
= start_decl (synth_id_with_class_suffix (name
, objc_implementation_context
),
3778 decl_specs
, 1, NULL_TREE
);
3780 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
3781 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3784 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3791 generate_ivar_lists ()
3793 tree initlist
, ivar_list_template
, chain
;
3794 tree cast
, variable_length_type
;
3797 generating_instance_variables
= 1;
3799 if (!objc_ivar_template
)
3800 objc_ivar_template
= build_ivar_template ();
3804 (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3805 get_identifier (UTAG_IVAR_LIST
))),
3807 variable_length_type
= groktypename (cast
);
3809 /* Only generate class variables for the root of the inheritance
3810 hierarchy since these will be the same for every class. */
3812 if (CLASS_SUPER_NAME (implementation_template
) == NULL_TREE
3813 && (chain
= TYPE_FIELDS (objc_class_template
)))
3815 size
= list_length (chain
);
3817 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3818 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3820 UOBJC_CLASS_VARIABLES_decl
3821 = generate_ivars_list (ivar_list_template
, "_OBJC_CLASS_VARIABLES",
3823 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl
) = variable_length_type
;
3826 UOBJC_CLASS_VARIABLES_decl
= 0;
3828 chain
= CLASS_IVARS (implementation_template
);
3831 size
= list_length (chain
);
3832 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3833 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3835 UOBJC_INSTANCE_VARIABLES_decl
3836 = generate_ivars_list (ivar_list_template
, "_OBJC_INSTANCE_VARIABLES",
3838 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl
) = variable_length_type
;
3841 UOBJC_INSTANCE_VARIABLES_decl
= 0;
3843 generating_instance_variables
= 0;
3847 build_dispatch_table_initializer (type
, entries
)
3851 tree initlist
= NULL_TREE
;
3855 tree elemlist
= NULL_TREE
;
3857 elemlist
= tree_cons (NULL_TREE
,
3858 build_selector (METHOD_SEL_NAME (entries
)),
3861 /* Generate the method encoding if we don't have one already. */
3862 if (! METHOD_ENCODING (entries
))
3863 METHOD_ENCODING (entries
) =
3864 encode_method_def (METHOD_DEFINITION (entries
));
3866 elemlist
= tree_cons (NULL_TREE
,
3867 add_objc_string (METHOD_ENCODING (entries
),
3871 elemlist
= tree_cons (NULL_TREE
,
3872 build_unary_op (ADDR_EXPR
,
3873 METHOD_DEFINITION (entries
), 1),
3876 initlist
= tree_cons (NULL_TREE
,
3877 build_constructor (type
, nreverse (elemlist
)),
3880 entries
= TREE_CHAIN (entries
);
3884 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3887 /* To accomplish method prototyping without generating all kinds of
3888 inane warnings, the definition of the dispatch table entries were
3891 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3893 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3896 build_method_template ()
3899 tree decl_specs
, field_decl
, field_decl_chain
;
3901 _SLT_record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD
));
3903 /* struct objc_selector *_cmd; */
3904 decl_specs
= tree_cons (NULL_TREE
,
3905 xref_tag (RECORD_TYPE
,
3906 get_identifier (TAG_SELECTOR
)),
3908 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
3910 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3911 decl_specs
, NULL_TREE
);
3912 field_decl_chain
= field_decl
;
3914 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
3915 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
,
3916 get_identifier ("method_types"));
3917 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3918 decl_specs
, NULL_TREE
);
3919 chainon (field_decl_chain
, field_decl
);
3923 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_VOID
], NULL_TREE
);
3924 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_imp"));
3925 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3926 decl_specs
, NULL_TREE
);
3927 chainon (field_decl_chain
, field_decl
);
3929 finish_struct (_SLT_record
, field_decl_chain
, NULL_TREE
);
3936 generate_dispatch_table (type
, name
, size
, list
)
3942 tree sc_spec
, decl_specs
, decl
, initlist
;
3944 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3945 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
3947 decl
= start_decl (synth_id_with_class_suffix (name
, objc_implementation_context
),
3948 decl_specs
, 1, NULL_TREE
);
3950 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
3951 initlist
= tree_cons (NULL_TREE
, build_int_2 (size
, 0), initlist
);
3952 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3955 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3962 generate_dispatch_tables ()
3964 tree initlist
, chain
, method_list_template
;
3965 tree cast
, variable_length_type
;
3968 if (!objc_method_template
)
3969 objc_method_template
= build_method_template ();
3973 (build_tree_list (NULL_TREE
,
3974 xref_tag (RECORD_TYPE
,
3975 get_identifier (UTAG_METHOD_LIST
))),
3978 variable_length_type
= groktypename (cast
);
3980 chain
= CLASS_CLS_METHODS (objc_implementation_context
);
3983 size
= list_length (chain
);
3985 method_list_template
3986 = build_method_list_template (objc_method_template
, size
);
3988 = build_dispatch_table_initializer (objc_method_template
, chain
);
3990 UOBJC_CLASS_METHODS_decl
3991 = generate_dispatch_table (method_list_template
,
3992 ((TREE_CODE (objc_implementation_context
)
3993 == CLASS_IMPLEMENTATION_TYPE
)
3994 ? "_OBJC_CLASS_METHODS"
3995 : "_OBJC_CATEGORY_CLASS_METHODS"),
3997 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
4000 UOBJC_CLASS_METHODS_decl
= 0;
4002 chain
= CLASS_NST_METHODS (objc_implementation_context
);
4005 size
= list_length (chain
);
4007 method_list_template
4008 = build_method_list_template (objc_method_template
, size
);
4010 = build_dispatch_table_initializer (objc_method_template
, chain
);
4012 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
4013 UOBJC_INSTANCE_METHODS_decl
4014 = generate_dispatch_table (method_list_template
,
4015 "_OBJC_INSTANCE_METHODS",
4018 /* We have a category. */
4019 UOBJC_INSTANCE_METHODS_decl
4020 = generate_dispatch_table (method_list_template
,
4021 "_OBJC_CATEGORY_INSTANCE_METHODS",
4023 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
4026 UOBJC_INSTANCE_METHODS_decl
= 0;
4030 generate_protocol_list (i_or_p
)
4033 tree initlist
, decl_specs
, sc_spec
;
4034 tree refs_decl
, expr_decl
, lproto
, e
, plist
;
4038 if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
4039 || TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4040 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
4041 else if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4042 plist
= PROTOCOL_LIST (i_or_p
);
4046 cast_type
= groktypename
4048 (build_tree_list (NULL_TREE
,
4049 xref_tag (RECORD_TYPE
,
4050 get_identifier (UTAG_PROTOCOL
))),
4051 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
4054 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4055 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
4056 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
4059 /* Build initializer. */
4060 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), NULL_TREE
);
4062 e
= build_int_2 (size
, 0);
4063 TREE_TYPE (e
) = cast_type
;
4064 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4066 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4068 tree pval
= TREE_VALUE (lproto
);
4070 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
4071 && PROTOCOL_FORWARD_DECL (pval
))
4073 e
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (pval
), 0);
4074 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4078 /* static struct objc_protocol *refs[n]; */
4080 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4081 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
4082 get_identifier (UTAG_PROTOCOL
)),
4085 if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4086 expr_decl
= build_nt (ARRAY_REF
,
4087 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4089 build_int_2 (size
+ 2, 0));
4090 else if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
)
4091 expr_decl
= build_nt (ARRAY_REF
,
4092 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4094 build_int_2 (size
+ 2, 0));
4095 else if (TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4097 = build_nt (ARRAY_REF
,
4098 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4100 build_int_2 (size
+ 2, 0));
4104 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
4106 refs_decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
);
4107 DECL_CONTEXT (refs_decl
) = NULL_TREE
;
4109 finish_decl (refs_decl
, build_constructor (TREE_TYPE (refs_decl
),
4110 nreverse (initlist
)),
4117 build_category_initializer (type
, cat_name
, class_name
,
4118 instance_methods
, class_methods
, protocol_list
)
4122 tree instance_methods
;
4126 tree initlist
= NULL_TREE
, expr
;
4128 initlist
= tree_cons (NULL_TREE
, cat_name
, initlist
);
4129 initlist
= tree_cons (NULL_TREE
, class_name
, initlist
);
4131 if (!instance_methods
)
4132 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4135 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
4136 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4139 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4142 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
4143 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4146 /* protocol_list = */
4148 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4151 tree cast_type2
= groktypename
4153 (build_tree_list (NULL_TREE
,
4154 xref_tag (RECORD_TYPE
,
4155 get_identifier (UTAG_PROTOCOL
))),
4156 build1 (INDIRECT_REF
, NULL_TREE
,
4157 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4159 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4160 TREE_TYPE (expr
) = cast_type2
;
4161 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4164 return build_constructor (type
, nreverse (initlist
));
4167 /* struct objc_class {
4168 struct objc_class *isa;
4169 struct objc_class *super_class;
4174 struct objc_ivar_list *ivars;
4175 struct objc_method_list *methods;
4176 if (flag_next_runtime)
4177 struct objc_cache *cache;
4179 struct sarray *dtable;
4180 struct objc_class *subclass_list;
4181 struct objc_class *sibling_class;
4183 struct objc_protocol_list *protocols;
4184 void *gc_object_type;
4188 build_shared_structure_initializer (type
, isa
, super
, name
, size
, status
,
4189 dispatch_table
, ivar_list
, protocol_list
)
4196 tree dispatch_table
;
4200 tree initlist
= NULL_TREE
, expr
;
4203 initlist
= tree_cons (NULL_TREE
, isa
, initlist
);
4206 initlist
= tree_cons (NULL_TREE
, super
, initlist
);
4209 initlist
= tree_cons (NULL_TREE
, default_conversion (name
), initlist
);
4212 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4215 initlist
= tree_cons (NULL_TREE
, build_int_2 (status
, 0), initlist
);
4217 /* instance_size = */
4218 initlist
= tree_cons (NULL_TREE
, size
, initlist
);
4220 /* objc_ivar_list = */
4222 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4225 expr
= build_unary_op (ADDR_EXPR
, ivar_list
, 0);
4226 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4229 /* objc_method_list = */
4230 if (!dispatch_table
)
4231 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4234 expr
= build_unary_op (ADDR_EXPR
, dispatch_table
, 0);
4235 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4238 if (flag_next_runtime
)
4239 /* method_cache = */
4240 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4244 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4246 /* subclass_list = */
4247 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4249 /* sibling_class = */
4250 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4253 /* protocol_list = */
4254 if (! protocol_list
)
4255 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4261 (build_tree_list (NULL_TREE
,
4262 xref_tag (RECORD_TYPE
,
4263 get_identifier (UTAG_PROTOCOL
))),
4264 build1 (INDIRECT_REF
, NULL_TREE
,
4265 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4267 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4268 TREE_TYPE (expr
) = cast_type2
;
4269 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4272 /* gc_object_type = NULL */
4273 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4275 return build_constructor (type
, nreverse (initlist
));
4278 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4281 generate_category (cat
)
4284 tree sc_spec
, decl_specs
, decl
;
4285 tree initlist
, cat_name_expr
, class_name_expr
;
4286 tree protocol_decl
, category
;
4288 add_class_reference (CLASS_NAME (cat
));
4289 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
4291 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
4293 category
= CLASS_CATEGORY_LIST (implementation_template
);
4295 /* find the category interface from the class it is associated with */
4298 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
4300 category
= CLASS_CATEGORY_LIST (category
);
4303 if (category
&& CLASS_PROTOCOL_LIST (category
))
4305 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
4306 protocol_decl
= generate_protocol_list (category
);
4311 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4312 decl_specs
= tree_cons (NULL_TREE
, objc_category_template
, sc_spec
);
4314 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4315 objc_implementation_context
),
4316 decl_specs
, 1, NULL_TREE
);
4318 initlist
= build_category_initializer (TREE_TYPE (decl
),
4319 cat_name_expr
, class_name_expr
,
4320 UOBJC_INSTANCE_METHODS_decl
,
4321 UOBJC_CLASS_METHODS_decl
,
4324 TREE_USED (decl
) = 1;
4325 finish_decl (decl
, initlist
, NULL_TREE
);
4328 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4329 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4332 generate_shared_structures ()
4334 tree sc_spec
, decl_specs
, decl
;
4335 tree name_expr
, super_expr
, root_expr
;
4336 tree my_root_id
= NULL_TREE
, my_super_id
= NULL_TREE
;
4337 tree cast_type
, initlist
, protocol_decl
;
4339 my_super_id
= CLASS_SUPER_NAME (implementation_template
);
4342 add_class_reference (my_super_id
);
4344 /* Compute "my_root_id" - this is required for code generation.
4345 the "isa" for all meta class structures points to the root of
4346 the inheritance hierarchy (e.g. "__Object")... */
4347 my_root_id
= my_super_id
;
4350 tree my_root_int
= lookup_interface (my_root_id
);
4352 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
4353 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
4360 /* No super class. */
4361 my_root_id
= CLASS_NAME (implementation_template
);
4364 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
4365 objc_class_template
),
4366 build1 (INDIRECT_REF
,
4367 NULL_TREE
, NULL_TREE
)));
4369 name_expr
= add_objc_string (CLASS_NAME (implementation_template
),
4372 /* Install class `isa' and `super' pointers at runtime. */
4375 super_expr
= add_objc_string (my_super_id
, class_names
);
4376 super_expr
= build_c_cast (cast_type
, super_expr
); /* cast! */
4379 super_expr
= build_int_2 (0, 0);
4381 root_expr
= add_objc_string (my_root_id
, class_names
);
4382 root_expr
= build_c_cast (cast_type
, root_expr
); /* cast! */
4384 if (CLASS_PROTOCOL_LIST (implementation_template
))
4386 generate_protocol_references
4387 (CLASS_PROTOCOL_LIST (implementation_template
));
4388 protocol_decl
= generate_protocol_list (implementation_template
);
4393 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4395 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
4396 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
4398 decl
= start_decl (DECL_NAME (UOBJC_METACLASS_decl
), decl_specs
, 1,
4402 = build_shared_structure_initializer
4404 root_expr
, super_expr
, name_expr
,
4405 convert (integer_type_node
, TYPE_SIZE_UNIT (objc_class_template
)),
4407 UOBJC_CLASS_METHODS_decl
,
4408 UOBJC_CLASS_VARIABLES_decl
,
4411 finish_decl (decl
, initlist
, NULL_TREE
);
4413 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4415 decl
= start_decl (DECL_NAME (UOBJC_CLASS_decl
), decl_specs
, 1,
4419 = build_shared_structure_initializer
4421 build_unary_op (ADDR_EXPR
, UOBJC_METACLASS_decl
, 0),
4422 super_expr
, name_expr
,
4423 convert (integer_type_node
,
4424 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
4425 (implementation_template
))),
4427 UOBJC_INSTANCE_METHODS_decl
,
4428 UOBJC_INSTANCE_VARIABLES_decl
,
4431 finish_decl (decl
, initlist
, NULL_TREE
);
4435 synth_id_with_class_suffix (preamble
, ctxt
)
4436 const char *preamble
;
4440 if (TREE_CODE (ctxt
) == CLASS_IMPLEMENTATION_TYPE
4441 || TREE_CODE (ctxt
) == CLASS_INTERFACE_TYPE
)
4443 const char *const class_name
4444 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
4445 string
= (char *) alloca (strlen (preamble
) + strlen (class_name
) + 3);
4446 sprintf (string
, "%s_%s", preamble
,
4447 IDENTIFIER_POINTER (CLASS_NAME (ctxt
)));
4449 else if (TREE_CODE (ctxt
) == CATEGORY_IMPLEMENTATION_TYPE
4450 || TREE_CODE (ctxt
) == CATEGORY_INTERFACE_TYPE
)
4452 /* We have a category. */
4453 const char *const class_name
4454 = IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
4455 const char *const class_super_name
4456 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
));
4457 string
= (char *) alloca (strlen (preamble
)
4458 + strlen (class_name
)
4459 + strlen (class_super_name
)
4461 sprintf (string
, "%s_%s_%s", preamble
, class_name
, class_super_name
);
4463 else if (TREE_CODE (ctxt
) == PROTOCOL_INTERFACE_TYPE
)
4465 const char *protocol_name
= IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt
));
4467 = (char *) alloca (strlen (preamble
) + strlen (protocol_name
) + 3);
4468 sprintf (string
, "%s_%s", preamble
, protocol_name
);
4473 return get_identifier (string
);
4477 is_objc_type_qualifier (node
)
4480 return (TREE_CODE (node
) == IDENTIFIER_NODE
4481 && (node
== ridpointers
[(int) RID_CONST
]
4482 || node
== ridpointers
[(int) RID_VOLATILE
]
4483 || node
== ridpointers
[(int) RID_IN
]
4484 || node
== ridpointers
[(int) RID_OUT
]
4485 || node
== ridpointers
[(int) RID_INOUT
]
4486 || node
== ridpointers
[(int) RID_BYCOPY
]
4487 || node
== ridpointers
[(int) RID_BYREF
]
4488 || node
== ridpointers
[(int) RID_ONEWAY
]));
4491 /* If type is empty or only type qualifiers are present, add default
4492 type of id (otherwise grokdeclarator will default to int). */
4495 adjust_type_for_id_default (type
)
4498 tree declspecs
, chain
;
4501 return build_tree_list (build_tree_list (NULL_TREE
, objc_object_reference
),
4502 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4504 declspecs
= TREE_PURPOSE (type
);
4506 /* Determine if a typespec is present. */
4507 for (chain
= declspecs
;
4509 chain
= TREE_CHAIN (chain
))
4511 if (!is_objc_type_qualifier (TREE_VALUE (chain
)))
4515 return build_tree_list (tree_cons (NULL_TREE
, objc_object_reference
,
4517 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4522 selector ':' '(' typename ')' identifier
4525 Transform an Objective-C keyword argument into
4526 the C equivalent parameter declarator.
4528 In: key_name, an "identifier_node" (optional).
4529 arg_type, a "tree_list" (optional).
4530 arg_name, an "identifier_node".
4532 Note: It would be really nice to strongly type the preceding
4533 arguments in the function prototype; however, then I
4534 could not use the "accessor" macros defined in "tree.h".
4536 Out: an instance of "keyword_decl". */
4539 build_keyword_decl (key_name
, arg_type
, arg_name
)
4546 /* If no type is specified, default to "id". */
4547 arg_type
= adjust_type_for_id_default (arg_type
);
4549 keyword_decl
= make_node (KEYWORD_DECL
);
4551 TREE_TYPE (keyword_decl
) = arg_type
;
4552 KEYWORD_ARG_NAME (keyword_decl
) = arg_name
;
4553 KEYWORD_KEY_NAME (keyword_decl
) = key_name
;
4555 return keyword_decl
;
4558 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4561 build_keyword_selector (selector
)
4565 tree key_chain
, key_name
;
4568 /* Scan the selector to see how much space we'll need. */
4569 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4571 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4572 key_name
= KEYWORD_KEY_NAME (key_chain
);
4573 else if (TREE_CODE (selector
) == TREE_LIST
)
4574 key_name
= TREE_PURPOSE (key_chain
);
4579 len
+= IDENTIFIER_LENGTH (key_name
) + 1;
4581 /* Just a ':' arg. */
4585 buf
= (char *) alloca (len
+ 1);
4586 /* Start the buffer out as an empty string. */
4589 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4591 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4592 key_name
= KEYWORD_KEY_NAME (key_chain
);
4593 else if (TREE_CODE (selector
) == TREE_LIST
)
4594 key_name
= TREE_PURPOSE (key_chain
);
4599 strcat (buf
, IDENTIFIER_POINTER (key_name
));
4603 return get_identifier (buf
);
4606 /* Used for declarations and definitions. */
4609 build_method_decl (code
, ret_type
, selector
, add_args
)
4610 enum tree_code code
;
4617 /* If no type is specified, default to "id". */
4618 ret_type
= adjust_type_for_id_default (ret_type
);
4620 method_decl
= make_node (code
);
4621 TREE_TYPE (method_decl
) = ret_type
;
4623 /* If we have a keyword selector, create an identifier_node that
4624 represents the full selector name (`:' included)... */
4625 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4627 METHOD_SEL_NAME (method_decl
) = build_keyword_selector (selector
);
4628 METHOD_SEL_ARGS (method_decl
) = selector
;
4629 METHOD_ADD_ARGS (method_decl
) = add_args
;
4633 METHOD_SEL_NAME (method_decl
) = selector
;
4634 METHOD_SEL_ARGS (method_decl
) = NULL_TREE
;
4635 METHOD_ADD_ARGS (method_decl
) = NULL_TREE
;
4641 #define METHOD_DEF 0
4642 #define METHOD_REF 1
4644 /* Used by `build_objc_method_call' and `comp_method_types'. Return
4645 an argument list for method METH. CONTEXT is either METHOD_DEF or
4646 METHOD_REF, saying whether we are trying to define a method or call
4647 one. SUPERFLAG says this is for a send to super; this makes a
4648 difference for the NeXT calling sequence in which the lookup and
4649 the method call are done together. */
4652 get_arg_type_list (meth
, context
, superflag
)
4659 /* Receiver type. */
4660 if (flag_next_runtime
&& superflag
)
4661 arglist
= build_tree_list (NULL_TREE
, super_type
);
4662 else if (context
== METHOD_DEF
)
4663 arglist
= build_tree_list (NULL_TREE
, TREE_TYPE (self_decl
));
4665 arglist
= build_tree_list (NULL_TREE
, id_type
);
4667 /* Selector type - will eventually change to `int'. */
4668 chainon (arglist
, build_tree_list (NULL_TREE
, selector_type
));
4670 /* Build a list of argument types. */
4671 for (akey
= METHOD_SEL_ARGS (meth
); akey
; akey
= TREE_CHAIN (akey
))
4673 tree arg_decl
= groktypename_in_parm_context (TREE_TYPE (akey
));
4674 chainon (arglist
, build_tree_list (NULL_TREE
, TREE_TYPE (arg_decl
)));
4677 if (METHOD_ADD_ARGS (meth
) == objc_ellipsis_node
)
4678 /* We have a `, ...' immediately following the selector,
4679 finalize the arglist...simulate get_parm_info (0). */
4681 else if (METHOD_ADD_ARGS (meth
))
4683 /* we have a variable length selector */
4684 tree add_arg_list
= TREE_CHAIN (METHOD_ADD_ARGS (meth
));
4685 chainon (arglist
, add_arg_list
);
4688 /* finalize the arglist...simulate get_parm_info (1) */
4689 chainon (arglist
, build_tree_list (NULL_TREE
, void_type_node
));
4695 check_duplicates (hsh
)
4698 tree meth
= NULL_TREE
;
4706 /* We have two methods with the same name and different types. */
4708 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
) ? '-' : '+';
4710 warning ("multiple declarations for method `%s'",
4711 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
4713 warn_with_method ("using", type
, meth
);
4714 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
4715 warn_with_method ("also found", type
, loop
->value
);
4721 /* If RECEIVER is a class reference, return the identifier node for
4722 the referenced class. RECEIVER is created by get_class_reference,
4723 so we check the exact form created depending on which runtimes are
4727 receiver_is_class_object (receiver
)
4730 tree chain
, exp
, arg
;
4732 /* The receiver is 'self' in the context of a class method. */
4733 if (objc_method_context
4734 && receiver
== self_decl
4735 && TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
4737 return CLASS_NAME (objc_implementation_context
);
4740 if (flag_next_runtime
)
4742 /* The receiver is a variable created by
4743 build_class_reference_decl. */
4744 if (TREE_CODE (receiver
) == VAR_DECL
4745 && TREE_TYPE (receiver
) == objc_class_type
)
4746 /* Look up the identifier. */
4747 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
4748 if (TREE_PURPOSE (chain
) == receiver
)
4749 return TREE_VALUE (chain
);
4753 /* The receiver is a function call that returns an id. Check if
4754 it is a call to objc_getClass, if so, pick up the class name. */
4755 if (TREE_CODE (receiver
) == CALL_EXPR
4756 && (exp
= TREE_OPERAND (receiver
, 0))
4757 && TREE_CODE (exp
) == ADDR_EXPR
4758 && (exp
= TREE_OPERAND (exp
, 0))
4759 && TREE_CODE (exp
) == FUNCTION_DECL
4760 && exp
== objc_get_class_decl
4761 /* We have a call to objc_getClass! */
4762 && (arg
= TREE_OPERAND (receiver
, 1))
4763 && TREE_CODE (arg
) == TREE_LIST
4764 && (arg
= TREE_VALUE (arg
)))
4767 if (TREE_CODE (arg
) == ADDR_EXPR
4768 && (arg
= TREE_OPERAND (arg
, 0))
4769 && TREE_CODE (arg
) == STRING_CST
)
4770 /* Finally, we have the class name. */
4771 return get_identifier (TREE_STRING_POINTER (arg
));
4777 /* If we are currently building a message expr, this holds
4778 the identifier of the selector of the message. This is
4779 used when printing warnings about argument mismatches. */
4781 static tree building_objc_message_expr
= 0;
4784 maybe_building_objc_message_expr ()
4786 return building_objc_message_expr
;
4789 /* Construct an expression for sending a message.
4790 MESS has the object to send to in TREE_PURPOSE
4791 and the argument list (including selector) in TREE_VALUE.
4793 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4794 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4797 build_message_expr (mess
)
4800 tree receiver
= TREE_PURPOSE (mess
);
4802 tree args
= TREE_VALUE (mess
);
4803 tree method_params
= NULL_TREE
;
4805 if (TREE_CODE (receiver
) == ERROR_MARK
)
4806 return error_mark_node
;
4808 /* Obtain the full selector name. */
4809 if (TREE_CODE (args
) == IDENTIFIER_NODE
)
4810 /* A unary selector. */
4812 else if (TREE_CODE (args
) == TREE_LIST
)
4813 sel_name
= build_keyword_selector (args
);
4817 /* Build the parameter list to give to the method. */
4818 if (TREE_CODE (args
) == TREE_LIST
)
4820 tree chain
= args
, prev
= NULL_TREE
;
4822 /* We have a keyword selector--check for comma expressions. */
4825 tree element
= TREE_VALUE (chain
);
4827 /* We have a comma expression, must collapse... */
4828 if (TREE_CODE (element
) == TREE_LIST
)
4831 TREE_CHAIN (prev
) = element
;
4836 chain
= TREE_CHAIN (chain
);
4838 method_params
= args
;
4841 return finish_message_expr (receiver
, sel_name
, method_params
);
4844 /* The 'finish_message_expr' routine is called from within
4845 'build_message_expr' for non-template functions. In the case of
4846 C++ template functions, it is called from 'build_expr_from_tree'
4847 (in decl2.c) after RECEIVER and METHOD_PARAMS have been expanded. */
4850 finish_message_expr (receiver
, sel_name
, method_params
)
4851 tree receiver
, sel_name
, method_params
;
4853 tree method_prototype
= NULL_TREE
, class_ident
= NULL_TREE
;
4854 tree selector
, self_object
, retval
;
4855 int statically_typed
= 0, statically_allocated
= 0;
4857 /* Determine receiver type. */
4858 tree rtype
= TREE_TYPE (receiver
);
4859 int super
= IS_SUPER (rtype
);
4863 if (TREE_STATIC_TEMPLATE (rtype
))
4864 statically_allocated
= 1;
4865 else if (TREE_CODE (rtype
) == POINTER_TYPE
4866 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype
)))
4867 statically_typed
= 1;
4868 else if ((flag_next_runtime
4870 && (class_ident
= receiver_is_class_object (receiver
)))
4872 else if (! IS_ID (rtype
)
4873 /* Allow any type that matches objc_class_type. */
4874 && ! comptypes (rtype
, objc_class_type
))
4876 warning ("invalid receiver type `%s'",
4877 gen_declaration (rtype
, errbuf
));
4879 if (statically_allocated
)
4880 receiver
= build_unary_op (ADDR_EXPR
, receiver
, 0);
4882 /* Don't evaluate the receiver twice. */
4883 receiver
= save_expr (receiver
);
4884 self_object
= receiver
;
4887 /* If sending to `super', use current self as the object. */
4888 self_object
= self_decl
;
4890 /* Determine operation return type. */
4896 if (CLASS_SUPER_NAME (implementation_template
))
4899 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
4901 if (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
)
4902 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4904 method_prototype
= lookup_class_method_static (iface
, sel_name
);
4906 if (iface
&& !method_prototype
)
4907 warning ("`%s' does not respond to `%s'",
4908 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template
)),
4909 IDENTIFIER_POINTER (sel_name
));
4913 error ("no super class declared in interface for `%s'",
4914 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
4915 return error_mark_node
;
4919 else if (statically_allocated
)
4921 tree ctype
= TREE_TYPE (rtype
);
4922 tree iface
= lookup_interface (TYPE_NAME (rtype
));
4925 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4927 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
4929 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
4932 if (!method_prototype
)
4933 warning ("`%s' does not respond to `%s'",
4934 IDENTIFIER_POINTER (TYPE_NAME (rtype
)),
4935 IDENTIFIER_POINTER (sel_name
));
4937 else if (statically_typed
)
4939 tree ctype
= TREE_TYPE (rtype
);
4941 /* `self' is now statically_typed. All methods should be visible
4942 within the context of the implementation. */
4943 if (objc_implementation_context
4944 && CLASS_NAME (objc_implementation_context
) == TYPE_NAME (ctype
))
4947 = lookup_instance_method_static (implementation_template
,
4950 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
4952 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
4955 if (! method_prototype
4956 && implementation_template
!= objc_implementation_context
)
4957 /* The method is not published in the interface. Check
4960 = lookup_method (CLASS_NST_METHODS (objc_implementation_context
),
4967 if ((iface
= lookup_interface (TYPE_NAME (ctype
))))
4968 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4970 if (! method_prototype
)
4972 tree protocol_list
= TYPE_PROTOCOL_LIST (ctype
);
4975 = lookup_method_in_protocol_list (protocol_list
,
4980 if (!method_prototype
)
4981 warning ("`%s' does not respond to `%s'",
4982 IDENTIFIER_POINTER (TYPE_NAME (ctype
)),
4983 IDENTIFIER_POINTER (sel_name
));
4985 else if (class_ident
)
4987 if (objc_implementation_context
4988 && CLASS_NAME (objc_implementation_context
) == class_ident
)
4991 = lookup_class_method_static (implementation_template
, sel_name
);
4993 if (!method_prototype
4994 && implementation_template
!= objc_implementation_context
)
4995 /* The method is not published in the interface. Check
4998 = lookup_method (CLASS_CLS_METHODS (objc_implementation_context
),
5005 if ((iface
= lookup_interface (class_ident
)))
5006 method_prototype
= lookup_class_method_static (iface
, sel_name
);
5009 if (!method_prototype
)
5011 warning ("cannot find class (factory) method");
5012 warning ("return type for `%s' defaults to id",
5013 IDENTIFIER_POINTER (sel_name
));
5016 else if (IS_PROTOCOL_QUALIFIED_ID (rtype
))
5018 /* An anonymous object that has been qualified with a protocol. */
5020 tree protocol_list
= TYPE_PROTOCOL_LIST (rtype
);
5022 method_prototype
= lookup_method_in_protocol_list (protocol_list
,
5025 if (!method_prototype
)
5029 warning ("method `%s' not implemented by protocol",
5030 IDENTIFIER_POINTER (sel_name
));
5032 /* Try and find the method signature in the global pools. */
5034 if (!(hsh
= hash_lookup (nst_method_hash_list
, sel_name
)))
5035 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5037 if (!(method_prototype
= check_duplicates (hsh
)))
5038 warning ("return type defaults to id");
5045 /* We think we have an instance...loophole: extern id Object; */
5046 hsh
= hash_lookup (nst_method_hash_list
, sel_name
);
5049 /* For various loopholes */
5050 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5052 method_prototype
= check_duplicates (hsh
);
5053 if (!method_prototype
)
5055 warning ("cannot find method");
5056 warning ("return type for `%s' defaults to id",
5057 IDENTIFIER_POINTER (sel_name
));
5061 /* Save the selector name for printing error messages. */
5062 building_objc_message_expr
= sel_name
;
5064 /* Build the parameters list for looking up the method.
5065 These are the object itself and the selector. */
5067 if (flag_typed_selectors
)
5068 selector
= build_typed_selector_reference (sel_name
, method_prototype
);
5070 selector
= build_selector_reference (sel_name
);
5072 retval
= build_objc_method_call (super
, method_prototype
,
5073 receiver
, self_object
,
5074 selector
, method_params
);
5076 building_objc_message_expr
= 0;
5081 /* Build a tree expression to send OBJECT the operation SELECTOR,
5082 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5083 assuming the method has prototype METHOD_PROTOTYPE.
5084 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5085 Use METHOD_PARAMS as list of args to pass to the method.
5086 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5089 build_objc_method_call (super_flag
, method_prototype
, lookup_object
, object
,
5090 selector
, method_params
)
5092 tree method_prototype
, lookup_object
, object
, selector
, method_params
;
5094 tree sender
= (super_flag
? umsg_super_decl
: umsg_decl
);
5095 tree rcv_p
= (super_flag
5096 ? build_pointer_type (xref_tag (RECORD_TYPE
,
5097 get_identifier (TAG_SUPER
)))
5100 if (flag_next_runtime
)
5102 if (! method_prototype
)
5104 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5105 tree_cons (NULL_TREE
, selector
,
5107 assemble_external (sender
);
5108 return build_function_call (sender
, method_params
);
5112 /* This is a real kludge, but it is used only for the Next.
5113 Clobber the data type of SENDER temporarily to accept
5114 all the arguments for this operation, and to return
5115 whatever this operation returns. */
5116 tree arglist
= NULL_TREE
, retval
, savarg
, savret
;
5117 tree ret_type
= groktypename (TREE_TYPE (method_prototype
));
5119 /* Save the proper contents of SENDER's data type. */
5120 savarg
= TYPE_ARG_TYPES (TREE_TYPE (sender
));
5121 savret
= TREE_TYPE (TREE_TYPE (sender
));
5123 /* Install this method's argument types. */
5124 arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5126 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = arglist
;
5128 /* Install this method's return type. */
5129 TREE_TYPE (TREE_TYPE (sender
)) = ret_type
;
5131 /* Call SENDER with all the parameters. This will do type
5132 checking using the arg types for this method. */
5133 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5134 tree_cons (NULL_TREE
, selector
,
5136 assemble_external (sender
);
5137 retval
= build_function_call (sender
, method_params
);
5139 /* Restore SENDER's return/argument types. */
5140 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = savarg
;
5141 TREE_TYPE (TREE_TYPE (sender
)) = savret
;
5147 /* This is the portable way.
5148 First call the lookup function to get a pointer to the method,
5149 then cast the pointer, then call it with the method arguments. */
5152 /* Avoid trouble since we may evaluate each of these twice. */
5153 object
= save_expr (object
);
5154 selector
= save_expr (selector
);
5156 lookup_object
= build_c_cast (rcv_p
, lookup_object
);
5158 assemble_external (sender
);
5160 = build_function_call (sender
,
5161 tree_cons (NULL_TREE
, lookup_object
,
5162 tree_cons (NULL_TREE
, selector
,
5165 /* If we have a method prototype, construct the data type this
5166 method needs, and cast what we got from SENDER into a pointer
5168 if (method_prototype
)
5170 tree arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5172 tree valtype
= groktypename (TREE_TYPE (method_prototype
));
5173 tree fake_function_type
= build_function_type (valtype
, arglist
);
5174 TREE_TYPE (method
) = build_pointer_type (fake_function_type
);
5178 = build_pointer_type (build_function_type (ptr_type_node
, NULL_TREE
));
5180 /* Pass the object to the method. */
5181 assemble_external (method
);
5182 return build_function_call (method
,
5183 tree_cons (NULL_TREE
, object
,
5184 tree_cons (NULL_TREE
, selector
,
5190 build_protocol_reference (p
)
5193 tree decl
, ident
, ptype
;
5195 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5197 ident
= synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
);
5199 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
5200 objc_protocol_template
),
5203 if (IDENTIFIER_GLOBAL_VALUE (ident
))
5204 decl
= IDENTIFIER_GLOBAL_VALUE (ident
); /* Set by pushdecl. */
5207 decl
= build_decl (VAR_DECL
, ident
, ptype
);
5208 DECL_EXTERNAL (decl
) = 1;
5209 TREE_PUBLIC (decl
) = 1;
5210 TREE_USED (decl
) = 1;
5211 DECL_ARTIFICIAL (decl
) = 1;
5213 make_decl_rtl (decl
, 0);
5214 pushdecl_top_level (decl
);
5217 PROTOCOL_FORWARD_DECL (p
) = decl
;
5221 build_protocol_expr (protoname
)
5225 tree p
= lookup_protocol (protoname
);
5229 error ("cannot find protocol declaration for `%s'",
5230 IDENTIFIER_POINTER (protoname
));
5231 return error_mark_node
;
5234 if (!PROTOCOL_FORWARD_DECL (p
))
5235 build_protocol_reference (p
);
5237 expr
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
5239 TREE_TYPE (expr
) = protocol_type
;
5245 build_selector_expr (selnamelist
)
5250 /* Obtain the full selector name. */
5251 if (TREE_CODE (selnamelist
) == IDENTIFIER_NODE
)
5252 /* A unary selector. */
5253 selname
= selnamelist
;
5254 else if (TREE_CODE (selnamelist
) == TREE_LIST
)
5255 selname
= build_keyword_selector (selnamelist
);
5259 if (flag_typed_selectors
)
5260 return build_typed_selector_reference (selname
, 0);
5262 return build_selector_reference (selname
);
5266 build_encode_expr (type
)
5272 encode_type (type
, obstack_object_size (&util_obstack
),
5273 OBJC_ENCODE_INLINE_DEFS
);
5274 obstack_1grow (&util_obstack
, 0); /* null terminate string */
5275 string
= obstack_finish (&util_obstack
);
5277 /* Synthesize a string that represents the encoded struct/union. */
5278 result
= my_build_string (strlen (string
) + 1, string
);
5279 obstack_free (&util_obstack
, util_firstobj
);
5284 build_ivar_reference (id
)
5287 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
5289 /* Historically, a class method that produced objects (factory
5290 method) would assign `self' to the instance that it
5291 allocated. This would effectively turn the class method into
5292 an instance method. Following this assignment, the instance
5293 variables could be accessed. That practice, while safe,
5294 violates the simple rule that a class method should not refer
5295 to an instance variable. It's better to catch the cases
5296 where this is done unknowingly than to support the above
5298 warning ("instance variable `%s' accessed in class method",
5299 IDENTIFIER_POINTER (id
));
5300 TREE_TYPE (self_decl
) = instance_type
; /* cast */
5303 return build_component_ref (build_indirect_ref (self_decl
, "->"), id
);
5306 /* Compute a hash value for a given method SEL_NAME. */
5309 hash_func (sel_name
)
5312 const unsigned char *s
5313 = (const unsigned char *)IDENTIFIER_POINTER (sel_name
);
5317 h
= h
* 67 + *s
++ - 113;
5324 nst_method_hash_list
= (hash
*) xcalloc (SIZEHASHTABLE
, sizeof (hash
));
5325 cls_method_hash_list
= (hash
*) xcalloc (SIZEHASHTABLE
, sizeof (hash
));
5328 /* WARNING!!!! hash_enter is called with a method, and will peek
5329 inside to find its selector! But hash_lookup is given a selector
5330 directly, and looks for the selector that's inside the found
5331 entry's key (method) for comparison. */
5334 hash_enter (hashlist
, method
)
5338 static hash hash_alloc_list
= 0;
5339 static int hash_alloc_index
= 0;
5341 int slot
= hash_func (METHOD_SEL_NAME (method
)) % SIZEHASHTABLE
;
5343 if (! hash_alloc_list
|| hash_alloc_index
>= HASH_ALLOC_LIST_SIZE
)
5345 hash_alloc_index
= 0;
5346 hash_alloc_list
= (hash
) xmalloc (sizeof (struct hashed_entry
)
5347 * HASH_ALLOC_LIST_SIZE
);
5349 obj
= &hash_alloc_list
[hash_alloc_index
++];
5351 obj
->next
= hashlist
[slot
];
5354 hashlist
[slot
] = obj
; /* append to front */
5358 hash_lookup (hashlist
, sel_name
)
5364 target
= hashlist
[hash_func (sel_name
) % SIZEHASHTABLE
];
5368 if (sel_name
== METHOD_SEL_NAME (target
->key
))
5371 target
= target
->next
;
5377 hash_add_attr (entry
, value
)
5381 static attr attr_alloc_list
= 0;
5382 static int attr_alloc_index
= 0;
5385 if (! attr_alloc_list
|| attr_alloc_index
>= ATTR_ALLOC_LIST_SIZE
)
5387 attr_alloc_index
= 0;
5388 attr_alloc_list
= (attr
) xmalloc (sizeof (struct hashed_attribute
)
5389 * ATTR_ALLOC_LIST_SIZE
);
5391 obj
= &attr_alloc_list
[attr_alloc_index
++];
5392 obj
->next
= entry
->list
;
5395 entry
->list
= obj
; /* append to front */
5399 lookup_method (mchain
, method
)
5405 if (TREE_CODE (method
) == IDENTIFIER_NODE
)
5408 key
= METHOD_SEL_NAME (method
);
5412 if (METHOD_SEL_NAME (mchain
) == key
)
5414 mchain
= TREE_CHAIN (mchain
);
5420 lookup_instance_method_static (interface
, ident
)
5424 tree inter
= interface
;
5425 tree chain
= CLASS_NST_METHODS (inter
);
5426 tree meth
= NULL_TREE
;
5430 if ((meth
= lookup_method (chain
, ident
)))
5433 if (CLASS_CATEGORY_LIST (inter
))
5435 tree category
= CLASS_CATEGORY_LIST (inter
);
5436 chain
= CLASS_NST_METHODS (category
);
5440 if ((meth
= lookup_method (chain
, ident
)))
5443 /* Check for instance methods in protocols in categories. */
5444 if (CLASS_PROTOCOL_LIST (category
))
5446 if ((meth
= (lookup_method_in_protocol_list
5447 (CLASS_PROTOCOL_LIST (category
), ident
, 0))))
5451 if ((category
= CLASS_CATEGORY_LIST (category
)))
5452 chain
= CLASS_NST_METHODS (category
);
5457 if (CLASS_PROTOCOL_LIST (inter
))
5459 if ((meth
= (lookup_method_in_protocol_list
5460 (CLASS_PROTOCOL_LIST (inter
), ident
, 0))))
5464 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5465 chain
= CLASS_NST_METHODS (inter
);
5473 lookup_class_method_static (interface
, ident
)
5477 tree inter
= interface
;
5478 tree chain
= CLASS_CLS_METHODS (inter
);
5479 tree meth
= NULL_TREE
;
5480 tree root_inter
= NULL_TREE
;
5484 if ((meth
= lookup_method (chain
, ident
)))
5487 if (CLASS_CATEGORY_LIST (inter
))
5489 tree category
= CLASS_CATEGORY_LIST (inter
);
5490 chain
= CLASS_CLS_METHODS (category
);
5494 if ((meth
= lookup_method (chain
, ident
)))
5497 /* Check for class methods in protocols in categories. */
5498 if (CLASS_PROTOCOL_LIST (category
))
5500 if ((meth
= (lookup_method_in_protocol_list
5501 (CLASS_PROTOCOL_LIST (category
), ident
, 1))))
5505 if ((category
= CLASS_CATEGORY_LIST (category
)))
5506 chain
= CLASS_CLS_METHODS (category
);
5511 /* Check for class methods in protocols. */
5512 if (CLASS_PROTOCOL_LIST (inter
))
5514 if ((meth
= (lookup_method_in_protocol_list
5515 (CLASS_PROTOCOL_LIST (inter
), ident
, 1))))
5520 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5521 chain
= CLASS_CLS_METHODS (inter
);
5525 /* If no class (factory) method was found, check if an _instance_
5526 method of the same name exists in the root class. This is what
5527 the Objective-C runtime will do. */
5528 return lookup_instance_method_static (root_inter
, ident
);
5532 add_class_method (class, method
)
5539 if (!(mth
= lookup_method (CLASS_CLS_METHODS (class), method
)))
5541 /* put method on list in reverse order */
5542 TREE_CHAIN (method
) = CLASS_CLS_METHODS (class);
5543 CLASS_CLS_METHODS (class) = method
;
5547 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5548 error ("duplicate definition of class method `%s'",
5549 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5552 /* Check types; if different, complain. */
5553 if (!comp_proto_with_proto (method
, mth
))
5554 error ("duplicate declaration of class method `%s'",
5555 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5559 if (!(hsh
= hash_lookup (cls_method_hash_list
, METHOD_SEL_NAME (method
))))
5561 /* Install on a global chain. */
5562 hash_enter (cls_method_hash_list
, method
);
5566 /* Check types; if different, add to a list. */
5567 if (!comp_proto_with_proto (method
, hsh
->key
))
5568 hash_add_attr (hsh
, method
);
5574 add_instance_method (class, method
)
5581 if (!(mth
= lookup_method (CLASS_NST_METHODS (class), method
)))
5583 /* Put method on list in reverse order. */
5584 TREE_CHAIN (method
) = CLASS_NST_METHODS (class);
5585 CLASS_NST_METHODS (class) = method
;
5589 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5590 error ("duplicate definition of instance method `%s'",
5591 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5594 /* Check types; if different, complain. */
5595 if (!comp_proto_with_proto (method
, mth
))
5596 error ("duplicate declaration of instance method `%s'",
5597 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5601 if (!(hsh
= hash_lookup (nst_method_hash_list
, METHOD_SEL_NAME (method
))))
5603 /* Install on a global chain. */
5604 hash_enter (nst_method_hash_list
, method
);
5608 /* Check types; if different, add to a list. */
5609 if (!comp_proto_with_proto (method
, hsh
->key
))
5610 hash_add_attr (hsh
, method
);
5619 /* Put interfaces on list in reverse order. */
5620 TREE_CHAIN (class) = interface_chain
;
5621 interface_chain
= class;
5622 return interface_chain
;
5626 add_category (class, category
)
5630 /* Put categories on list in reverse order. */
5631 tree cat
= CLASS_CATEGORY_LIST (class);
5635 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
5636 warning ("duplicate interface declaration for category `%s(%s)'",
5637 IDENTIFIER_POINTER (CLASS_NAME (class)),
5638 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category
)));
5639 cat
= CLASS_CATEGORY_LIST (cat
);
5642 CLASS_CATEGORY_LIST (category
) = CLASS_CATEGORY_LIST (class);
5643 CLASS_CATEGORY_LIST (class) = category
;
5646 /* Called after parsing each instance variable declaration. Necessary to
5647 preserve typedefs and implement public/private...
5649 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5652 add_instance_variable (class, public, declarator
, declspecs
, width
)
5659 tree field_decl
, raw_decl
;
5661 raw_decl
= build_tree_list (declspecs
, declarator
);
5663 if (CLASS_RAW_IVARS (class))
5664 chainon (CLASS_RAW_IVARS (class), raw_decl
);
5666 CLASS_RAW_IVARS (class) = raw_decl
;
5668 field_decl
= grokfield (input_filename
, lineno
,
5669 declarator
, declspecs
, width
);
5671 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5675 TREE_PUBLIC (field_decl
) = 0;
5676 TREE_PRIVATE (field_decl
) = 0;
5677 TREE_PROTECTED (field_decl
) = 1;
5681 TREE_PUBLIC (field_decl
) = 1;
5682 TREE_PRIVATE (field_decl
) = 0;
5683 TREE_PROTECTED (field_decl
) = 0;
5687 TREE_PUBLIC (field_decl
) = 0;
5688 TREE_PRIVATE (field_decl
) = 1;
5689 TREE_PROTECTED (field_decl
) = 0;
5694 if (CLASS_IVARS (class))
5695 chainon (CLASS_IVARS (class), field_decl
);
5697 CLASS_IVARS (class) = field_decl
;
5703 is_ivar (decl_chain
, ident
)
5707 for ( ; decl_chain
; decl_chain
= TREE_CHAIN (decl_chain
))
5708 if (DECL_NAME (decl_chain
) == ident
)
5713 /* True if the ivar is private and we are not in its implementation. */
5719 if (TREE_PRIVATE (decl
)
5720 && ! is_ivar (CLASS_IVARS (implementation_template
), DECL_NAME (decl
)))
5722 error ("instance variable `%s' is declared private",
5723 IDENTIFIER_POINTER (DECL_NAME (decl
)));
5730 /* We have an instance variable reference;, check to see if it is public. */
5733 is_public (expr
, identifier
)
5737 tree basetype
= TREE_TYPE (expr
);
5738 enum tree_code code
= TREE_CODE (basetype
);
5741 if (code
== RECORD_TYPE
)
5743 if (TREE_STATIC_TEMPLATE (basetype
))
5745 if (!lookup_interface (TYPE_NAME (basetype
)))
5747 error ("cannot find interface declaration for `%s'",
5748 IDENTIFIER_POINTER (TYPE_NAME (basetype
)));
5752 if ((decl
= is_ivar (TYPE_FIELDS (basetype
), identifier
)))
5754 if (TREE_PUBLIC (decl
))
5757 /* Important difference between the Stepstone translator:
5758 all instance variables should be public within the context
5759 of the implementation. */
5760 if (objc_implementation_context
5761 && (((TREE_CODE (objc_implementation_context
)
5762 == CLASS_IMPLEMENTATION_TYPE
)
5763 || (TREE_CODE (objc_implementation_context
)
5764 == CATEGORY_IMPLEMENTATION_TYPE
))
5765 && (CLASS_NAME (objc_implementation_context
)
5766 == TYPE_NAME (basetype
))))
5767 return ! is_private (decl
);
5769 error ("instance variable `%s' is declared %s",
5770 IDENTIFIER_POINTER (identifier
),
5771 TREE_PRIVATE (decl
) ? "private" : "protected");
5776 else if (objc_implementation_context
&& (basetype
== objc_object_reference
))
5778 TREE_TYPE (expr
) = uprivate_record
;
5779 warning ("static access to object of type `id'");
5786 /* Implement @defs (<classname>) within struct bodies. */
5789 get_class_ivars (interface
)
5792 /* Make sure we copy the leaf ivars in case @defs is used in a local
5793 context. Otherwise finish_struct will overwrite the layout info
5794 using temporary storage. */
5795 return build_ivar_chain (interface
, 1);
5798 /* Make sure all entries in CHAIN are also in LIST. */
5801 check_methods (chain
, list
, mtype
)
5810 if (!lookup_method (list
, chain
))
5814 if (TREE_CODE (objc_implementation_context
)
5815 == CLASS_IMPLEMENTATION_TYPE
)
5816 warning ("incomplete implementation of class `%s'",
5817 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
)));
5818 else if (TREE_CODE (objc_implementation_context
)
5819 == CATEGORY_IMPLEMENTATION_TYPE
)
5820 warning ("incomplete implementation of category `%s'",
5821 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
5825 warning ("method definition for `%c%s' not found",
5826 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
5829 chain
= TREE_CHAIN (chain
);
5835 /* Check if CLASS, or its superclasses, explicitly conforms to PROTOCOL. */
5838 conforms_to_protocol (class, protocol
)
5842 if (TREE_CODE (protocol
) == PROTOCOL_INTERFACE_TYPE
)
5844 tree p
= CLASS_PROTOCOL_LIST (class);
5845 while (p
&& TREE_VALUE (p
) != protocol
)
5850 tree super
= (CLASS_SUPER_NAME (class)
5851 ? lookup_interface (CLASS_SUPER_NAME (class))
5853 int tmp
= super
? conforms_to_protocol (super
, protocol
) : 0;
5862 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5863 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5866 check_methods_accessible (chain
, context
, mtype
)
5873 tree base_context
= context
;
5877 context
= base_context
;
5881 list
= CLASS_CLS_METHODS (context
);
5883 list
= CLASS_NST_METHODS (context
);
5885 if (lookup_method (list
, chain
))
5888 else if (TREE_CODE (context
) == CLASS_IMPLEMENTATION_TYPE
5889 || TREE_CODE (context
) == CLASS_INTERFACE_TYPE
)
5890 context
= (CLASS_SUPER_NAME (context
)
5891 ? lookup_interface (CLASS_SUPER_NAME (context
))
5894 else if (TREE_CODE (context
) == CATEGORY_IMPLEMENTATION_TYPE
5895 || TREE_CODE (context
) == CATEGORY_INTERFACE_TYPE
)
5896 context
= (CLASS_NAME (context
)
5897 ? lookup_interface (CLASS_NAME (context
))
5903 if (context
== NULL_TREE
)
5907 if (TREE_CODE (objc_implementation_context
)
5908 == CLASS_IMPLEMENTATION_TYPE
)
5909 warning ("incomplete implementation of class `%s'",
5911 (CLASS_NAME (objc_implementation_context
)));
5912 else if (TREE_CODE (objc_implementation_context
)
5913 == CATEGORY_IMPLEMENTATION_TYPE
)
5914 warning ("incomplete implementation of category `%s'",
5916 (CLASS_SUPER_NAME (objc_implementation_context
)));
5919 warning ("method definition for `%c%s' not found",
5920 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
5923 chain
= TREE_CHAIN (chain
); /* next method... */
5928 /* Check whether the current interface (accessible via
5929 'objc_implementation_context') actually implements protocol P, along
5930 with any protocols that P inherits. */
5933 check_protocol (p
, type
, name
)
5938 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
5942 /* Ensure that all protocols have bodies! */
5943 if (flag_warn_protocol
)
5945 f1
= check_methods (PROTOCOL_CLS_METHODS (p
),
5946 CLASS_CLS_METHODS (objc_implementation_context
),
5948 f2
= check_methods (PROTOCOL_NST_METHODS (p
),
5949 CLASS_NST_METHODS (objc_implementation_context
),
5954 f1
= check_methods_accessible (PROTOCOL_CLS_METHODS (p
),
5955 objc_implementation_context
,
5957 f2
= check_methods_accessible (PROTOCOL_NST_METHODS (p
),
5958 objc_implementation_context
,
5963 warning ("%s `%s' does not fully implement the `%s' protocol",
5964 type
, name
, IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
5967 /* Check protocols recursively. */
5968 if (PROTOCOL_LIST (p
))
5970 tree subs
= PROTOCOL_LIST (p
);
5972 lookup_interface (CLASS_SUPER_NAME (implementation_template
));
5976 tree sub
= TREE_VALUE (subs
);
5978 /* If the superclass does not conform to the protocols
5979 inherited by P, then we must! */
5980 if (!super_class
|| !conforms_to_protocol (super_class
, sub
))
5981 check_protocol (sub
, type
, name
);
5982 subs
= TREE_CHAIN (subs
);
5987 /* Check whether the current interface (accessible via
5988 'objc_implementation_context') actually implements the protocols listed
5992 check_protocols (proto_list
, type
, name
)
5997 for ( ; proto_list
; proto_list
= TREE_CHAIN (proto_list
))
5999 tree p
= TREE_VALUE (proto_list
);
6001 check_protocol (p
, type
, name
);
6005 /* Make sure that the class CLASS_NAME is defined
6006 CODE says which kind of thing CLASS_NAME ought to be.
6007 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6008 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. */
6011 start_class (code
, class_name
, super_name
, protocol_list
)
6012 enum tree_code code
;
6019 if (objc_implementation_context
)
6021 warning ("`@end' missing in implementation context");
6022 finish_class (objc_implementation_context
);
6023 objc_ivar_chain
= NULL_TREE
;
6024 objc_implementation_context
= NULL_TREE
;
6027 class = make_node (code
);
6028 TYPE_BINFO (class) = make_tree_vec (5);
6030 CLASS_NAME (class) = class_name
;
6031 CLASS_SUPER_NAME (class) = super_name
;
6032 CLASS_CLS_METHODS (class) = NULL_TREE
;
6034 if (! is_class_name (class_name
) && (decl
= lookup_name (class_name
)))
6036 error ("`%s' redeclared as different kind of symbol",
6037 IDENTIFIER_POINTER (class_name
));
6038 error_with_decl (decl
, "previous declaration of `%s'");
6041 if (code
== CLASS_IMPLEMENTATION_TYPE
)
6046 for (chain
= implemented_classes
; chain
; chain
= TREE_CHAIN (chain
))
6047 if (TREE_VALUE (chain
) == class_name
)
6049 error ("reimplementation of class `%s'",
6050 IDENTIFIER_POINTER (class_name
));
6051 return error_mark_node
;
6053 implemented_classes
= tree_cons (NULL_TREE
, class_name
,
6054 implemented_classes
);
6057 /* Pre-build the following entities - for speed/convenience. */
6059 self_id
= get_identifier ("self");
6061 ucmd_id
= get_identifier ("_cmd");
6064 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6065 if (!objc_super_template
)
6066 objc_super_template
= build_super_template ();
6068 /* Reset for multiple classes per file. */
6071 objc_implementation_context
= class;
6073 /* Lookup the interface for this implementation. */
6075 if (!(implementation_template
= lookup_interface (class_name
)))
6077 warning ("cannot find interface declaration for `%s'",
6078 IDENTIFIER_POINTER (class_name
));
6079 add_class (implementation_template
= objc_implementation_context
);
6082 /* If a super class has been specified in the implementation,
6083 insure it conforms to the one specified in the interface. */
6086 && (super_name
!= CLASS_SUPER_NAME (implementation_template
)))
6088 tree previous_name
= CLASS_SUPER_NAME (implementation_template
);
6089 const char *const name
=
6090 previous_name
? IDENTIFIER_POINTER (previous_name
) : "";
6091 error ("conflicting super class name `%s'",
6092 IDENTIFIER_POINTER (super_name
));
6093 error ("previous declaration of `%s'", name
);
6096 else if (! super_name
)
6098 CLASS_SUPER_NAME (objc_implementation_context
)
6099 = CLASS_SUPER_NAME (implementation_template
);
6103 else if (code
== CLASS_INTERFACE_TYPE
)
6105 if (lookup_interface (class_name
))
6106 warning ("duplicate interface declaration for class `%s'",
6107 IDENTIFIER_POINTER (class_name
));
6112 CLASS_PROTOCOL_LIST (class)
6113 = lookup_and_install_protocols (protocol_list
);
6116 else if (code
== CATEGORY_INTERFACE_TYPE
)
6118 tree class_category_is_assoc_with
;
6120 /* For a category, class_name is really the name of the class that
6121 the following set of methods will be associated with. We must
6122 find the interface so that can derive the objects template. */
6124 if (!(class_category_is_assoc_with
= lookup_interface (class_name
)))
6126 error ("cannot find interface declaration for `%s'",
6127 IDENTIFIER_POINTER (class_name
));
6128 exit (FATAL_EXIT_CODE
);
6131 add_category (class_category_is_assoc_with
, class);
6134 CLASS_PROTOCOL_LIST (class)
6135 = lookup_and_install_protocols (protocol_list
);
6138 else if (code
== CATEGORY_IMPLEMENTATION_TYPE
)
6140 /* Pre-build the following entities for speed/convenience. */
6142 self_id
= get_identifier ("self");
6144 ucmd_id
= get_identifier ("_cmd");
6147 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6148 if (!objc_super_template
)
6149 objc_super_template
= build_super_template ();
6151 /* Reset for multiple classes per file. */
6154 objc_implementation_context
= class;
6156 /* For a category, class_name is really the name of the class that
6157 the following set of methods will be associated with. We must
6158 find the interface so that can derive the objects template. */
6160 if (!(implementation_template
= lookup_interface (class_name
)))
6162 error ("cannot find interface declaration for `%s'",
6163 IDENTIFIER_POINTER (class_name
));
6164 exit (FATAL_EXIT_CODE
);
6171 continue_class (class)
6174 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6175 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6177 struct imp_entry
*imp_entry
;
6180 /* Check consistency of the instance variables. */
6182 if (CLASS_IVARS (class))
6183 check_ivars (implementation_template
, class);
6185 /* code generation */
6187 ivar_context
= build_private_template (implementation_template
);
6189 if (!objc_class_template
)
6190 build_class_template ();
6192 imp_entry
= (struct imp_entry
*) xmalloc (sizeof (struct imp_entry
));
6194 imp_entry
->next
= imp_list
;
6195 imp_entry
->imp_context
= class;
6196 imp_entry
->imp_template
= implementation_template
;
6198 synth_forward_declarations ();
6199 imp_entry
->class_decl
= UOBJC_CLASS_decl
;
6200 imp_entry
->meta_decl
= UOBJC_METACLASS_decl
;
6202 /* Append to front and increment count. */
6203 imp_list
= imp_entry
;
6204 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6209 return ivar_context
;
6212 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6214 tree record
= xref_tag (RECORD_TYPE
, CLASS_NAME (class));
6216 if (!TYPE_FIELDS (record
))
6218 finish_struct (record
, build_ivar_chain (class, 0), NULL_TREE
);
6219 CLASS_STATIC_TEMPLATE (class) = record
;
6221 /* Mark this record as a class template for static typing. */
6222 TREE_STATIC_TEMPLATE (record
) = 1;
6229 return error_mark_node
;
6232 /* This is called once we see the "@end" in an interface/implementation. */
6235 finish_class (class)
6238 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6240 /* All code generation is done in finish_objc. */
6242 if (implementation_template
!= objc_implementation_context
)
6244 /* Ensure that all method listed in the interface contain bodies. */
6245 check_methods (CLASS_CLS_METHODS (implementation_template
),
6246 CLASS_CLS_METHODS (objc_implementation_context
), '+');
6247 check_methods (CLASS_NST_METHODS (implementation_template
),
6248 CLASS_NST_METHODS (objc_implementation_context
), '-');
6250 if (CLASS_PROTOCOL_LIST (implementation_template
))
6251 check_protocols (CLASS_PROTOCOL_LIST (implementation_template
),
6253 IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
)));
6257 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6259 tree category
= CLASS_CATEGORY_LIST (implementation_template
);
6261 /* Find the category interface from the class it is associated with. */
6264 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category
))
6266 category
= CLASS_CATEGORY_LIST (category
);
6271 /* Ensure all method listed in the interface contain bodies. */
6272 check_methods (CLASS_CLS_METHODS (category
),
6273 CLASS_CLS_METHODS (objc_implementation_context
), '+');
6274 check_methods (CLASS_NST_METHODS (category
),
6275 CLASS_NST_METHODS (objc_implementation_context
), '-');
6277 if (CLASS_PROTOCOL_LIST (category
))
6278 check_protocols (CLASS_PROTOCOL_LIST (category
),
6280 IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
6284 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6287 const char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (class));
6288 char *string
= (char *) alloca (strlen (class_name
) + 3);
6290 /* extern struct objc_object *_<my_name>; */
6292 sprintf (string
, "_%s", class_name
);
6294 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
6295 decl_specs
= tree_cons (NULL_TREE
, objc_object_reference
, decl_specs
);
6296 define_decl (build1 (INDIRECT_REF
, NULL_TREE
, get_identifier (string
)),
6302 add_protocol (protocol
)
6305 /* Put protocol on list in reverse order. */
6306 TREE_CHAIN (protocol
) = protocol_chain
;
6307 protocol_chain
= protocol
;
6308 return protocol_chain
;
6312 lookup_protocol (ident
)
6317 for (chain
= protocol_chain
; chain
; chain
= TREE_CHAIN (chain
))
6318 if (ident
== PROTOCOL_NAME (chain
))
6324 /* This function forward declares the protocols named by NAMES. If
6325 they are already declared or defined, the function has no effect. */
6328 objc_declare_protocols (names
)
6333 for (list
= names
; list
; list
= TREE_CHAIN (list
))
6335 tree name
= TREE_VALUE (list
);
6337 if (lookup_protocol (name
) == NULL_TREE
)
6339 tree protocol
= make_node (PROTOCOL_INTERFACE_TYPE
);
6341 TYPE_BINFO (protocol
) = make_tree_vec (2);
6342 PROTOCOL_NAME (protocol
) = name
;
6343 PROTOCOL_LIST (protocol
) = NULL_TREE
;
6344 add_protocol (protocol
);
6345 PROTOCOL_DEFINED (protocol
) = 0;
6346 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6352 start_protocol (code
, name
, list
)
6353 enum tree_code code
;
6359 /* This is as good a place as any. Need to invoke
6360 push_tag_toplevel. */
6361 if (!objc_protocol_template
)
6362 objc_protocol_template
= build_protocol_template ();
6364 protocol
= lookup_protocol (name
);
6368 protocol
= make_node (code
);
6369 TYPE_BINFO (protocol
) = make_tree_vec (2);
6371 PROTOCOL_NAME (protocol
) = name
;
6372 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
6373 add_protocol (protocol
);
6374 PROTOCOL_DEFINED (protocol
) = 1;
6375 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6377 check_protocol_recursively (protocol
, list
);
6379 else if (! PROTOCOL_DEFINED (protocol
))
6381 PROTOCOL_DEFINED (protocol
) = 1;
6382 PROTOCOL_LIST (protocol
) = lookup_and_install_protocols (list
);
6384 check_protocol_recursively (protocol
, list
);
6388 warning ("duplicate declaration for protocol `%s'",
6389 IDENTIFIER_POINTER (name
));
6395 finish_protocol (protocol
)
6396 tree protocol ATTRIBUTE_UNUSED
;
6401 /* "Encode" a data type into a string, which grows in util_obstack.
6402 ??? What is the FORMAT? Someone please document this! */
6405 encode_type_qualifiers (declspecs
)
6410 for (spec
= declspecs
; spec
; spec
= TREE_CHAIN (spec
))
6412 if (ridpointers
[(int) RID_CONST
] == TREE_VALUE (spec
))
6413 obstack_1grow (&util_obstack
, 'r');
6414 else if (ridpointers
[(int) RID_IN
] == TREE_VALUE (spec
))
6415 obstack_1grow (&util_obstack
, 'n');
6416 else if (ridpointers
[(int) RID_INOUT
] == TREE_VALUE (spec
))
6417 obstack_1grow (&util_obstack
, 'N');
6418 else if (ridpointers
[(int) RID_OUT
] == TREE_VALUE (spec
))
6419 obstack_1grow (&util_obstack
, 'o');
6420 else if (ridpointers
[(int) RID_BYCOPY
] == TREE_VALUE (spec
))
6421 obstack_1grow (&util_obstack
, 'O');
6422 else if (ridpointers
[(int) RID_BYREF
] == TREE_VALUE (spec
))
6423 obstack_1grow (&util_obstack
, 'R');
6424 else if (ridpointers
[(int) RID_ONEWAY
] == TREE_VALUE (spec
))
6425 obstack_1grow (&util_obstack
, 'V');
6429 /* Encode a pointer type. */
6432 encode_pointer (type
, curtype
, format
)
6437 tree pointer_to
= TREE_TYPE (type
);
6439 if (TREE_CODE (pointer_to
) == RECORD_TYPE
)
6441 if (TYPE_NAME (pointer_to
)
6442 && TREE_CODE (TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
)
6444 const char *name
= IDENTIFIER_POINTER (TYPE_NAME (pointer_to
));
6446 if (strcmp (name
, TAG_OBJECT
) == 0) /* '@' */
6448 obstack_1grow (&util_obstack
, '@');
6451 else if (TREE_STATIC_TEMPLATE (pointer_to
))
6453 if (generating_instance_variables
)
6455 obstack_1grow (&util_obstack
, '@');
6456 obstack_1grow (&util_obstack
, '"');
6457 obstack_grow (&util_obstack
, name
, strlen (name
));
6458 obstack_1grow (&util_obstack
, '"');
6463 obstack_1grow (&util_obstack
, '@');
6467 else if (strcmp (name
, TAG_CLASS
) == 0) /* '#' */
6469 obstack_1grow (&util_obstack
, '#');
6472 else if (strcmp (name
, TAG_SELECTOR
) == 0) /* ':' */
6474 obstack_1grow (&util_obstack
, ':');
6479 else if (TREE_CODE (pointer_to
) == INTEGER_TYPE
6480 && TYPE_MODE (pointer_to
) == QImode
)
6482 obstack_1grow (&util_obstack
, '*');
6486 /* We have a type that does not get special treatment. */
6488 /* NeXT extension */
6489 obstack_1grow (&util_obstack
, '^');
6490 encode_type (pointer_to
, curtype
, format
);
6494 encode_array (type
, curtype
, format
)
6499 tree an_int_cst
= TYPE_SIZE (type
);
6500 tree array_of
= TREE_TYPE (type
);
6503 /* An incomplete array is treated like a pointer. */
6504 if (an_int_cst
== NULL
)
6506 encode_pointer (type
, curtype
, format
);
6510 sprintf (buffer
, "[%ld",
6511 (long) (TREE_INT_CST_LOW (an_int_cst
)
6512 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
6514 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6515 encode_type (array_of
, curtype
, format
);
6516 obstack_1grow (&util_obstack
, ']');
6521 encode_aggregate_within (type
, curtype
, format
, left
, right
)
6528 /* The RECORD_TYPE may in fact be a typedef! For purposes
6529 of encoding, we need the real underlying enchilada. */
6530 if (TYPE_MAIN_VARIANT (type
))
6531 type
= TYPE_MAIN_VARIANT (type
);
6533 if (obstack_object_size (&util_obstack
) > 0
6534 && *(obstack_next_free (&util_obstack
) - 1) == '^')
6536 tree name
= TYPE_NAME (type
);
6538 /* we have a reference; this is a NeXT extension. */
6540 if (obstack_object_size (&util_obstack
) - curtype
== 1
6541 && format
== OBJC_ENCODE_INLINE_DEFS
)
6543 /* Output format of struct for first level only. */
6544 tree fields
= TYPE_FIELDS (type
);
6546 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6548 obstack_1grow (&util_obstack
, left
);
6549 obstack_grow (&util_obstack
,
6550 IDENTIFIER_POINTER (name
),
6551 strlen (IDENTIFIER_POINTER (name
)));
6552 obstack_1grow (&util_obstack
, '=');
6556 obstack_1grow (&util_obstack
, left
);
6557 obstack_grow (&util_obstack
, "?=", 2);
6560 for ( ; fields
; fields
= TREE_CHAIN (fields
))
6561 encode_field_decl (fields
, curtype
, format
);
6563 obstack_1grow (&util_obstack
, right
);
6566 else if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6568 obstack_1grow (&util_obstack
, left
);
6569 obstack_grow (&util_obstack
,
6570 IDENTIFIER_POINTER (name
),
6571 strlen (IDENTIFIER_POINTER (name
)));
6572 obstack_1grow (&util_obstack
, right
);
6577 /* We have an untagged structure or a typedef. */
6578 obstack_1grow (&util_obstack
, left
);
6579 obstack_1grow (&util_obstack
, '?');
6580 obstack_1grow (&util_obstack
, right
);
6586 tree name
= TYPE_NAME (type
);
6587 tree fields
= TYPE_FIELDS (type
);
6589 if (format
== OBJC_ENCODE_INLINE_DEFS
6590 || generating_instance_variables
)
6592 obstack_1grow (&util_obstack
, left
);
6593 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6594 obstack_grow (&util_obstack
,
6595 IDENTIFIER_POINTER (name
),
6596 strlen (IDENTIFIER_POINTER (name
)));
6598 obstack_1grow (&util_obstack
, '?');
6600 obstack_1grow (&util_obstack
, '=');
6602 for (; fields
; fields
= TREE_CHAIN (fields
))
6604 if (generating_instance_variables
)
6606 tree fname
= DECL_NAME (fields
);
6608 obstack_1grow (&util_obstack
, '"');
6609 if (fname
&& TREE_CODE (fname
) == IDENTIFIER_NODE
)
6611 obstack_grow (&util_obstack
,
6612 IDENTIFIER_POINTER (fname
),
6613 strlen (IDENTIFIER_POINTER (fname
)));
6616 obstack_1grow (&util_obstack
, '"');
6619 encode_field_decl (fields
, curtype
, format
);
6622 obstack_1grow (&util_obstack
, right
);
6627 obstack_1grow (&util_obstack
, left
);
6628 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6629 obstack_grow (&util_obstack
,
6630 IDENTIFIER_POINTER (name
),
6631 strlen (IDENTIFIER_POINTER (name
)));
6633 /* We have an untagged structure or a typedef. */
6634 obstack_1grow (&util_obstack
, '?');
6636 obstack_1grow (&util_obstack
, right
);
6642 encode_aggregate (type
, curtype
, format
)
6647 enum tree_code code
= TREE_CODE (type
);
6653 encode_aggregate_within(type
, curtype
, format
, '{', '}');
6658 encode_aggregate_within(type
, curtype
, format
, '(', ')');
6663 obstack_1grow (&util_obstack
, 'i');
6671 /* Support bitfields. The current version of Objective-C does not support
6672 them. The string will consist of one or more "b:n"'s where n is an
6673 integer describing the width of the bitfield. Currently, classes in
6674 the kit implement a method "-(char *)describeBitfieldStruct:" that
6675 simulates this. If they do not implement this method, the archiver
6676 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6677 according to the GNU compiler. After looking at the "kit", it appears
6678 that all classes currently rely on this default behavior, rather than
6679 hand generating this string (which is tedious). */
6682 encode_bitfield (width
)
6686 sprintf (buffer
, "b%d", width
);
6687 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6690 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6693 encode_type (type
, curtype
, format
)
6698 enum tree_code code
= TREE_CODE (type
);
6700 if (code
== INTEGER_TYPE
)
6702 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6704 /* Unsigned integer types. */
6706 if (TYPE_MODE (type
) == QImode
)
6707 obstack_1grow (&util_obstack
, 'C');
6708 else if (TYPE_MODE (type
) == HImode
)
6709 obstack_1grow (&util_obstack
, 'S');
6710 else if (TYPE_MODE (type
) == SImode
)
6712 if (type
== long_unsigned_type_node
)
6713 obstack_1grow (&util_obstack
, 'L');
6715 obstack_1grow (&util_obstack
, 'I');
6717 else if (TYPE_MODE (type
) == DImode
)
6718 obstack_1grow (&util_obstack
, 'Q');
6722 /* Signed integer types. */
6724 if (TYPE_MODE (type
) == QImode
)
6725 obstack_1grow (&util_obstack
, 'c');
6726 else if (TYPE_MODE (type
) == HImode
)
6727 obstack_1grow (&util_obstack
, 's');
6728 else if (TYPE_MODE (type
) == SImode
)
6730 if (type
== long_integer_type_node
)
6731 obstack_1grow (&util_obstack
, 'l');
6733 obstack_1grow (&util_obstack
, 'i');
6736 else if (TYPE_MODE (type
) == DImode
)
6737 obstack_1grow (&util_obstack
, 'q');
6741 else if (code
== REAL_TYPE
)
6743 /* Floating point types. */
6745 if (TYPE_MODE (type
) == SFmode
)
6746 obstack_1grow (&util_obstack
, 'f');
6747 else if (TYPE_MODE (type
) == DFmode
6748 || TYPE_MODE (type
) == TFmode
)
6749 obstack_1grow (&util_obstack
, 'd');
6752 else if (code
== VOID_TYPE
)
6753 obstack_1grow (&util_obstack
, 'v');
6755 else if (code
== ARRAY_TYPE
)
6756 encode_array (type
, curtype
, format
);
6758 else if (code
== POINTER_TYPE
)
6759 encode_pointer (type
, curtype
, format
);
6761 else if (code
== RECORD_TYPE
|| code
== UNION_TYPE
|| code
== ENUMERAL_TYPE
)
6762 encode_aggregate (type
, curtype
, format
);
6764 else if (code
== FUNCTION_TYPE
) /* '?' */
6765 obstack_1grow (&util_obstack
, '?');
6769 encode_complete_bitfield (int position
, tree type
, int size
)
6771 enum tree_code code
= TREE_CODE (type
);
6773 char charType
= '?';
6775 if (code
== INTEGER_TYPE
)
6777 if (integer_zerop (TYPE_MIN_VALUE (type
)))
6779 /* Unsigned integer types. */
6781 if (TYPE_MODE (type
) == QImode
)
6783 else if (TYPE_MODE (type
) == HImode
)
6785 else if (TYPE_MODE (type
) == SImode
)
6787 if (type
== long_unsigned_type_node
)
6792 else if (TYPE_MODE (type
) == DImode
)
6797 /* Signed integer types. */
6799 if (TYPE_MODE (type
) == QImode
)
6801 else if (TYPE_MODE (type
) == HImode
)
6803 else if (TYPE_MODE (type
) == SImode
)
6805 if (type
== long_integer_type_node
)
6811 else if (TYPE_MODE (type
) == DImode
)
6815 else if (code
== ENUMERAL_TYPE
)
6820 sprintf (buffer
, "b%d%c%d", position
, charType
, size
);
6821 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6825 encode_field_decl (field_decl
, curtype
, format
)
6832 type
= TREE_TYPE (field_decl
);
6834 /* If this field is obviously a bitfield, or is a bitfield that has been
6835 clobbered to look like a ordinary integer mode, go ahead and generate
6836 the bitfield typing information. */
6837 if (flag_next_runtime
)
6839 if (DECL_BIT_FIELD (field_decl
))
6840 encode_bitfield (tree_low_cst (DECL_SIZE (field_decl
), 1));
6842 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6846 if (DECL_BIT_FIELD (field_decl
))
6847 encode_complete_bitfield (int_bit_position (field_decl
),
6848 DECL_BIT_FIELD_TYPE (field_decl
),
6849 tree_low_cst (DECL_SIZE (field_decl
), 1));
6851 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6856 expr_last (complex_expr
)
6862 while ((next
= TREE_OPERAND (complex_expr
, 0)))
6863 complex_expr
= next
;
6865 return complex_expr
;
6868 /* Transform a method definition into a function definition as follows:
6869 - synthesize the first two arguments, "self" and "_cmd". */
6872 start_method_def (method
)
6877 /* Required to implement _msgSuper. */
6878 objc_method_context
= method
;
6879 UOBJC_SUPER_decl
= NULL_TREE
;
6881 /* Must be called BEFORE start_function. */
6884 /* Generate prototype declarations for arguments..."new-style". */
6886 if (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
)
6887 decl_specs
= build_tree_list (NULL_TREE
, uprivate_record
);
6889 /* Really a `struct objc_class *'. However, we allow people to
6890 assign to self, which changes its type midstream. */
6891 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
6893 push_parm_decl (build_tree_list
6894 (build_tree_list (decl_specs
,
6895 build1 (INDIRECT_REF
, NULL_TREE
, self_id
)),
6898 decl_specs
= build_tree_list (NULL_TREE
,
6899 xref_tag (RECORD_TYPE
,
6900 get_identifier (TAG_SELECTOR
)));
6901 push_parm_decl (build_tree_list
6902 (build_tree_list (decl_specs
,
6903 build1 (INDIRECT_REF
, NULL_TREE
, ucmd_id
)),
6906 /* Generate argument declarations if a keyword_decl. */
6907 if (METHOD_SEL_ARGS (method
))
6909 tree arglist
= METHOD_SEL_ARGS (method
);
6912 tree arg_spec
= TREE_PURPOSE (TREE_TYPE (arglist
));
6913 tree arg_decl
= TREE_VALUE (TREE_TYPE (arglist
));
6917 tree last_expr
= expr_last (arg_decl
);
6919 /* Unite the abstract decl with its name. */
6920 TREE_OPERAND (last_expr
, 0) = KEYWORD_ARG_NAME (arglist
);
6921 push_parm_decl (build_tree_list
6922 (build_tree_list (arg_spec
, arg_decl
),
6925 /* Unhook: restore the abstract declarator. */
6926 TREE_OPERAND (last_expr
, 0) = NULL_TREE
;
6930 push_parm_decl (build_tree_list
6931 (build_tree_list (arg_spec
,
6932 KEYWORD_ARG_NAME (arglist
)),
6935 arglist
= TREE_CHAIN (arglist
);
6940 if (METHOD_ADD_ARGS (method
) != NULL_TREE
6941 && METHOD_ADD_ARGS (method
) != objc_ellipsis_node
)
6943 /* We have a variable length selector - in "prototype" format. */
6944 tree akey
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
6947 /* This must be done prior to calling pushdecl. pushdecl is
6948 going to change our chain on us. */
6949 tree nextkey
= TREE_CHAIN (akey
);
6957 warn_with_method (message
, mtype
, method
)
6958 const char *message
;
6962 if (count_error (1) == 0)
6965 report_error_function (DECL_SOURCE_FILE (method
));
6967 /* Add a readable method name to the warning. */
6968 warning_with_file_and_line (DECL_SOURCE_FILE (method
),
6969 DECL_SOURCE_LINE (method
),
6972 gen_method_decl (method
, errbuf
));
6975 /* Return 1 if METHOD is consistent with PROTO. */
6978 comp_method_with_proto (method
, proto
)
6981 /* Create a function template node at most once. */
6982 if (!function1_template
)
6983 function1_template
= make_node (FUNCTION_TYPE
);
6985 /* Install argument types - normally set by build_function_type. */
6986 TYPE_ARG_TYPES (function1_template
) = get_arg_type_list (proto
, METHOD_DEF
, 0);
6988 /* install return type */
6989 TREE_TYPE (function1_template
) = groktypename (TREE_TYPE (proto
));
6991 return comptypes (TREE_TYPE (METHOD_DEFINITION (method
)), function1_template
);
6994 /* Return 1 if PROTO1 is consistent with PROTO2. */
6997 comp_proto_with_proto (proto0
, proto1
)
6998 tree proto0
, proto1
;
7000 /* Create a couple of function_template nodes at most once. */
7001 if (!function1_template
)
7002 function1_template
= make_node (FUNCTION_TYPE
);
7003 if (!function2_template
)
7004 function2_template
= make_node (FUNCTION_TYPE
);
7006 /* Install argument types; normally set by build_function_type. */
7007 TYPE_ARG_TYPES (function1_template
) = get_arg_type_list (proto0
, METHOD_REF
, 0);
7008 TYPE_ARG_TYPES (function2_template
) = get_arg_type_list (proto1
, METHOD_REF
, 0);
7010 /* Install return type. */
7011 TREE_TYPE (function1_template
) = groktypename (TREE_TYPE (proto0
));
7012 TREE_TYPE (function2_template
) = groktypename (TREE_TYPE (proto1
));
7014 return comptypes (function1_template
, function2_template
);
7017 /* - Generate an identifier for the function. the format is "_n_cls",
7018 where 1 <= n <= nMethods, and cls is the name the implementation we
7020 - Install the return type from the method declaration.
7021 - If we have a prototype, check for type consistency. */
7024 really_start_method (method
, parmlist
)
7025 tree method
, parmlist
;
7027 tree sc_spec
, ret_spec
, ret_decl
, decl_specs
;
7028 tree method_decl
, method_id
;
7029 const char *sel_name
, *class_name
, *cat_name
;
7032 /* Synth the storage class & assemble the return type. */
7033 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
7034 ret_spec
= TREE_PURPOSE (TREE_TYPE (method
));
7035 decl_specs
= chainon (sc_spec
, ret_spec
);
7037 sel_name
= IDENTIFIER_POINTER (METHOD_SEL_NAME (method
));
7038 class_name
= IDENTIFIER_POINTER (CLASS_NAME (objc_implementation_context
));
7039 cat_name
= ((TREE_CODE (objc_implementation_context
)
7040 == CLASS_IMPLEMENTATION_TYPE
)
7042 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (objc_implementation_context
)));
7045 /* Make sure this is big enough for any plausible method label. */
7046 buf
= (char *) alloca (50 + strlen (sel_name
) + strlen (class_name
)
7047 + (cat_name
? strlen (cat_name
) : 0));
7049 OBJC_GEN_METHOD_LABEL (buf
, TREE_CODE (method
) == INSTANCE_METHOD_DECL
,
7050 class_name
, cat_name
, sel_name
, method_slot
);
7052 method_id
= get_identifier (buf
);
7054 method_decl
= build_nt (CALL_EXPR
, method_id
, parmlist
, NULL_TREE
);
7056 /* Check the declarator portion of the return type for the method. */
7057 if ((ret_decl
= TREE_VALUE (TREE_TYPE (method
))))
7059 /* Unite the complex decl (specified in the abstract decl) with the
7060 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7061 tree save_expr
= expr_last (ret_decl
);
7063 TREE_OPERAND (save_expr
, 0) = method_decl
;
7064 method_decl
= ret_decl
;
7066 /* Fool the parser into thinking it is starting a function. */
7067 start_function (decl_specs
, method_decl
, NULL_TREE
);
7069 /* Unhook: this has the effect of restoring the abstract declarator. */
7070 TREE_OPERAND (save_expr
, 0) = NULL_TREE
;
7075 TREE_VALUE (TREE_TYPE (method
)) = method_decl
;
7077 /* Fool the parser into thinking it is starting a function. */
7078 start_function (decl_specs
, method_decl
, NULL_TREE
);
7080 /* Unhook: this has the effect of restoring the abstract declarator. */
7081 TREE_VALUE (TREE_TYPE (method
)) = NULL_TREE
;
7084 METHOD_DEFINITION (method
) = current_function_decl
;
7086 /* Check consistency...start_function, pushdecl, duplicate_decls. */
7088 if (implementation_template
!= objc_implementation_context
)
7092 if (TREE_CODE (method
) == INSTANCE_METHOD_DECL
)
7093 proto
= lookup_instance_method_static (implementation_template
,
7094 METHOD_SEL_NAME (method
));
7096 proto
= lookup_class_method_static (implementation_template
,
7097 METHOD_SEL_NAME (method
));
7099 if (proto
&& ! comp_method_with_proto (method
, proto
))
7101 char type
= (TREE_CODE (method
) == INSTANCE_METHOD_DECL
? '-' : '+');
7103 warn_with_method ("conflicting types for", type
, method
);
7104 warn_with_method ("previous declaration of", type
, proto
);
7109 /* The following routine is always called...this "architecture" is to
7110 accommodate "old-style" variable length selectors.
7112 - a:a b:b // prototype ; id c; id d; // old-style. */
7115 continue_method_def ()
7119 if (METHOD_ADD_ARGS (objc_method_context
) == objc_ellipsis_node
)
7120 /* We have a `, ...' immediately following the selector. */
7121 parmlist
= get_parm_info (0);
7123 parmlist
= get_parm_info (1); /* place a `void_at_end' */
7125 /* Set self_decl from the first argument...this global is used by
7126 build_ivar_reference calling build_indirect_ref. */
7127 self_decl
= TREE_PURPOSE (parmlist
);
7130 really_start_method (objc_method_context
, parmlist
);
7131 store_parm_decls ();
7134 /* Called by the parser, from the `pushlevel' production. */
7139 if (!UOBJC_SUPER_decl
)
7141 UOBJC_SUPER_decl
= start_decl (get_identifier (UTAG_SUPER
),
7142 build_tree_list (NULL_TREE
,
7143 objc_super_template
),
7146 finish_decl (UOBJC_SUPER_decl
, NULL_TREE
, NULL_TREE
);
7148 /* This prevents `unused variable' warnings when compiling with -Wall. */
7149 TREE_USED (UOBJC_SUPER_decl
) = 1;
7150 DECL_ARTIFICIAL (UOBJC_SUPER_decl
) = 1;
7154 /* _n_Method (id self, SEL sel, ...)
7156 struct objc_super _S;
7157 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7161 get_super_receiver ()
7163 if (objc_method_context
)
7165 tree super_expr
, super_expr_list
;
7167 /* Set receiver to self. */
7168 super_expr
= build_component_ref (UOBJC_SUPER_decl
, self_id
);
7169 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, self_decl
);
7170 super_expr_list
= build_tree_list (NULL_TREE
, super_expr
);
7172 /* Set class to begin searching. */
7173 super_expr
= build_component_ref (UOBJC_SUPER_decl
,
7174 get_identifier ("class"));
7176 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
7178 /* [_cls, __cls]Super are "pre-built" in
7179 synth_forward_declarations. */
7181 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
,
7182 ((TREE_CODE (objc_method_context
)
7183 == INSTANCE_METHOD_DECL
)
7185 : uucls_super_ref
));
7189 /* We have a category. */
7191 tree super_name
= CLASS_SUPER_NAME (implementation_template
);
7194 /* Barf if super used in a category of Object. */
7197 error ("no super class declared in interface for `%s'",
7198 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
7199 return error_mark_node
;
7202 if (flag_next_runtime
)
7204 super_class
= get_class_reference (super_name
);
7205 if (TREE_CODE (objc_method_context
) == CLASS_METHOD_DECL
)
7207 = build_component_ref (build_indirect_ref (super_class
, "->"),
7208 get_identifier ("isa"));
7212 add_class_reference (super_name
);
7213 super_class
= (TREE_CODE (objc_method_context
) == INSTANCE_METHOD_DECL
7214 ? objc_get_class_decl
: objc_get_meta_class_decl
);
7215 assemble_external (super_class
);
7217 = build_function_call
7221 my_build_string (IDENTIFIER_LENGTH (super_name
) + 1,
7222 IDENTIFIER_POINTER (super_name
))));
7225 TREE_TYPE (super_class
) = TREE_TYPE (ucls_super_ref
);
7226 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, super_class
);
7229 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7231 super_expr
= build_unary_op (ADDR_EXPR
, UOBJC_SUPER_decl
, 0);
7232 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7234 return build_compound_expr (super_expr_list
);
7238 error ("[super ...] must appear in a method context");
7239 return error_mark_node
;
7244 encode_method_def (func_decl
)
7249 HOST_WIDE_INT max_parm_end
= 0;
7254 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
7255 obstack_object_size (&util_obstack
),
7256 OBJC_ENCODE_INLINE_DEFS
);
7259 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7260 parms
= TREE_CHAIN (parms
))
7262 HOST_WIDE_INT parm_end
= (forwarding_offset (parms
)
7263 + int_size_in_bytes (TREE_TYPE (parms
)));
7265 if (! offset_is_register
&& parm_end
> max_parm_end
)
7266 max_parm_end
= parm_end
;
7269 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
7271 sprintf (buffer
, "%d", stack_size
);
7272 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7274 /* Argument types. */
7275 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7276 parms
= TREE_CHAIN (parms
))
7279 encode_type (TREE_TYPE (parms
),
7280 obstack_object_size (&util_obstack
),
7281 OBJC_ENCODE_INLINE_DEFS
);
7283 /* Compute offset. */
7284 sprintf (buffer
, "%d", forwarding_offset (parms
));
7286 /* Indicate register. */
7287 if (offset_is_register
)
7288 obstack_1grow (&util_obstack
, '+');
7290 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7293 /* Null terminate string. */
7294 obstack_1grow (&util_obstack
, 0);
7295 result
= get_identifier (obstack_finish (&util_obstack
));
7296 obstack_free (&util_obstack
, util_firstobj
);
7301 objc_expand_function_end ()
7303 METHOD_ENCODING (objc_method_context
) = encode_method_def (current_function_decl
);
7307 finish_method_def ()
7309 lang_expand_function_end
= objc_expand_function_end
;
7310 finish_function (0);
7311 lang_expand_function_end
= NULL
;
7313 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7314 since the optimizer may find "may be used before set" errors. */
7315 objc_method_context
= NULL_TREE
;
7320 lang_report_error_function (decl
)
7323 if (objc_method_context
)
7325 fprintf (stderr
, "In method `%s'\n",
7326 IDENTIFIER_POINTER (METHOD_SEL_NAME (objc_method_context
)));
7336 is_complex_decl (type
)
7339 return (TREE_CODE (type
) == ARRAY_TYPE
7340 || TREE_CODE (type
) == FUNCTION_TYPE
7341 || (TREE_CODE (type
) == POINTER_TYPE
&& ! IS_ID (type
)));
7345 /* Code to convert a decl node into text for a declaration in C. */
7347 static char tmpbuf
[256];
7350 adorn_decl (decl
, str
)
7354 enum tree_code code
= TREE_CODE (decl
);
7356 if (code
== ARRAY_REF
)
7358 tree an_int_cst
= TREE_OPERAND (decl
, 1);
7360 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_CST
)
7361 sprintf (str
+ strlen (str
), "[%ld]",
7362 (long) TREE_INT_CST_LOW (an_int_cst
));
7367 else if (code
== ARRAY_TYPE
)
7369 tree an_int_cst
= TYPE_SIZE (decl
);
7370 tree array_of
= TREE_TYPE (decl
);
7372 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_TYPE
)
7373 sprintf (str
+ strlen (str
), "[%ld]",
7374 (long) (TREE_INT_CST_LOW (an_int_cst
)
7375 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
7380 else if (code
== CALL_EXPR
)
7382 tree chain
= TREE_PURPOSE (TREE_OPERAND (decl
, 1));
7387 gen_declaration_1 (chain
, str
);
7388 chain
= TREE_CHAIN (chain
);
7395 else if (code
== FUNCTION_TYPE
)
7397 tree chain
= TYPE_ARG_TYPES (decl
);
7400 while (chain
&& TREE_VALUE (chain
) != void_type_node
)
7402 gen_declaration_1 (TREE_VALUE (chain
), str
);
7403 chain
= TREE_CHAIN (chain
);
7404 if (chain
&& TREE_VALUE (chain
) != void_type_node
)
7410 else if (code
== INDIRECT_REF
)
7412 strcpy (tmpbuf
, "*");
7413 if (TREE_TYPE (decl
) && TREE_CODE (TREE_TYPE (decl
)) == TREE_LIST
)
7417 for (chain
= nreverse (copy_list (TREE_TYPE (decl
)));
7419 chain
= TREE_CHAIN (chain
))
7421 if (TREE_CODE (TREE_VALUE (chain
)) == IDENTIFIER_NODE
)
7423 strcat (tmpbuf
, " ");
7424 strcat (tmpbuf
, IDENTIFIER_POINTER (TREE_VALUE (chain
)));
7428 strcat (tmpbuf
, " ");
7430 strcat (tmpbuf
, str
);
7431 strcpy (str
, tmpbuf
);
7434 else if (code
== POINTER_TYPE
)
7436 strcpy (tmpbuf
, "*");
7437 if (TREE_READONLY (decl
) || TYPE_VOLATILE (decl
))
7439 if (TREE_READONLY (decl
))
7440 strcat (tmpbuf
, " const");
7441 if (TYPE_VOLATILE (decl
))
7442 strcat (tmpbuf
, " volatile");
7444 strcat (tmpbuf
, " ");
7446 strcat (tmpbuf
, str
);
7447 strcpy (str
, tmpbuf
);
7452 gen_declarator (decl
, buf
, name
)
7459 enum tree_code code
= TREE_CODE (decl
);
7469 op
= TREE_OPERAND (decl
, 0);
7471 /* We have a pointer to a function or array...(*)(), (*)[] */
7472 if ((code
== ARRAY_REF
|| code
== CALL_EXPR
)
7473 && op
&& TREE_CODE (op
) == INDIRECT_REF
)
7476 str
= gen_declarator (op
, buf
, name
);
7480 strcpy (tmpbuf
, "(");
7481 strcat (tmpbuf
, str
);
7482 strcat (tmpbuf
, ")");
7483 strcpy (str
, tmpbuf
);
7486 adorn_decl (decl
, str
);
7495 /* This clause is done iteratively rather than recursively. */
7498 op
= (is_complex_decl (TREE_TYPE (decl
))
7499 ? TREE_TYPE (decl
) : NULL_TREE
);
7501 adorn_decl (decl
, str
);
7503 /* We have a pointer to a function or array...(*)(), (*)[] */
7504 if (code
== POINTER_TYPE
7505 && op
&& (TREE_CODE (op
) == FUNCTION_TYPE
7506 || TREE_CODE (op
) == ARRAY_TYPE
))
7508 strcpy (tmpbuf
, "(");
7509 strcat (tmpbuf
, str
);
7510 strcat (tmpbuf
, ")");
7511 strcpy (str
, tmpbuf
);
7514 decl
= (is_complex_decl (TREE_TYPE (decl
))
7515 ? TREE_TYPE (decl
) : NULL_TREE
);
7518 while (decl
&& (code
= TREE_CODE (decl
)))
7523 case IDENTIFIER_NODE
:
7524 /* Will only happen if we are processing a "raw" expr-decl. */
7525 strcpy (buf
, IDENTIFIER_POINTER (decl
));
7536 /* We have an abstract declarator or a _DECL node. */
7544 gen_declspecs (declspecs
, buf
, raw
)
7553 for (chain
= nreverse (copy_list (declspecs
));
7554 chain
; chain
= TREE_CHAIN (chain
))
7556 tree aspec
= TREE_VALUE (chain
);
7558 if (TREE_CODE (aspec
) == IDENTIFIER_NODE
)
7559 strcat (buf
, IDENTIFIER_POINTER (aspec
));
7560 else if (TREE_CODE (aspec
) == RECORD_TYPE
)
7562 if (TYPE_NAME (aspec
))
7564 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7566 if (! TREE_STATIC_TEMPLATE (aspec
))
7567 strcat (buf
, "struct ");
7568 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7573 tree chain
= protocol_list
;
7580 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7581 chain
= TREE_CHAIN (chain
);
7590 strcat (buf
, "untagged struct");
7593 else if (TREE_CODE (aspec
) == UNION_TYPE
)
7595 if (TYPE_NAME (aspec
))
7597 if (! TREE_STATIC_TEMPLATE (aspec
))
7598 strcat (buf
, "union ");
7599 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7602 strcat (buf
, "untagged union");
7605 else if (TREE_CODE (aspec
) == ENUMERAL_TYPE
)
7607 if (TYPE_NAME (aspec
))
7609 if (! TREE_STATIC_TEMPLATE (aspec
))
7610 strcat (buf
, "enum ");
7611 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7614 strcat (buf
, "untagged enum");
7617 else if (TREE_CODE (aspec
) == TYPE_DECL
&& DECL_NAME (aspec
))
7618 strcat (buf
, IDENTIFIER_POINTER (DECL_NAME (aspec
)));
7620 else if (IS_ID (aspec
))
7622 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7627 tree chain
= protocol_list
;
7634 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7635 chain
= TREE_CHAIN (chain
);
7642 if (TREE_CHAIN (chain
))
7648 /* Type qualifiers. */
7649 if (TREE_READONLY (declspecs
))
7650 strcat (buf
, "const ");
7651 if (TYPE_VOLATILE (declspecs
))
7652 strcat (buf
, "volatile ");
7654 switch (TREE_CODE (declspecs
))
7656 /* Type specifiers. */
7659 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7661 /* Signed integer types. */
7663 if (declspecs
== short_integer_type_node
)
7664 strcat (buf
, "short int ");
7665 else if (declspecs
== integer_type_node
)
7666 strcat (buf
, "int ");
7667 else if (declspecs
== long_integer_type_node
)
7668 strcat (buf
, "long int ");
7669 else if (declspecs
== long_long_integer_type_node
)
7670 strcat (buf
, "long long int ");
7671 else if (declspecs
== signed_char_type_node
7672 || declspecs
== char_type_node
)
7673 strcat (buf
, "char ");
7675 /* Unsigned integer types. */
7677 else if (declspecs
== short_unsigned_type_node
)
7678 strcat (buf
, "unsigned short ");
7679 else if (declspecs
== unsigned_type_node
)
7680 strcat (buf
, "unsigned int ");
7681 else if (declspecs
== long_unsigned_type_node
)
7682 strcat (buf
, "unsigned long ");
7683 else if (declspecs
== long_long_unsigned_type_node
)
7684 strcat (buf
, "unsigned long long ");
7685 else if (declspecs
== unsigned_char_type_node
)
7686 strcat (buf
, "unsigned char ");
7690 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7692 if (declspecs
== float_type_node
)
7693 strcat (buf
, "float ");
7694 else if (declspecs
== double_type_node
)
7695 strcat (buf
, "double ");
7696 else if (declspecs
== long_double_type_node
)
7697 strcat (buf
, "long double ");
7701 if (TYPE_NAME (declspecs
)
7702 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7704 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7706 if (! TREE_STATIC_TEMPLATE (declspecs
))
7707 strcat (buf
, "struct ");
7708 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7712 tree chain
= protocol_list
;
7719 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7720 chain
= TREE_CHAIN (chain
);
7729 strcat (buf
, "untagged struct");
7735 if (TYPE_NAME (declspecs
)
7736 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7738 strcat (buf
, "union ");
7739 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7744 strcat (buf
, "untagged union ");
7748 if (TYPE_NAME (declspecs
)
7749 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7751 strcat (buf
, "enum ");
7752 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7757 strcat (buf
, "untagged enum ");
7761 strcat (buf
, "void ");
7766 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7771 tree chain
= protocol_list
;
7778 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7779 chain
= TREE_CHAIN (chain
);
7795 /* Given a tree node, produce a printable description of it in the given
7796 buffer, overwriting the buffer. */
7799 gen_declaration (atype_or_adecl
, buf
)
7800 tree atype_or_adecl
;
7804 gen_declaration_1 (atype_or_adecl
, buf
);
7808 /* Given a tree node, append a printable description to the end of the
7812 gen_declaration_1 (atype_or_adecl
, buf
)
7813 tree atype_or_adecl
;
7818 if (TREE_CODE (atype_or_adecl
) == TREE_LIST
)
7820 tree declspecs
; /* "identifier_node", "record_type" */
7821 tree declarator
; /* "array_ref", "indirect_ref", "call_expr"... */
7823 /* We have a "raw", abstract declarator (typename). */
7824 declarator
= TREE_VALUE (atype_or_adecl
);
7825 declspecs
= TREE_PURPOSE (atype_or_adecl
);
7827 gen_declspecs (declspecs
, buf
, 1);
7831 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7838 tree declspecs
; /* "integer_type", "real_type", "record_type"... */
7839 tree declarator
; /* "array_type", "function_type", "pointer_type". */
7841 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7842 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7843 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7844 atype
= TREE_TYPE (atype_or_adecl
);
7846 /* Assume we have a *_type node. */
7847 atype
= atype_or_adecl
;
7849 if (is_complex_decl (atype
))
7853 /* Get the declaration specifier; it is at the end of the list. */
7854 declarator
= chain
= atype
;
7856 chain
= TREE_TYPE (chain
); /* not TREE_CHAIN (chain); */
7857 while (is_complex_decl (chain
));
7864 declarator
= NULL_TREE
;
7867 gen_declspecs (declspecs
, buf
, 0);
7869 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7870 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7871 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7873 const char *const decl_name
=
7874 (DECL_NAME (atype_or_adecl
)
7875 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl
)) : "");
7880 strcat (buf
, gen_declarator (declarator
, declbuf
, decl_name
));
7883 else if (decl_name
[0])
7886 strcat (buf
, decl_name
);
7889 else if (declarator
)
7892 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7897 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7899 /* Given a method tree, put a printable description into the given
7900 buffer (overwriting) and return a pointer to the buffer. */
7903 gen_method_decl (method
, buf
)
7910 if (RAW_TYPESPEC (method
) != objc_object_reference
)
7913 gen_declaration_1 (TREE_TYPE (method
), buf
);
7917 chain
= METHOD_SEL_ARGS (method
);
7920 /* We have a chain of keyword_decls. */
7923 if (KEYWORD_KEY_NAME (chain
))
7924 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain
)));
7927 if (RAW_TYPESPEC (chain
) != objc_object_reference
)
7930 gen_declaration_1 (TREE_TYPE (chain
), buf
);
7934 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain
)));
7935 if ((chain
= TREE_CHAIN (chain
)))
7940 if (METHOD_ADD_ARGS (method
) == objc_ellipsis_node
)
7941 strcat (buf
, ", ...");
7942 else if (METHOD_ADD_ARGS (method
))
7944 /* We have a tree list node as generate by get_parm_info. */
7945 chain
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
7947 /* Know we have a chain of parm_decls. */
7951 gen_declaration_1 (chain
, buf
);
7952 chain
= TREE_CHAIN (chain
);
7958 /* We have a unary selector. */
7959 strcat (buf
, IDENTIFIER_POINTER (METHOD_SEL_NAME (method
)));
7967 dump_interface (fp
, chain
)
7971 char *buf
= (char *) xmalloc (256);
7972 const char *my_name
= IDENTIFIER_POINTER (CLASS_NAME (chain
));
7973 tree ivar_decls
= CLASS_RAW_IVARS (chain
);
7974 tree nst_methods
= CLASS_NST_METHODS (chain
);
7975 tree cls_methods
= CLASS_CLS_METHODS (chain
);
7977 fprintf (fp
, "\n@interface %s", my_name
);
7979 if (CLASS_SUPER_NAME (chain
))
7981 const char *super_name
= IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain
));
7982 fprintf (fp
, " : %s\n", super_name
);
7989 fprintf (fp
, "{\n");
7992 fprintf (fp
, "\t%s;\n", gen_declaration (ivar_decls
, buf
));
7993 ivar_decls
= TREE_CHAIN (ivar_decls
);
7996 fprintf (fp
, "}\n");
8001 fprintf (fp
, "- %s;\n", gen_method_decl (nst_methods
, buf
));
8002 nst_methods
= TREE_CHAIN (nst_methods
);
8007 fprintf (fp
, "+ %s;\n", gen_method_decl (cls_methods
, buf
));
8008 cls_methods
= TREE_CHAIN (cls_methods
);
8010 fprintf (fp
, "\n@end");
8013 /* Demangle function for Objective-C */
8015 objc_demangle (mangled
)
8016 const char *mangled
;
8018 char *demangled
, *cp
;
8020 if (mangled
[0] == '_' &&
8021 (mangled
[1] == 'i' || mangled
[1] == 'c') &&
8024 cp
= demangled
= xmalloc(strlen(mangled
) + 2);
8025 if (mangled
[1] == 'i')
8026 *cp
++ = '-'; /* for instance method */
8028 *cp
++ = '+'; /* for class method */
8029 *cp
++ = '['; /* opening left brace */
8030 strcpy(cp
, mangled
+3); /* tack on the rest of the mangled name */
8031 while (*cp
&& *cp
== '_')
8032 cp
++; /* skip any initial underbars in class name */
8033 cp
= strchr(cp
, '_'); /* find first non-initial underbar */
8036 free(demangled
); /* not mangled name */
8039 if (cp
[1] == '_') /* easy case: no category name */
8041 *cp
++ = ' '; /* replace two '_' with one ' ' */
8042 strcpy(cp
, mangled
+ (cp
- demangled
) + 2);
8046 *cp
++ = '('; /* less easy case: category name */
8047 cp
= strchr(cp
, '_');
8050 free(demangled
); /* not mangled name */
8054 *cp
++ = ' '; /* overwriting 1st char of method name... */
8055 strcpy(cp
, mangled
+ (cp
- demangled
)); /* get it back */
8057 while (*cp
&& *cp
== '_')
8058 cp
++; /* skip any initial underbars in method name */
8061 *cp
= ':'; /* replace remaining '_' with ':' */
8062 *cp
++ = ']'; /* closing right brace */
8063 *cp
++ = 0; /* string terminator */
8067 return mangled
; /* not an objc mangled name */
8071 objc_printable_name (decl
, kind
)
8073 int kind ATTRIBUTE_UNUSED
;
8075 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl
)));
8078 /* Adds the tree codes specific to the ObjC/ObjC++ front end to the
8079 list of all tree codes. */
8082 add_objc_tree_codes ()
8084 int add
= (int) LAST_OBJC_TREE_CODE
- (int) LAST_BASE_TREE_CODE
;
8086 memcpy (tree_code_type
+ (int) LAST_BASE_TREE_CODE
,
8087 objc_tree_code_type
, add
);
8088 memcpy (tree_code_length
+ (int) LAST_BASE_TREE_CODE
,
8089 objc_tree_code_length
, add
* sizeof (int));
8090 memcpy (tree_code_name
+ (int) LAST_BASE_TREE_CODE
,
8091 objc_tree_code_name
, add
* sizeof (char *));
8097 gcc_obstack_init (&util_obstack
);
8098 util_firstobj
= (char *) obstack_finish (&util_obstack
);
8100 errbuf
= (char *) xmalloc (BUFSIZE
);
8102 synth_module_prologue ();
8108 struct imp_entry
*impent
;
8110 /* The internally generated initializers appear to have missing braces.
8111 Don't warn about this. */
8112 int save_warn_missing_braces
= warn_missing_braces
;
8113 warn_missing_braces
= 0;
8115 /* A missing @end may not be detected by the parser. */
8116 if (objc_implementation_context
)
8118 warning ("`@end' missing in implementation context");
8119 finish_class (objc_implementation_context
);
8120 objc_ivar_chain
= NULL_TREE
;
8121 objc_implementation_context
= NULL_TREE
;
8124 generate_forward_declaration_to_string_table ();
8126 #ifdef OBJC_PROLOGUE
8130 /* Process the static instances here because initialization of objc_symtab
8132 if (objc_static_instances
)
8133 generate_static_references ();
8135 if (imp_list
|| class_names_chain
8136 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8137 generate_objc_symtab_decl ();
8139 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8141 objc_implementation_context
= impent
->imp_context
;
8142 implementation_template
= impent
->imp_template
;
8144 UOBJC_CLASS_decl
= impent
->class_decl
;
8145 UOBJC_METACLASS_decl
= impent
->meta_decl
;
8147 if (TREE_CODE (objc_implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
8149 /* all of the following reference the string pool... */
8150 generate_ivar_lists ();
8151 generate_dispatch_tables ();
8152 generate_shared_structures ();
8156 generate_dispatch_tables ();
8157 generate_category (objc_implementation_context
);
8161 /* If we are using an array of selectors, we must always
8162 finish up the array decl even if no selectors were used. */
8163 if (! flag_next_runtime
|| sel_ref_chain
)
8164 build_selector_translation_table ();
8167 generate_protocols ();
8169 if (objc_implementation_context
|| class_names_chain
|| objc_static_instances
8170 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8172 /* Arrange for ObjC data structures to be initialized at run time. */
8173 rtx init_sym
= build_module_descriptor ();
8174 if (init_sym
&& targetm
.have_ctors_dtors
)
8175 (* targetm
.asm_out
.constructor
) (init_sym
, DEFAULT_INIT_PRIORITY
);
8178 /* Dump the class references. This forces the appropriate classes
8179 to be linked into the executable image, preserving unix archive
8180 semantics. This can be removed when we move to a more dynamically
8181 linked environment. */
8183 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
8185 handle_class_ref (chain
);
8186 if (TREE_PURPOSE (chain
))
8187 generate_classref_translation_entry (chain
);
8190 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8191 handle_impent (impent
);
8193 /* Dump the string table last. */
8195 generate_strings ();
8197 if (flag_gen_declaration
)
8199 add_class (objc_implementation_context
);
8200 dump_interface (gen_declaration_file
, objc_implementation_context
);
8208 /* Run through the selector hash tables and print a warning for any
8209 selector which has multiple methods. */
8211 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8212 for (hsh
= cls_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8215 tree meth
= hsh
->key
;
8216 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8220 warning ("potential selector conflict for method `%s'",
8221 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8222 warn_with_method ("found", type
, meth
);
8223 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8224 warn_with_method ("found", type
, loop
->value
);
8227 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8228 for (hsh
= nst_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8231 tree meth
= hsh
->key
;
8232 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8236 warning ("potential selector conflict for method `%s'",
8237 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8238 warn_with_method ("found", type
, meth
);
8239 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8240 warn_with_method ("found", type
, loop
->value
);
8244 warn_missing_braces
= save_warn_missing_braces
;
8247 /* Subroutines of finish_objc. */
8250 generate_classref_translation_entry (chain
)
8253 tree expr
, name
, decl_specs
, decl
, sc_spec
;
8256 type
= TREE_TYPE (TREE_PURPOSE (chain
));
8258 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
8259 expr
= build_c_cast (type
, expr
); /* cast! */
8261 name
= DECL_NAME (TREE_PURPOSE (chain
));
8263 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
8265 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8266 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
8268 /* The decl that is returned from start_decl is the one that we
8269 forward declared in build_class_reference. */
8270 decl
= start_decl (name
, decl_specs
, 1, NULL_TREE
);
8271 DECL_CONTEXT (decl
) = NULL_TREE
;
8272 finish_decl (decl
, expr
, NULL_TREE
);
8277 handle_class_ref (chain
)
8280 const char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
8281 char *string
= (char *) alloca (strlen (name
) + 30);
8285 sprintf (string
, "%sobjc_class_name_%s",
8286 (flag_next_runtime
? "." : "__"), name
);
8288 #ifdef ASM_DECLARE_UNRESOLVED_REFERENCE
8289 if (flag_next_runtime
)
8291 ASM_DECLARE_UNRESOLVED_REFERENCE (asm_out_file
, string
);
8296 /* Make a decl for this name, so we can use its address in a tree. */
8297 decl
= build_decl (VAR_DECL
, get_identifier (string
), char_type_node
);
8298 DECL_EXTERNAL (decl
) = 1;
8299 TREE_PUBLIC (decl
) = 1;
8302 rest_of_decl_compilation (decl
, 0, 0, 0);
8304 /* Make a decl for the address. */
8305 sprintf (string
, "%sobjc_class_ref_%s",
8306 (flag_next_runtime
? "." : "__"), name
);
8307 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
8308 decl
= build_decl (VAR_DECL
, get_identifier (string
), string_type_node
);
8309 DECL_INITIAL (decl
) = exp
;
8310 TREE_STATIC (decl
) = 1;
8313 rest_of_decl_compilation (decl
, 0, 0, 0);
8317 handle_impent (impent
)
8318 struct imp_entry
*impent
;
8322 objc_implementation_context
= impent
->imp_context
;
8323 implementation_template
= impent
->imp_template
;
8325 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
8327 const char *const class_name
=
8328 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8330 string
= (char *) alloca (strlen (class_name
) + 30);
8332 sprintf (string
, "*%sobjc_class_name_%s",
8333 (flag_next_runtime
? "." : "__"), class_name
);
8335 else if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
8337 const char *const class_name
=
8338 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8339 const char *const class_super_name
=
8340 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
8342 string
= (char *) alloca (strlen (class_name
)
8343 + strlen (class_super_name
) + 30);
8345 /* Do the same for categories. Even though no references to
8346 these symbols are generated automatically by the compiler, it
8347 gives you a handle to pull them into an archive by hand. */
8348 sprintf (string
, "*%sobjc_category_name_%s_%s",
8349 (flag_next_runtime
? "." : "__"), class_name
, class_super_name
);
8354 #ifdef ASM_DECLARE_CLASS_REFERENCE
8355 if (flag_next_runtime
)
8357 ASM_DECLARE_CLASS_REFERENCE (asm_out_file
, string
);
8365 init
= build_int_2 (0, 0);
8366 TREE_TYPE (init
) = type_for_size (BITS_PER_WORD
, 1);
8367 decl
= build_decl (VAR_DECL
, get_identifier (string
), TREE_TYPE (init
));
8368 TREE_PUBLIC (decl
) = 1;
8369 TREE_READONLY (decl
) = 1;
8370 TREE_USED (decl
) = 1;
8371 TREE_CONSTANT (decl
) = 1;
8372 DECL_CONTEXT (decl
) = 0;
8373 DECL_ARTIFICIAL (decl
) = 1;
8374 DECL_INITIAL (decl
) = init
;
8375 assemble_variable (decl
, 1, 0, 0);
8380 ggc_mark_imp_list (arg
)
8383 struct imp_entry
*impent
;
8385 for (impent
= *(struct imp_entry
**)arg
; impent
; impent
= impent
->next
)
8387 ggc_mark_tree (impent
->imp_context
);
8388 ggc_mark_tree (impent
->imp_template
);
8389 ggc_mark_tree (impent
->class_decl
);
8390 ggc_mark_tree (impent
->meta_decl
);
8395 ggc_mark_hash_table (arg
)
8398 hash
*hash_table
= *(hash
**)arg
;
8403 if (hash_table
== NULL
)
8405 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
8406 for (hst
= hash_table
[i
]; hst
; hst
= hst
->next
)
8408 ggc_mark_tree (hst
->key
);
8409 for (list
= hst
->list
; list
; list
= list
->next
)
8410 ggc_mark_tree (list
->value
);
8414 /* Add GC roots for variables local to this file. */
8416 objc_act_parse_init ()
8418 ggc_add_tree_root (objc_global_trees
, OCTI_MAX
);
8419 ggc_add_root (&imp_list
, 1, sizeof imp_list
, ggc_mark_imp_list
);
8420 ggc_add_root (&nst_method_hash_list
, 1, sizeof nst_method_hash_list
, ggc_mark_hash_table
);
8421 ggc_add_root (&cls_method_hash_list
, 1, sizeof cls_method_hash_list
, ggc_mark_hash_table
);
8424 /* Look up ID as an instance variable. */
8426 lookup_objc_ivar (id
)
8431 if (objc_receiver_context
&& !strcmp (IDENTIFIER_POINTER (id
), "super"))
8432 /* we have a message to super */
8433 return get_super_receiver ();
8434 else if (objc_method_context
&& (decl
= is_ivar (objc_ivar_chain
, id
)))
8436 if (is_private (decl
))
8437 return error_mark_node
;
8439 return build_ivar_reference (id
);