1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 93-95, 97, 1998 Free Software Foundation, Inc.
3 Contributed by Steve Naroff.
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* Purpose: This module implements the Objective-C 4.0 language.
24 compatibility issues (with the Stepstone translator):
26 - does not recognize the following 3.3 constructs.
27 @requires, @classes, @messages, = (...)
28 - methods with variable arguments must conform to ANSI standard.
29 - tagged structure definitions that appear in BOTH the interface
30 and implementation are not allowed.
31 - public/private: all instance variables are public within the
32 context of the implementation...I consider this to be a bug in
34 - statically allocated objects are not supported. the user will
35 receive an error if this service is requested.
37 code generation `options':
39 - OBJC_INT_SELECTORS */
56 extern cpp_reader parse_in
;
57 extern cpp_options parse_options
;
58 static int cpp_initialized
;
61 /* This is the default way of generating a method name. */
62 /* I am not sure it is really correct.
63 Perhaps there's a danger that it will make name conflicts
64 if method names contain underscores. -- rms. */
65 #ifndef OBJC_GEN_METHOD_LABEL
66 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
69 sprintf ((BUF), "_%s_%s_%s_%s", \
70 ((IS_INST) ? "i" : "c"), \
72 ((CAT_NAME)? (CAT_NAME) : ""), \
74 for (temp = (BUF); *temp; temp++) \
75 if (*temp == ':') *temp = '_'; \
79 /* These need specifying. */
80 #ifndef OBJC_FORWARDING_STACK_OFFSET
81 #define OBJC_FORWARDING_STACK_OFFSET 0
84 #ifndef OBJC_FORWARDING_MIN_OFFSET
85 #define OBJC_FORWARDING_MIN_OFFSET 0
88 /* Define the special tree codes that we use. */
90 /* Table indexed by tree code giving a string containing a character
91 classifying the tree code. Possibilities are
92 t, d, s, c, r, <, 1 and 2. See objc-tree.def for details. */
94 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
96 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 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 char *objc_tree_code_name
[] = {
120 #include "objc-tree.def"
124 /* Set up for use of obstacks. */
128 #define obstack_chunk_alloc xmalloc
129 #define obstack_chunk_free free
131 /* This obstack is used to accumulate the encoding of a data type. */
132 static struct obstack util_obstack
;
133 /* This points to the beginning of obstack contents,
134 so we can free the whole contents. */
137 /* List of classes with list of their static instances. */
138 static tree objc_static_instances
= NULL_TREE
;
140 /* The declaration of the array administrating the static instances. */
141 static tree static_instances_decl
= NULL_TREE
;
143 /* for encode_method_def */
147 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
148 #define PROTOCOL_VERSION 2
150 #define OBJC_ENCODE_INLINE_DEFS 0
151 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
153 /*** Private Interface (procedures) ***/
155 /* Used by compile_file. */
157 static void init_objc
PROTO((void));
158 static void finish_objc
PROTO((void));
160 /* Code generation. */
162 static void synth_module_prologue
PROTO((void));
163 static tree build_constructor
PROTO((tree
, tree
));
164 static char *build_module_descriptor
PROTO((void));
165 static tree init_module_descriptor
PROTO((tree
));
166 static tree build_objc_method_call
PROTO((int, tree
, tree
,
168 static void generate_strings
PROTO((void));
169 static tree get_proto_encoding
PROTO((tree
));
170 static void build_selector_translation_table
PROTO((void));
171 static tree build_ivar_chain
PROTO((tree
, int));
173 static tree objc_add_static_instance
PROTO((tree
, tree
));
175 static tree build_ivar_template
PROTO((void));
176 static tree build_method_template
PROTO((void));
177 static tree build_private_template
PROTO((tree
));
178 static void build_class_template
PROTO((void));
179 static void build_selector_template
PROTO((void));
180 static void build_category_template
PROTO((void));
181 static tree build_super_template
PROTO((void));
182 static tree build_category_initializer
PROTO((tree
, tree
, tree
,
184 static tree build_protocol_initializer
PROTO((tree
, tree
, tree
,
187 static void synth_forward_declarations
PROTO((void));
188 static void generate_ivar_lists
PROTO((void));
189 static void generate_dispatch_tables
PROTO((void));
190 static void generate_shared_structures
PROTO((void));
191 static tree generate_protocol_list
PROTO((tree
));
192 static void generate_forward_declaration_to_string_table
PROTO((void));
193 static void build_protocol_reference
PROTO((tree
));
195 static tree init_selector
PROTO((int));
196 static tree build_keyword_selector
PROTO((tree
));
197 static tree synth_id_with_class_suffix
PROTO((char *, tree
));
199 static void generate_static_references
PROTO((void));
200 static int check_methods_accessible
PROTO((tree
, tree
,
202 static void encode_aggregate_within
PROTO((tree
, int, int,
205 /* We handle printing method names ourselves for ObjC */
206 extern char *(*decl_printable_name
) ();
208 /* Misc. bookkeeping */
210 typedef struct hashed_entry
*hash
;
211 typedef struct hashed_attribute
*attr
;
213 struct hashed_attribute
225 static void hash_init
PROTO((void));
226 static void hash_enter
PROTO((hash
*, tree
));
227 static hash hash_lookup
PROTO((hash
*, tree
));
228 static void hash_add_attr
PROTO((hash
, tree
));
229 static tree lookup_method
PROTO((tree
, tree
));
230 static tree lookup_instance_method_static
PROTO((tree
, tree
));
231 static tree lookup_class_method_static
PROTO((tree
, tree
));
232 static tree add_class
PROTO((tree
));
233 static void add_category
PROTO((tree
, tree
));
237 class_names
, /* class, category, protocol, module names */
238 meth_var_names
, /* method and variable names */
239 meth_var_types
/* method and variable type descriptors */
242 static tree add_objc_string
PROTO((tree
,
243 enum string_section
));
244 static tree get_objc_string_decl
PROTO((tree
,
245 enum string_section
));
246 static tree build_objc_string_decl
PROTO((tree
,
247 enum string_section
));
248 static tree build_selector_reference_decl
PROTO((tree
));
250 /* Protocol additions. */
252 static tree add_protocol
PROTO((tree
));
253 static tree lookup_protocol
PROTO((tree
));
254 static tree lookup_and_install_protocols
PROTO((tree
));
258 static void encode_type_qualifiers
PROTO((tree
));
259 static void encode_pointer
PROTO((tree
, int, int));
260 static void encode_array
PROTO((tree
, int, int));
261 static void encode_aggregate
PROTO((tree
, int, int));
262 static void encode_bitfield
PROTO((int, int));
263 static void encode_type
PROTO((tree
, int, int));
264 static void encode_field_decl
PROTO((tree
, int, int));
266 static void really_start_method
PROTO((tree
, tree
));
267 static int comp_method_with_proto
PROTO((tree
, tree
));
268 static int comp_proto_with_proto
PROTO((tree
, tree
));
269 static tree get_arg_type_list
PROTO((tree
, int, int));
270 static tree expr_last
PROTO((tree
));
272 /* Utilities for debugging and error diagnostics. */
274 static void warn_with_method
PROTO((char *, int, tree
));
275 static void error_with_ivar
PROTO((char *, tree
, tree
));
276 static char *gen_method_decl
PROTO((tree
, char *));
277 static char *gen_declaration
PROTO((tree
, char *));
278 static char *gen_declarator
PROTO((tree
, char *, char *));
279 static int is_complex_decl
PROTO((tree
));
280 static void adorn_decl
PROTO((tree
, char *));
281 static void dump_interface
PROTO((FILE *, tree
));
283 /* Everything else. */
285 static void objc_fatal
PROTO((void));
286 static tree define_decl
PROTO((tree
, tree
));
287 static tree lookup_method_in_protocol_list
PROTO((tree
, tree
, int));
288 static tree lookup_protocol_in_reflist
PROTO((tree
, tree
));
289 static tree create_builtin_decl
PROTO((enum tree_code
,
291 static tree my_build_string
PROTO((int, char *));
292 static void build_objc_symtab_template
PROTO((void));
293 static tree init_def_list
PROTO((tree
));
294 static tree init_objc_symtab
PROTO((tree
));
295 static void forward_declare_categories
PROTO((void));
296 static void generate_objc_symtab_decl
PROTO((void));
297 static tree build_selector
PROTO((tree
));
298 static tree build_msg_pool_reference
PROTO((int));
299 static tree build_typed_selector_reference
PROTO((tree
, tree
));
300 static tree build_selector_reference
PROTO((tree
));
301 static tree build_class_reference_decl
PROTO((tree
));
302 static void add_class_reference
PROTO((tree
));
303 static tree objc_copy_list
PROTO((tree
, tree
*));
304 static tree build_protocol_template
PROTO((void));
305 static tree build_descriptor_table_initializer
PROTO((tree
, tree
));
306 static tree build_method_prototype_list_template
PROTO((tree
, int));
307 static tree build_method_prototype_template
PROTO((void));
308 static int forwarding_offset
PROTO((tree
));
309 static tree encode_method_prototype
PROTO((tree
, tree
));
310 static tree generate_descriptor_table
PROTO((tree
, char *, int, tree
, tree
));
311 static void generate_method_descriptors
PROTO((tree
));
312 static tree build_tmp_function_decl
PROTO((void));
313 static void hack_method_prototype
PROTO((tree
, tree
));
314 static void generate_protocol_references
PROTO((tree
));
315 static void generate_protocols
PROTO((void));
316 static void check_ivars
PROTO((tree
, tree
));
317 static tree build_ivar_list_template
PROTO((tree
, int));
318 static tree build_method_list_template
PROTO((tree
, int));
319 static tree build_ivar_list_initializer
PROTO((tree
, tree
));
320 static tree generate_ivars_list
PROTO((tree
, char *,
322 static tree build_dispatch_table_initializer
PROTO((tree
, tree
));
323 static tree generate_dispatch_table
PROTO((tree
, char *,
325 static tree build_shared_structure_initializer
PROTO((tree
, tree
, tree
, tree
,
326 tree
, int, tree
, tree
,
328 static void generate_category
PROTO((tree
));
329 static int is_objc_type_qualifier
PROTO((tree
));
330 static tree adjust_type_for_id_default
PROTO((tree
));
331 static tree check_duplicates
PROTO((hash
));
332 static tree receiver_is_class_object
PROTO((tree
));
333 static int check_methods
PROTO((tree
, tree
, int));
334 static int conforms_to_protocol
PROTO((tree
, tree
));
335 static void check_protocols
PROTO((tree
, char *, char *));
336 static tree encode_method_def
PROTO((tree
));
337 static void gen_declspecs
PROTO((tree
, char *, int));
338 static void generate_classref_translation_entry
PROTO((tree
));
339 static void handle_class_ref
PROTO((tree
));
341 /*** Private Interface (data) ***/
343 /* Reserved tag definitions. */
346 #define TAG_OBJECT "objc_object"
347 #define TAG_CLASS "objc_class"
348 #define TAG_SUPER "objc_super"
349 #define TAG_SELECTOR "objc_selector"
351 #define UTAG_CLASS "_objc_class"
352 #define UTAG_IVAR "_objc_ivar"
353 #define UTAG_IVAR_LIST "_objc_ivar_list"
354 #define UTAG_METHOD "_objc_method"
355 #define UTAG_METHOD_LIST "_objc_method_list"
356 #define UTAG_CATEGORY "_objc_category"
357 #define UTAG_MODULE "_objc_module"
358 #define UTAG_STATICS "_objc_statics"
359 #define UTAG_SYMTAB "_objc_symtab"
360 #define UTAG_SUPER "_objc_super"
361 #define UTAG_SELECTOR "_objc_selector"
363 #define UTAG_PROTOCOL "_objc_protocol"
364 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
365 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
366 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
368 #define STRING_OBJECT_CLASS_NAME "NXConstantString"
369 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
371 static char *TAG_GETCLASS
;
372 static char *TAG_GETMETACLASS
;
373 static char *TAG_MSGSEND
;
374 static char *TAG_MSGSENDSUPER
;
375 static char *TAG_EXECCLASS
;
377 /* Set by `continue_class' and checked by `is_public'. */
379 #define TREE_STATIC_TEMPLATE(record_type) (TREE_PUBLIC (record_type))
380 #define TYPED_OBJECT(type) \
381 (TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type))
383 /* Some commonly used instances of "identifier_node". */
385 static tree self_id
, ucmd_id
;
386 static tree unused_list
;
388 static tree self_decl
, umsg_decl
, umsg_super_decl
;
389 static tree objc_get_class_decl
, objc_get_meta_class_decl
;
391 static tree super_type
, selector_type
, id_type
, objc_class_type
;
392 static tree instance_type
, protocol_type
;
394 /* Type checking macros. */
396 #define IS_ID(TYPE) \
397 (TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (id_type))
398 #define IS_PROTOCOL_QUALIFIED_ID(TYPE) \
399 (IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE))
400 #define IS_SUPER(TYPE) \
401 (super_type && TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (super_type))
403 static tree class_chain
= NULL_TREE
;
404 static tree alias_chain
= NULL_TREE
;
405 static tree interface_chain
= NULL_TREE
;
406 static tree protocol_chain
= NULL_TREE
;
408 /* Chains to manage selectors that are referenced and defined in the
411 static tree cls_ref_chain
= NULL_TREE
; /* Classes referenced. */
412 static tree sel_ref_chain
= NULL_TREE
; /* Selectors referenced. */
414 /* Chains to manage uniquing of strings. */
416 static tree class_names_chain
= NULL_TREE
;
417 static tree meth_var_names_chain
= NULL_TREE
;
418 static tree meth_var_types_chain
= NULL_TREE
;
420 /* Hash tables to manage the global pool of method prototypes. */
422 static hash
*nst_method_hash_list
= 0;
423 static hash
*cls_method_hash_list
= 0;
425 /* Backend data declarations. */
427 static tree UOBJC_SYMBOLS_decl
;
428 static tree UOBJC_INSTANCE_VARIABLES_decl
, UOBJC_CLASS_VARIABLES_decl
;
429 static tree UOBJC_INSTANCE_METHODS_decl
, UOBJC_CLASS_METHODS_decl
;
430 static tree UOBJC_CLASS_decl
, UOBJC_METACLASS_decl
;
431 static tree UOBJC_SELECTOR_TABLE_decl
;
432 static tree UOBJC_MODULES_decl
;
433 static tree UOBJC_STRINGS_decl
;
435 /* The following are used when compiling a class implementation.
436 implementation_template will normally be an interface, however if
437 none exists this will be equal to implementation_context...it is
438 set in start_class. */
440 static tree implementation_context
= NULL_TREE
;
441 static tree implementation_template
= NULL_TREE
;
445 struct imp_entry
*next
;
448 tree class_decl
; /* _OBJC_CLASS_<my_name>; */
449 tree meta_decl
; /* _OBJC_METACLASS_<my_name>; */
452 static void handle_impent
PROTO((struct imp_entry
*));
454 static struct imp_entry
*imp_list
= 0;
455 static int imp_count
= 0; /* `@implementation' */
456 static int cat_count
= 0; /* `@category' */
458 static tree objc_class_template
, objc_category_template
, uprivate_record
;
459 static tree objc_protocol_template
, objc_selector_template
;
460 static tree ucls_super_ref
, uucls_super_ref
;
462 static tree objc_method_template
, objc_ivar_template
;
463 static tree objc_symtab_template
, objc_module_template
;
464 static tree objc_super_template
, objc_object_reference
;
466 static tree objc_object_id
, objc_class_id
, objc_id_id
;
467 static tree constant_string_id
;
468 static tree constant_string_type
;
469 static tree UOBJC_SUPER_decl
;
471 static tree method_context
= NULL_TREE
;
472 static int method_slot
= 0; /* Used by start_method_def, */
476 static char *errbuf
; /* Buffer for error diagnostics */
478 /* Data imported from tree.c. */
480 extern enum debug_info_type write_symbols
;
482 /* Data imported from toplev.c. */
484 extern char *dump_base_name
;
486 /* Generate code for GNU or NeXT runtime environment. */
488 #ifdef NEXT_OBJC_RUNTIME
489 int flag_next_runtime
= 1;
491 int flag_next_runtime
= 0;
494 int flag_typed_selectors
;
496 /* Open and close the file for outputting class declarations, if requested. */
498 int flag_gen_declaration
= 0;
500 FILE *gen_declaration_file
;
502 /* Warn if multiple methods are seen for the same selector, but with
503 different argument types. */
505 int warn_selector
= 0;
507 /* Warn if methods required by a protocol are not implemented in the
508 class adopting it. When turned off, methods inherited to that
509 class are also considered implemented */
511 int flag_warn_protocol
= 1;
513 /* Tells "encode_pointer/encode_aggregate" whether we are generating
514 type descriptors for instance variables (as opposed to methods).
515 Type descriptors for instance variables contain more information
516 than methods (for static typing and embedded structures). This
517 was added to support features being planned for dbkit2. */
519 static int generating_instance_variables
= 0;
521 /* Tells the compiler that this is a special run. Do not perform
522 any compiling, instead we are to test some platform dependent
523 features and output a C header file with appropriate definitions. */
525 static int print_struct_values
= 0;
527 /* Some platforms pass small structures through registers versus through
528 an invisible pointer. Determine at what size structure is the
529 transition point between the two possibilities. */
532 generate_struct_by_value_array ()
535 tree field_decl
, field_decl_chain
;
537 int aggregate_in_mem
[32];
540 /* Presumbaly no platform passes 32 byte structures in a register. */
541 for (i
= 1; i
< 32; i
++)
545 /* Create an unnamed struct that has `i' character components */
546 type
= start_struct (RECORD_TYPE
, NULL_TREE
);
548 strcpy (buffer
, "c1");
549 field_decl
= create_builtin_decl (FIELD_DECL
,
552 field_decl_chain
= field_decl
;
554 for (j
= 1; j
< i
; j
++)
556 sprintf (buffer
, "c%d", j
+ 1);
557 field_decl
= create_builtin_decl (FIELD_DECL
,
560 chainon (field_decl_chain
, field_decl
);
562 finish_struct (type
, field_decl_chain
, NULL_TREE
);
564 aggregate_in_mem
[i
] = aggregate_value_p (type
);
565 if (!aggregate_in_mem
[i
])
569 /* We found some structures that are returned in registers instead of memory
570 so output the necessary data. */
573 for (i
= 31; i
>= 0; i
--)
574 if (!aggregate_in_mem
[i
])
576 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i
);
578 /* The first member of the structure is always 0 because we don't handle
579 structures with 0 members */
580 printf ("static int struct_forward_array[] = {\n 0");
582 for (j
= 1; j
<= i
; j
++)
583 printf (", %d", aggregate_in_mem
[j
]);
599 /* The beginning of the file is a new line; check for #.
600 With luck, we discover the real source file's name from that
601 and put it in input_filename. */
602 ungetc (check_newline (), finput
);
605 /* The line number can be -1 if we had -g3 and the input file
606 had a directive specifying line 0. But we want predefined
607 functions to have a line number of 0, not -1. */
611 /* If gen_declaration desired, open the output file. */
612 if (flag_gen_declaration
)
614 int dump_base_name_length
= strlen (dump_base_name
);
615 register char *dumpname
= (char *) xmalloc (dump_base_name_length
+ 7);
616 strcpy (dumpname
, dump_base_name
);
617 strcat (dumpname
, ".decl");
618 gen_declaration_file
= fopen (dumpname
, "w");
619 if (gen_declaration_file
== 0)
620 pfatal_with_name (dumpname
);
623 if (flag_next_runtime
)
625 TAG_GETCLASS
= "objc_getClass";
626 TAG_GETMETACLASS
= "objc_getMetaClass";
627 TAG_MSGSEND
= "objc_msgSend";
628 TAG_MSGSENDSUPER
= "objc_msgSendSuper";
629 TAG_EXECCLASS
= "__objc_execClass";
633 TAG_GETCLASS
= "objc_get_class";
634 TAG_GETMETACLASS
= "objc_get_meta_class";
635 TAG_MSGSEND
= "objc_msg_lookup";
636 TAG_MSGSENDSUPER
= "objc_msg_lookup_super";
637 TAG_EXECCLASS
= "__objc_exec_class";
638 flag_typed_selectors
= 1;
641 if (doing_objc_thang
)
644 if (print_struct_values
)
645 generate_struct_by_value_array ();
651 fatal ("Objective-C text in C source file");
657 if (doing_objc_thang
)
658 finish_objc (); /* Objective-C finalization */
660 if (gen_declaration_file
)
661 fclose (gen_declaration_file
);
676 lang_decode_option (argc
, argv
)
682 if (! cpp_initialized
)
684 cpp_reader_init (&parse_in
);
685 parse_in
.data
= &parse_options
;
686 cpp_options_init (&parse_options
);
690 if (!strcmp (p
, "-lang-objc"))
691 doing_objc_thang
= 1;
692 else if (!strcmp (p
, "-gen-decls"))
693 flag_gen_declaration
= 1;
694 else if (!strcmp (p
, "-Wselector"))
696 else if (!strcmp (p
, "-Wno-selector"))
698 else if (!strcmp (p
, "-Wprotocol"))
699 flag_warn_protocol
= 1;
700 else if (!strcmp (p
, "-Wno-protocol"))
701 flag_warn_protocol
= 0;
702 else if (!strcmp (p
, "-fgnu-runtime"))
703 flag_next_runtime
= 0;
704 else if (!strcmp (p
, "-fno-next-runtime"))
705 flag_next_runtime
= 0;
706 else if (!strcmp (p
, "-fno-gnu-runtime"))
707 flag_next_runtime
= 1;
708 else if (!strcmp (p
, "-fnext-runtime"))
709 flag_next_runtime
= 1;
710 else if (!strcmp (p
, "-print-objc-runtime-info"))
711 print_struct_values
= 1;
713 return c_decode_option (argc
, argv
);
718 /* used by print-tree.c */
721 lang_print_xnode (file
, node
, indent
)
722 FILE *file ATTRIBUTE_UNUSED
;
723 tree node ATTRIBUTE_UNUSED
;
724 int indent ATTRIBUTE_UNUSED
;
730 define_decl (declarator
, declspecs
)
734 tree decl
= start_decl (declarator
, declspecs
, 0, NULL_TREE
, NULL_TREE
);
735 finish_decl (decl
, NULL_TREE
, NULL_TREE
);
739 /* Return 1 if LHS and RHS are compatible types for assignment or
740 various other operations. Return 0 if they are incompatible, and
741 return -1 if we choose to not decide. When the operation is
742 REFLEXIVE, check for compatibility in either direction.
744 For statically typed objects, an assignment of the form `a' = `b'
748 `a' and `b' are the same class type, or
749 `a' and `b' are of class types A and B such that B is a descendant of A. */
752 maybe_objc_comptypes (lhs
, rhs
, reflexive
)
756 if (doing_objc_thang
)
757 return objc_comptypes (lhs
, rhs
, reflexive
);
762 lookup_method_in_protocol_list (rproto_list
, sel_name
, class_meth
)
770 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
772 p
= TREE_VALUE (rproto
);
774 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
776 if ((fnd
= lookup_method (class_meth
777 ? PROTOCOL_CLS_METHODS (p
)
778 : PROTOCOL_NST_METHODS (p
), sel_name
)))
780 else if (PROTOCOL_LIST (p
))
781 fnd
= lookup_method_in_protocol_list (PROTOCOL_LIST (p
),
782 sel_name
, class_meth
);
786 ; /* An identifier...if we could not find a protocol. */
797 lookup_protocol_in_reflist (rproto_list
, lproto
)
803 /* Make sure the protocol is support by the object on the rhs. */
804 if (TREE_CODE (lproto
) == PROTOCOL_INTERFACE_TYPE
)
807 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
809 p
= TREE_VALUE (rproto
);
811 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
816 else if (PROTOCOL_LIST (p
))
817 fnd
= lookup_protocol_in_reflist (PROTOCOL_LIST (p
), lproto
);
826 ; /* An identifier...if we could not find a protocol. */
832 /* Return 1 if LHS and RHS are compatible types for assignment
833 or various other operations. Return 0 if they are incompatible,
834 and return -1 if we choose to not decide. When the operation
835 is REFLEXIVE, check for compatibility in either direction. */
838 objc_comptypes (lhs
, rhs
, reflexive
)
843 /* New clause for protocols. */
845 if (TREE_CODE (lhs
) == POINTER_TYPE
846 && TREE_CODE (TREE_TYPE (lhs
)) == RECORD_TYPE
847 && TREE_CODE (rhs
) == POINTER_TYPE
848 && TREE_CODE (TREE_TYPE (rhs
)) == RECORD_TYPE
)
850 int lhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (lhs
);
851 int rhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (rhs
);
855 tree lproto
, lproto_list
= TYPE_PROTOCOL_LIST (lhs
);
856 tree rproto
, rproto_list
;
861 rproto_list
= TYPE_PROTOCOL_LIST (rhs
);
863 /* Make sure the protocol is supported by the object
865 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
867 p
= TREE_VALUE (lproto
);
868 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
871 warning ("object does not conform to the `%s' protocol",
872 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
875 else if (TYPED_OBJECT (TREE_TYPE (rhs
)))
877 tree rname
= TYPE_NAME (TREE_TYPE (rhs
));
880 /* Make sure the protocol is supported by the object
882 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
884 p
= TREE_VALUE (lproto
);
886 rinter
= lookup_interface (rname
);
888 while (rinter
&& !rproto
)
892 rproto_list
= CLASS_PROTOCOL_LIST (rinter
);
893 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
895 /* Check for protocols adopted by categories. */
896 cat
= CLASS_CATEGORY_LIST (rinter
);
897 while (cat
&& !rproto
)
899 rproto_list
= CLASS_PROTOCOL_LIST (cat
);
900 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
902 cat
= CLASS_CATEGORY_LIST (cat
);
905 rinter
= lookup_interface (CLASS_SUPER_NAME (rinter
));
909 warning ("class `%s' does not implement the `%s' protocol",
910 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs
))),
911 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
915 /* May change...based on whether there was any mismatch */
918 else if (rhs_is_proto
)
919 /* Lhs is not a protocol...warn if it is statically typed */
920 return (TYPED_OBJECT (TREE_TYPE (lhs
)) != 0);
923 /* Defer to comptypes .*/
927 else if (TREE_CODE (lhs
) == RECORD_TYPE
&& TREE_CODE (rhs
) == RECORD_TYPE
)
928 ; /* Fall thru. This is the case we have been handling all along */
930 /* Defer to comptypes. */
933 /* `id' = `<class> *', `<class> *' = `id' */
935 if ((TYPE_NAME (lhs
) == objc_object_id
&& TYPED_OBJECT (rhs
))
936 || (TYPE_NAME (rhs
) == objc_object_id
&& TYPED_OBJECT (lhs
)))
939 /* `id' = `Class', `Class' = `id' */
941 else if ((TYPE_NAME (lhs
) == objc_object_id
942 && TYPE_NAME (rhs
) == objc_class_id
)
943 || (TYPE_NAME (lhs
) == objc_class_id
944 && TYPE_NAME (rhs
) == objc_object_id
))
947 /* `<class> *' = `<class> *' */
949 else if (TYPED_OBJECT (lhs
) && TYPED_OBJECT (rhs
))
951 tree lname
= TYPE_NAME (lhs
);
952 tree rname
= TYPE_NAME (rhs
);
958 /* If the left hand side is a super class of the right hand side,
960 for (inter
= lookup_interface (rname
); inter
;
961 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
962 if (lname
== CLASS_SUPER_NAME (inter
))
965 /* Allow the reverse when reflexive. */
967 for (inter
= lookup_interface (lname
); inter
;
968 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
969 if (rname
== CLASS_SUPER_NAME (inter
))
975 /* Defer to comptypes. */
979 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
982 objc_check_decl (decl
)
985 tree type
= TREE_TYPE (decl
);
987 if (TREE_CODE (type
) == RECORD_TYPE
988 && TREE_STATIC_TEMPLATE (type
)
989 && type
!= constant_string_type
)
991 error_with_decl (decl
, "`%s' cannot be statically allocated");
992 fatal ("statically allocated objects not supported");
997 maybe_objc_check_decl (decl
)
1000 if (doing_objc_thang
)
1001 objc_check_decl (decl
);
1004 /* Implement static typing. At this point, we know we have an interface. */
1007 get_static_reference (interface
, protocols
)
1011 tree type
= xref_tag (RECORD_TYPE
, interface
);
1015 tree t
, m
= TYPE_MAIN_VARIANT (type
);
1017 push_obstacks_nochange ();
1018 end_temporary_allocation ();
1019 t
= copy_node (type
);
1020 TYPE_BINFO (t
) = make_tree_vec (2);
1023 /* Add this type to the chain of variants of TYPE. */
1024 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
1025 TYPE_NEXT_VARIANT (m
) = t
;
1027 /* Look up protocols and install in lang specific list. */
1028 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
1030 /* This forces a new pointer type to be created later
1031 (in build_pointer_type)...so that the new template
1032 we just created will actually be used...what a hack! */
1033 if (TYPE_POINTER_TO (t
))
1034 TYPE_POINTER_TO (t
) = 0;
1043 get_object_reference (protocols
)
1046 tree type_decl
= lookup_name (objc_id_id
);
1049 if (type_decl
&& TREE_CODE (type_decl
) == TYPE_DECL
)
1051 type
= TREE_TYPE (type_decl
);
1052 if (TYPE_MAIN_VARIANT (type
) != id_type
)
1053 warning ("Unexpected type for `id' (%s)",
1054 gen_declaration (type
, errbuf
));
1057 fatal ("Undefined type `id', please import <objc/objc.h>");
1059 /* This clause creates a new pointer type that is qualified with
1060 the protocol specification...this info is used later to do more
1061 elaborate type checking. */
1065 tree t
, m
= TYPE_MAIN_VARIANT (type
);
1067 push_obstacks_nochange ();
1068 end_temporary_allocation ();
1069 t
= copy_node (type
);
1070 TYPE_BINFO (t
) = make_tree_vec (2);
1073 /* Add this type to the chain of variants of TYPE. */
1074 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
1075 TYPE_NEXT_VARIANT (m
) = t
;
1077 /* Look up protocols...and install in lang specific list */
1078 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
1080 /* This forces a new pointer type to be created later
1081 (in build_pointer_type)...so that the new template
1082 we just created will actually be used...what a hack! */
1083 if (TYPE_POINTER_TO (t
))
1084 TYPE_POINTER_TO (t
) = NULL
;
1092 lookup_and_install_protocols (protocols
)
1097 tree return_value
= protocols
;
1099 for (proto
= protocols
; proto
; proto
= TREE_CHAIN (proto
))
1101 tree ident
= TREE_VALUE (proto
);
1102 tree p
= lookup_protocol (ident
);
1106 error ("Cannot find protocol declaration for `%s'",
1107 IDENTIFIER_POINTER (ident
));
1109 TREE_CHAIN (prev
) = TREE_CHAIN (proto
);
1111 return_value
= TREE_CHAIN (proto
);
1115 /* Replace identifier with actual protocol node. */
1116 TREE_VALUE (proto
) = p
;
1121 return return_value
;
1124 /* Create and push a decl for a built-in external variable or field NAME.
1126 TYPE is its data type. */
1129 create_builtin_decl (code
, type
, name
)
1130 enum tree_code code
;
1134 tree decl
= build_decl (code
, get_identifier (name
), type
);
1136 if (code
== VAR_DECL
)
1138 TREE_STATIC (decl
) = 1;
1139 make_decl_rtl (decl
, 0, 1);
1143 DECL_ARTIFICIAL (decl
) = 1;
1147 /* Purpose: "play" parser, creating/installing representations
1148 of the declarations that are required by Objective-C.
1152 type_spec--------->sc_spec
1153 (tree_list) (tree_list)
1156 identifier_node identifier_node */
1159 synth_module_prologue ()
1164 /* Defined in `objc.h' */
1165 objc_object_id
= get_identifier (TAG_OBJECT
);
1167 objc_object_reference
= xref_tag (RECORD_TYPE
, objc_object_id
);
1169 id_type
= build_pointer_type (objc_object_reference
);
1171 objc_id_id
= get_identifier (TYPE_ID
);
1172 objc_class_id
= get_identifier (TAG_CLASS
);
1174 objc_class_type
= build_pointer_type (xref_tag (RECORD_TYPE
, objc_class_id
));
1175 protocol_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
1176 get_identifier (PROTOCOL_OBJECT_CLASS_NAME
)));
1178 /* Declare type of selector-objects that represent an operation name. */
1180 #ifdef OBJC_INT_SELECTORS
1181 /* `unsigned int' */
1182 selector_type
= unsigned_type_node
;
1184 /* `struct objc_selector *' */
1186 = build_pointer_type (xref_tag (RECORD_TYPE
,
1187 get_identifier (TAG_SELECTOR
)));
1188 #endif /* not OBJC_INT_SELECTORS */
1190 /* Forward declare type, or else the prototype for msgSendSuper will
1193 super_p
= build_pointer_type (xref_tag (RECORD_TYPE
,
1194 get_identifier (TAG_SUPER
)));
1197 /* id objc_msgSend (id, SEL, ...); */
1200 = build_function_type (id_type
,
1201 tree_cons (NULL_TREE
, id_type
,
1202 tree_cons (NULL_TREE
, selector_type
,
1205 if (! flag_next_runtime
)
1207 umsg_decl
= build_decl (FUNCTION_DECL
,
1208 get_identifier (TAG_MSGSEND
), temp_type
);
1209 DECL_EXTERNAL (umsg_decl
) = 1;
1210 TREE_PUBLIC (umsg_decl
) = 1;
1211 DECL_INLINE (umsg_decl
) = 1;
1212 DECL_ARTIFICIAL (umsg_decl
) = 1;
1214 if (flag_traditional
&& TAG_MSGSEND
[0] != '_')
1215 DECL_BUILT_IN_NONANSI (umsg_decl
) = 1;
1217 make_decl_rtl (umsg_decl
, NULL_PTR
, 1);
1218 pushdecl (umsg_decl
);
1221 umsg_decl
= builtin_function (TAG_MSGSEND
, temp_type
, NOT_BUILT_IN
, 0);
1223 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1226 = build_function_type (id_type
,
1227 tree_cons (NULL_TREE
, super_p
,
1228 tree_cons (NULL_TREE
, selector_type
,
1231 umsg_super_decl
= builtin_function (TAG_MSGSENDSUPER
,
1232 temp_type
, NOT_BUILT_IN
, 0);
1234 /* id objc_getClass (const char *); */
1236 temp_type
= build_function_type (id_type
,
1237 tree_cons (NULL_TREE
,
1238 const_string_type_node
,
1239 tree_cons (NULL_TREE
, void_type_node
,
1243 = builtin_function (TAG_GETCLASS
, temp_type
, NOT_BUILT_IN
, 0);
1245 /* id objc_getMetaClass (const char *); */
1247 objc_get_meta_class_decl
1248 = builtin_function (TAG_GETMETACLASS
, temp_type
, NOT_BUILT_IN
, 0);
1250 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1252 if (! flag_next_runtime
)
1254 if (flag_typed_selectors
)
1256 /* Suppress outputting debug symbols, because
1257 dbxout_init hasn'r been called yet. */
1258 enum debug_info_type save_write_symbols
= write_symbols
;
1259 write_symbols
= NO_DEBUG
;
1261 build_selector_template ();
1262 temp_type
= build_array_type (objc_selector_template
, NULL_TREE
);
1264 write_symbols
= save_write_symbols
;
1267 temp_type
= build_array_type (selector_type
, NULL_TREE
);
1269 layout_type (temp_type
);
1270 UOBJC_SELECTOR_TABLE_decl
1271 = create_builtin_decl (VAR_DECL
, temp_type
,
1272 "_OBJC_SELECTOR_TABLE");
1274 /* Avoid warning when not sending messages. */
1275 TREE_USED (UOBJC_SELECTOR_TABLE_decl
) = 1;
1278 generate_forward_declaration_to_string_table ();
1280 /* Forward declare constant_string_id and constant_string_type. */
1281 constant_string_id
= get_identifier (STRING_OBJECT_CLASS_NAME
);
1282 constant_string_type
= xref_tag (RECORD_TYPE
, constant_string_id
);
1285 /* Custom build_string which sets TREE_TYPE! */
1288 my_build_string (len
, str
)
1293 tree a_string
= build_string (len
, str
);
1295 /* Some code from combine_strings, which is local to c-parse.y. */
1296 if (TREE_TYPE (a_string
) == int_array_type_node
)
1299 TREE_TYPE (a_string
)
1300 = build_array_type (wide_flag
? integer_type_node
: char_type_node
,
1301 build_index_type (build_int_2 (len
- 1, 0)));
1303 TREE_CONSTANT (a_string
) = 1; /* Puts string in the readonly segment */
1304 TREE_STATIC (a_string
) = 1;
1309 /* Return a newly constructed OBJC_STRING_CST node whose value is
1310 the LEN characters at STR.
1311 The TREE_TYPE is not initialized. */
1314 build_objc_string (len
, str
)
1318 tree s
= build_string (len
, str
);
1320 TREE_SET_CODE (s
, OBJC_STRING_CST
);
1324 /* Given a chain of OBJC_STRING_CST's, build a static instance of
1325 NXConstanString which points at the concatenation of those strings.
1326 We place the string object in the __string_objects section of the
1327 __OBJC segment. The Objective-C runtime will initialize the isa
1328 pointers of the string objects to point at the NXConstandString class
1332 build_objc_string_object (strings
)
1335 tree string
, initlist
, constructor
;
1338 if (!doing_objc_thang
)
1341 if (lookup_interface (constant_string_id
) == NULL_TREE
)
1343 error ("Cannot find interface declaration for `%s'",
1344 IDENTIFIER_POINTER (constant_string_id
));
1345 return error_mark_node
;
1348 add_class_reference (constant_string_id
);
1350 /* Combine_strings will work for OBJC_STRING_CST's too. */
1351 string
= combine_strings (strings
);
1352 TREE_SET_CODE (string
, STRING_CST
);
1353 length
= TREE_STRING_LENGTH (string
) - 1;
1355 if (! flag_next_runtime
)
1357 push_obstacks_nochange ();
1358 end_temporary_allocation ();
1359 if (! TREE_PERMANENT (strings
))
1360 string
= my_build_string (length
+ 1,
1361 TREE_STRING_POINTER (string
));
1364 /* & ((NXConstantString) {0, string, length}) */
1366 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1368 = tree_cons (NULL_TREE
, copy_node (build_unary_op (ADDR_EXPR
, string
, 1)),
1370 initlist
= tree_cons (NULL_TREE
, build_int_2 (length
, 0), initlist
);
1371 constructor
= build_constructor (constant_string_type
, nreverse (initlist
));
1373 if (!flag_next_runtime
)
1376 = objc_add_static_instance (constructor
, constant_string_type
);
1380 return (build_unary_op (ADDR_EXPR
, constructor
, 1));
1383 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1386 objc_add_static_instance (constructor
, class_decl
)
1387 tree constructor
, class_decl
;
1389 static int num_static_inst
;
1393 push_obstacks_nochange ();
1394 end_temporary_allocation ();
1396 /* Find the list of static instances for the CLASS_DECL. Create one if
1398 for (chain
= &objc_static_instances
;
1399 *chain
&& TREE_VALUE (*chain
) != class_decl
;
1400 chain
= &TREE_CHAIN (*chain
));
1403 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
1404 add_objc_string (TYPE_NAME (class_decl
), class_names
);
1407 sprintf (buf
, "_OBJC_INSTANCE_%d", num_static_inst
++);
1408 decl
= build_decl (VAR_DECL
, get_identifier (buf
), class_decl
);
1409 DECL_COMMON (decl
) = 1;
1410 TREE_STATIC (decl
) = 1;
1411 DECL_ARTIFICIAL (decl
) = 1;
1412 pushdecl_top_level (decl
);
1413 rest_of_decl_compilation (decl
, 0, 1, 0);
1415 /* Do this here so it gets output later instead of possibly
1416 inside something else we are writing. */
1417 DECL_INITIAL (decl
) = constructor
;
1419 /* Add the DECL to the head of this CLASS' list. */
1420 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
1426 /* Build a static constant CONSTRUCTOR
1427 with type TYPE and elements ELTS. */
1430 build_constructor (type
, elts
)
1433 tree constructor
= build (CONSTRUCTOR
, type
, NULL_TREE
, elts
);
1435 TREE_CONSTANT (constructor
) = 1;
1436 TREE_STATIC (constructor
) = 1;
1437 TREE_READONLY (constructor
) = 1;
1442 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1444 /* Predefine the following data type:
1452 void *defs[cls_def_cnt + cat_def_cnt];
1456 build_objc_symtab_template ()
1458 tree field_decl
, field_decl_chain
, index
;
1460 objc_symtab_template
1461 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SYMTAB
));
1463 /* long sel_ref_cnt; */
1465 field_decl
= create_builtin_decl (FIELD_DECL
,
1466 long_integer_type_node
,
1468 field_decl_chain
= field_decl
;
1472 field_decl
= create_builtin_decl (FIELD_DECL
,
1473 build_pointer_type (selector_type
),
1475 chainon (field_decl_chain
, field_decl
);
1477 /* short cls_def_cnt; */
1479 field_decl
= create_builtin_decl (FIELD_DECL
,
1480 short_integer_type_node
,
1482 chainon (field_decl_chain
, field_decl
);
1484 /* short cat_def_cnt; */
1486 field_decl
= create_builtin_decl (FIELD_DECL
,
1487 short_integer_type_node
,
1489 chainon (field_decl_chain
, field_decl
);
1491 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1493 if (!flag_next_runtime
)
1494 index
= build_index_type (build_int_2 (imp_count
+ cat_count
, 0));
1496 index
= build_index_type (build_int_2 (imp_count
+ cat_count
- 1,
1497 imp_count
== 0 && cat_count
== 0
1499 field_decl
= create_builtin_decl (FIELD_DECL
,
1500 build_array_type (ptr_type_node
, index
),
1502 chainon (field_decl_chain
, field_decl
);
1504 finish_struct (objc_symtab_template
, field_decl_chain
, NULL_TREE
);
1507 /* Create the initial value for the `defs' field of _objc_symtab.
1508 This is a CONSTRUCTOR. */
1511 init_def_list (type
)
1514 tree expr
, initlist
= NULL_TREE
;
1515 struct imp_entry
*impent
;
1518 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1520 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
1522 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1523 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1528 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1530 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1532 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1533 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1537 if (!flag_next_runtime
)
1539 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1542 if (static_instances_decl
)
1543 expr
= build_unary_op (ADDR_EXPR
, static_instances_decl
, 0);
1545 expr
= build_int_2 (0, 0);
1547 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1550 return build_constructor (type
, nreverse (initlist
));
1553 /* Construct the initial value for all of _objc_symtab. */
1556 init_objc_symtab (type
)
1561 /* sel_ref_cnt = { ..., 5, ... } */
1563 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1565 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1567 if (flag_next_runtime
|| ! sel_ref_chain
)
1568 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1570 initlist
= tree_cons (NULL_TREE
,
1571 build_unary_op (ADDR_EXPR
,
1572 UOBJC_SELECTOR_TABLE_decl
, 1),
1575 /* cls_def_cnt = { ..., 5, ... } */
1577 initlist
= tree_cons (NULL_TREE
, build_int_2 (imp_count
, 0), initlist
);
1579 /* cat_def_cnt = { ..., 5, ... } */
1581 initlist
= tree_cons (NULL_TREE
, build_int_2 (cat_count
, 0), initlist
);
1583 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1585 if (imp_count
|| cat_count
|| static_instances_decl
)
1588 tree field
= TYPE_FIELDS (type
);
1589 field
= TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field
))));
1591 initlist
= tree_cons (NULL_TREE
, init_def_list (TREE_TYPE (field
)),
1595 return build_constructor (type
, nreverse (initlist
));
1598 /* Push forward-declarations of all the categories
1599 so that init_def_list can use them in a CONSTRUCTOR. */
1602 forward_declare_categories ()
1604 struct imp_entry
*impent
;
1605 tree sav
= implementation_context
;
1607 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1609 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1611 /* Set an invisible arg to synth_id_with_class_suffix. */
1612 implementation_context
= impent
->imp_context
;
1614 = create_builtin_decl (VAR_DECL
, objc_category_template
,
1615 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", implementation_context
)));
1618 implementation_context
= sav
;
1621 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1622 and initialized appropriately. */
1625 generate_objc_symtab_decl ()
1629 if (!objc_category_template
)
1630 build_category_template ();
1632 /* forward declare categories */
1634 forward_declare_categories ();
1636 if (!objc_symtab_template
)
1637 build_objc_symtab_template ();
1639 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
1641 UOBJC_SYMBOLS_decl
= start_decl (get_identifier ("_OBJC_SYMBOLS"),
1642 tree_cons (NULL_TREE
,
1643 objc_symtab_template
, sc_spec
),
1645 NULL_TREE
, NULL_TREE
);
1647 TREE_USED (UOBJC_SYMBOLS_decl
) = 1;
1648 DECL_IGNORED_P (UOBJC_SYMBOLS_decl
) = 1;
1649 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl
) = 1;
1650 finish_decl (UOBJC_SYMBOLS_decl
,
1651 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)),
1656 init_module_descriptor (type
)
1659 tree initlist
, expr
;
1661 /* version = { 1, ... } */
1663 expr
= build_int_2 (OBJC_VERSION
, 0);
1664 initlist
= build_tree_list (NULL_TREE
, expr
);
1666 /* size = { ..., sizeof (struct objc_module), ... } */
1668 expr
= size_in_bytes (objc_module_template
);
1669 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1671 /* name = { ..., "foo.m", ... } */
1673 expr
= add_objc_string (get_identifier (input_filename
), class_names
);
1674 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1676 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1678 if (UOBJC_SYMBOLS_decl
)
1679 expr
= build_unary_op (ADDR_EXPR
, UOBJC_SYMBOLS_decl
, 0);
1681 expr
= build_int_2 (0, 0);
1682 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1684 return build_constructor (type
, nreverse (initlist
));
1687 /* Write out the data structures to describe Objective C classes defined.
1688 If appropriate, compile and output a setup function to initialize them.
1689 Return a string which is the name of a function to call to initialize
1690 the Objective C data structures for this file (and perhaps for other files
1693 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1696 build_module_descriptor ()
1698 tree decl_specs
, field_decl
, field_decl_chain
;
1700 objc_module_template
1701 = start_struct (RECORD_TYPE
, get_identifier (UTAG_MODULE
));
1705 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1706 field_decl
= get_identifier ("version");
1708 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1709 field_decl_chain
= field_decl
;
1713 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1714 field_decl
= get_identifier ("size");
1716 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1717 chainon (field_decl_chain
, field_decl
);
1721 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
1722 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
1724 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1725 chainon (field_decl_chain
, field_decl
);
1727 /* struct objc_symtab *symtab; */
1729 decl_specs
= get_identifier (UTAG_SYMTAB
);
1730 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
1731 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("symtab"));
1733 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1734 chainon (field_decl_chain
, field_decl
);
1736 finish_struct (objc_module_template
, field_decl_chain
, NULL_TREE
);
1738 /* Create an instance of "objc_module". */
1740 decl_specs
= tree_cons (NULL_TREE
, objc_module_template
,
1741 build_tree_list (NULL_TREE
,
1742 ridpointers
[(int) RID_STATIC
]));
1744 UOBJC_MODULES_decl
= start_decl (get_identifier ("_OBJC_MODULES"),
1745 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
1747 DECL_ARTIFICIAL (UOBJC_MODULES_decl
) = 1;
1748 DECL_IGNORED_P (UOBJC_MODULES_decl
) = 1;
1749 finish_decl (UOBJC_MODULES_decl
,
1750 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl
)),
1753 /* Mark the decl to avoid "defined but not used" warning. */
1754 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl
) = 1;
1756 /* Generate a constructor call for the module descriptor.
1757 This code was generated by reading the grammar rules
1758 of c-parse.in; Therefore, it may not be the most efficient
1759 way of generating the requisite code. */
1761 if (flag_next_runtime
)
1765 tree parms
, function_decl
, decelerator
, void_list_node
;
1767 tree init_function_name
= get_file_function_name ('I');
1769 /* Declare void __objc_execClass (void *); */
1771 void_list_node
= build_tree_list (NULL_TREE
, void_type_node
);
1773 = build_function_type (void_type_node
,
1774 tree_cons (NULL_TREE
, ptr_type_node
,
1776 function_decl
= build_decl (FUNCTION_DECL
,
1777 get_identifier (TAG_EXECCLASS
),
1779 DECL_EXTERNAL (function_decl
) = 1;
1780 DECL_ARTIFICIAL (function_decl
) = 1;
1781 TREE_PUBLIC (function_decl
) = 1;
1783 pushdecl (function_decl
);
1784 rest_of_decl_compilation (function_decl
, 0, 0, 0);
1787 = build_tree_list (NULL_TREE
,
1788 build_unary_op (ADDR_EXPR
, UOBJC_MODULES_decl
, 0));
1789 decelerator
= build_function_call (function_decl
, parms
);
1791 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1793 start_function (void_list_node
,
1794 build_parse_node (CALL_EXPR
, init_function_name
,
1795 /* This has the format of the output
1796 of get_parm_info. */
1797 tree_cons (NULL_TREE
, NULL_TREE
,
1800 NULL_TREE
, NULL_TREE
, 0);
1801 #if 0 /* This should be turned back on later
1802 for the systems where collect is not needed. */
1803 /* Make these functions nonglobal
1804 so each file can use the same name. */
1805 TREE_PUBLIC (current_function_decl
) = 0;
1807 TREE_USED (current_function_decl
) = 1;
1808 store_parm_decls ();
1810 assemble_external (function_decl
);
1811 c_expand_expr_stmt (decelerator
);
1813 TREE_PUBLIC (current_function_decl
) = 1;
1815 function_decl
= current_function_decl
;
1816 finish_function (0);
1818 /* Return the name of the constructor function. */
1819 return XSTR (XEXP (DECL_RTL (function_decl
), 0), 0);
1823 /* extern const char _OBJC_STRINGS[]; */
1826 generate_forward_declaration_to_string_table ()
1828 tree sc_spec
, decl_specs
, expr_decl
;
1830 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_EXTERN
], NULL_TREE
);
1831 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1834 = build_nt (ARRAY_REF
, get_identifier ("_OBJC_STRINGS"), NULL_TREE
);
1836 UOBJC_STRINGS_decl
= define_decl (expr_decl
, decl_specs
);
1839 /* Return the DECL of the string IDENT in the SECTION. */
1842 get_objc_string_decl (ident
, section
)
1844 enum string_section section
;
1848 if (section
== class_names
)
1849 chain
= class_names_chain
;
1850 else if (section
== meth_var_names
)
1851 chain
= meth_var_names_chain
;
1852 else if (section
== meth_var_types
)
1853 chain
= meth_var_types_chain
;
1855 for (; chain
!= 0; chain
= TREE_VALUE (chain
))
1856 if (TREE_VALUE (chain
) == ident
)
1857 return (TREE_PURPOSE (chain
));
1863 /* Output references to all statically allocated objects. Return the DECL
1864 for the array built. */
1867 generate_static_references ()
1869 tree decls
= NULL_TREE
, ident
, decl_spec
, expr_decl
, expr
= NULL_TREE
;
1870 tree class_name
, class, decl
, initlist
;
1871 tree cl_chain
, in_chain
, type
;
1872 int num_inst
, num_class
;
1875 if (flag_next_runtime
)
1878 for (cl_chain
= objc_static_instances
, num_class
= 0;
1879 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
1881 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
1882 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
1884 sprintf (buf
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
1885 ident
= get_identifier (buf
);
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 decl
= start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
, NULL_TREE
);
1892 DECL_CONTEXT (decl
) = 0;
1893 DECL_ARTIFICIAL (decl
) = 1;
1895 /* Output {class_name, ...}. */
1896 class = TREE_VALUE (cl_chain
);
1897 class_name
= get_objc_string_decl (TYPE_NAME (class), class_names
);
1898 initlist
= build_tree_list (NULL_TREE
,
1899 build_unary_op (ADDR_EXPR
, class_name
, 1));
1901 /* Output {..., instance, ...}. */
1902 for (in_chain
= TREE_PURPOSE (cl_chain
);
1903 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
1905 expr
= build_unary_op (ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
1906 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1909 /* Output {..., NULL}. */
1910 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1912 expr
= build_constructor (TREE_TYPE (decl
), nreverse (initlist
));
1913 finish_decl (decl
, expr
, NULL_TREE
);
1914 TREE_USED (decl
) = 1;
1916 type
= build_array_type (build_pointer_type (void_type_node
), 0);
1917 decl
= build_decl (VAR_DECL
, ident
, type
);
1918 make_decl_rtl (decl
, 0, 1);
1919 TREE_USED (decl
) = 1;
1921 = tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, decl
, 1), decls
);
1924 decls
= tree_cons (NULL_TREE
, build_int_2 (0, 0), decls
);
1925 ident
= get_identifier ("_OBJC_STATIC_INSTANCES");
1926 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1927 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1928 build_tree_list (NULL_TREE
,
1929 ridpointers
[(int) RID_STATIC
]));
1930 static_instances_decl
1931 = start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
, NULL_TREE
);
1932 TREE_USED (static_instances_decl
) = 1;
1933 DECL_CONTEXT (static_instances_decl
) = 0;
1934 DECL_ARTIFICIAL (static_instances_decl
) = 1;
1935 end_temporary_allocation ();
1936 expr
= build_constructor (TREE_TYPE (static_instances_decl
),
1938 finish_decl (static_instances_decl
, expr
, NULL_TREE
);
1941 /* Output all strings. */
1946 tree sc_spec
, decl_specs
, expr_decl
;
1947 tree chain
, string_expr
;
1950 for (chain
= class_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1952 string
= TREE_VALUE (chain
);
1953 decl
= TREE_PURPOSE (chain
);
1955 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1956 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1957 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1958 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
1959 end_temporary_allocation ();
1960 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1961 IDENTIFIER_POINTER (string
));
1962 finish_decl (decl
, string_expr
, NULL_TREE
);
1965 for (chain
= meth_var_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1967 string
= TREE_VALUE (chain
);
1968 decl
= TREE_PURPOSE (chain
);
1970 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1971 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1972 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1973 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
1974 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1975 IDENTIFIER_POINTER (string
));
1976 finish_decl (decl
, string_expr
, NULL_TREE
);
1979 for (chain
= meth_var_types_chain
; chain
; chain
= TREE_CHAIN (chain
))
1981 string
= TREE_VALUE (chain
);
1982 decl
= TREE_PURPOSE (chain
);
1984 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1985 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1986 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1987 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
1988 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1989 IDENTIFIER_POINTER (string
));
1990 finish_decl (decl
, string_expr
, NULL_TREE
);
1995 build_selector_reference_decl (name
)
2002 sprintf (buf
, "_OBJC_SELECTOR_REFERENCES_%d", idx
++);
2004 push_obstacks_nochange ();
2005 end_temporary_allocation ();
2007 ident
= get_identifier (buf
);
2009 decl
= build_decl (VAR_DECL
, ident
, selector_type
);
2010 DECL_EXTERNAL (decl
) = 1;
2011 TREE_PUBLIC (decl
) = 1;
2012 TREE_USED (decl
) = 1;
2013 TREE_READONLY (decl
) = 1;
2014 DECL_ARTIFICIAL (decl
) = 1;
2015 DECL_CONTEXT (decl
) = 0;
2017 make_decl_rtl (decl
, 0, 1);
2018 pushdecl_top_level (decl
);
2025 /* Just a handy wrapper for add_objc_string. */
2028 build_selector (ident
)
2031 tree expr
= add_objc_string (ident
, meth_var_names
);
2032 if (flag_typed_selectors
)
2035 return build_c_cast (selector_type
, expr
); /* cast! */
2038 /* Synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>]
2039 The cast stops the compiler from issuing the following message:
2040 grok.m: warning: initialization of non-const * pointer from const *
2041 grok.m: warning: initialization between incompatible pointer types. */
2044 build_msg_pool_reference (offset
)
2047 tree expr
= build_int_2 (offset
, 0);
2050 expr
= build_array_ref (UOBJC_STRINGS_decl
, expr
);
2051 expr
= build_unary_op (ADDR_EXPR
, expr
, 0);
2053 cast
= build_tree_list (build_tree_list (NULL_TREE
,
2054 ridpointers
[(int) RID_CHAR
]),
2055 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
2056 TREE_TYPE (expr
) = groktypename (cast
);
2061 init_selector (offset
)
2064 tree expr
= build_msg_pool_reference (offset
);
2065 TREE_TYPE (expr
) = selector_type
;
2070 build_selector_translation_table ()
2072 tree sc_spec
, decl_specs
;
2073 tree chain
, initlist
= NULL_TREE
;
2075 tree decl
, var_decl
, name
;
2077 /* The corresponding pop_obstacks is in finish_decl,
2078 called at the end of this function. */
2079 if (! flag_next_runtime
)
2080 push_obstacks_nochange ();
2082 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
2086 expr
= build_selector (TREE_VALUE (chain
));
2088 if (flag_next_runtime
)
2090 name
= DECL_NAME (TREE_PURPOSE (chain
));
2092 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
2094 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2095 decl_specs
= tree_cons (NULL_TREE
, selector_type
, sc_spec
);
2099 /* The `decl' that is returned from start_decl is the one that we
2100 forward declared in `build_selector_reference' */
2101 decl
= start_decl (var_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2104 /* add one for the '\0' character */
2105 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (chain
)) + 1;
2107 if (flag_next_runtime
)
2108 finish_decl (decl
, expr
, NULL_TREE
);
2111 if (flag_typed_selectors
)
2113 tree eltlist
= NULL_TREE
;
2114 tree encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
2115 eltlist
= tree_cons (NULL_TREE
, expr
, NULL_TREE
);
2116 eltlist
= tree_cons (NULL_TREE
, encoding
, eltlist
);
2117 expr
= build_constructor (objc_selector_template
,
2118 nreverse (eltlist
));
2120 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2125 if (! flag_next_runtime
)
2127 /* Cause the variable and its initial value to be actually output. */
2128 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl
) = 0;
2129 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl
) = 1;
2130 /* NULL terminate the list and fix the decl for output. */
2131 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
2132 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl
) = (tree
) 1;
2133 initlist
= build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
2134 nreverse (initlist
));
2135 finish_decl (UOBJC_SELECTOR_TABLE_decl
, initlist
, NULL_TREE
);
2136 current_function_decl
= NULL_TREE
;
2141 get_proto_encoding (proto
)
2149 if (! METHOD_ENCODING (proto
))
2151 tmp_decl
= build_tmp_function_decl ();
2152 hack_method_prototype (proto
, tmp_decl
);
2153 encoding
= encode_method_prototype (proto
, tmp_decl
);
2154 METHOD_ENCODING (proto
) = encoding
;
2157 encoding
= METHOD_ENCODING (proto
);
2159 return add_objc_string (encoding
, meth_var_types
);
2162 return build_int_2 (0, 0);
2165 /* sel_ref_chain is a list whose "value" fields will be instances of
2166 identifier_node that represent the selector. */
2169 build_typed_selector_reference (ident
, proto
)
2172 tree
*chain
= &sel_ref_chain
;
2178 if (TREE_PURPOSE (*chain
) == ident
&& TREE_VALUE (*chain
) == proto
)
2179 goto return_at_index
;
2182 chain
= &TREE_CHAIN (*chain
);
2185 *chain
= perm_tree_cons (proto
, ident
, NULL_TREE
);
2188 expr
= build_unary_op (ADDR_EXPR
,
2189 build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2190 build_int_2 (index
, 0)),
2192 return build_c_cast (selector_type
, expr
);
2196 build_selector_reference (ident
)
2199 tree
*chain
= &sel_ref_chain
;
2205 if (TREE_VALUE (*chain
) == ident
)
2206 return (flag_next_runtime
2207 ? TREE_PURPOSE (*chain
)
2208 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2209 build_int_2 (index
, 0)));
2212 chain
= &TREE_CHAIN (*chain
);
2215 expr
= build_selector_reference_decl (ident
);
2217 *chain
= perm_tree_cons (expr
, ident
, NULL_TREE
);
2219 return (flag_next_runtime
2221 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2222 build_int_2 (index
, 0)));
2226 build_class_reference_decl (name
)
2233 sprintf (buf
, "_OBJC_CLASS_REFERENCES_%d", idx
++);
2235 push_obstacks_nochange ();
2236 end_temporary_allocation ();
2238 ident
= get_identifier (buf
);
2240 decl
= build_decl (VAR_DECL
, ident
, objc_class_type
);
2241 DECL_EXTERNAL (decl
) = 1;
2242 TREE_PUBLIC (decl
) = 1;
2243 TREE_USED (decl
) = 1;
2244 TREE_READONLY (decl
) = 1;
2245 DECL_CONTEXT (decl
) = 0;
2246 DECL_ARTIFICIAL (decl
) = 1;
2248 make_decl_rtl (decl
, 0, 1);
2249 pushdecl_top_level (decl
);
2256 /* Create a class reference, but don't create a variable to reference
2260 add_class_reference (ident
)
2265 if ((chain
= cls_ref_chain
))
2270 if (ident
== TREE_VALUE (chain
))
2274 chain
= TREE_CHAIN (chain
);
2278 /* Append to the end of the list */
2279 TREE_CHAIN (tail
) = perm_tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2282 cls_ref_chain
= perm_tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2285 /* Get a class reference, creating it if necessary. Also create the
2286 reference variable. */
2289 get_class_reference (ident
)
2292 if (flag_next_runtime
)
2297 for (chain
= &cls_ref_chain
; *chain
; chain
= &TREE_CHAIN (*chain
))
2298 if (TREE_VALUE (*chain
) == ident
)
2300 if (! TREE_PURPOSE (*chain
))
2301 TREE_PURPOSE (*chain
) = build_class_reference_decl (ident
);
2303 return TREE_PURPOSE (*chain
);
2306 decl
= build_class_reference_decl (ident
);
2307 *chain
= perm_tree_cons (decl
, ident
, NULL_TREE
);
2314 add_class_reference (ident
);
2316 params
= build_tree_list (NULL_TREE
,
2317 my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
2318 IDENTIFIER_POINTER (ident
)));
2320 assemble_external (objc_get_class_decl
);
2321 return build_function_call (objc_get_class_decl
, params
);
2325 /* SEL_REFDEF_CHAIN is a list whose "value" fields will be instances
2326 of identifier_node that represent the selector. It returns the
2327 offset of the selector from the beginning of the _OBJC_STRINGS
2328 pool. This offset is typically used by init_selector during code
2331 For each string section we have a chain which maps identifier nodes
2332 to decls for the strings. */
2335 add_objc_string (ident
, section
)
2337 enum string_section section
;
2341 if (section
== class_names
)
2342 chain
= &class_names_chain
;
2343 else if (section
== meth_var_names
)
2344 chain
= &meth_var_names_chain
;
2345 else if (section
== meth_var_types
)
2346 chain
= &meth_var_types_chain
;
2350 if (TREE_VALUE (*chain
) == ident
)
2351 return build_unary_op (ADDR_EXPR
, TREE_PURPOSE (*chain
), 1);
2353 chain
= &TREE_CHAIN (*chain
);
2356 decl
= build_objc_string_decl (ident
, section
);
2358 *chain
= perm_tree_cons (decl
, ident
, NULL_TREE
);
2360 return build_unary_op (ADDR_EXPR
, decl
, 1);
2364 build_objc_string_decl (name
, section
)
2366 enum string_section section
;
2370 static int class_names_idx
= 0;
2371 static int meth_var_names_idx
= 0;
2372 static int meth_var_types_idx
= 0;
2374 if (section
== class_names
)
2375 sprintf (buf
, "_OBJC_CLASS_NAME_%d", class_names_idx
++);
2376 else if (section
== meth_var_names
)
2377 sprintf (buf
, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx
++);
2378 else if (section
== meth_var_types
)
2379 sprintf (buf
, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx
++);
2381 push_obstacks_nochange ();
2382 end_temporary_allocation ();
2383 ident
= get_identifier (buf
);
2385 decl
= build_decl (VAR_DECL
, ident
, build_array_type (char_type_node
, 0));
2386 DECL_EXTERNAL (decl
) = 1;
2387 TREE_PUBLIC (decl
) = 1;
2388 TREE_USED (decl
) = 1;
2389 TREE_READONLY (decl
) = 1;
2390 TREE_CONSTANT (decl
) = 1;
2391 DECL_CONTEXT (decl
) = 0;
2392 DECL_ARTIFICIAL (decl
) = 1;
2394 make_decl_rtl (decl
, 0, 1);
2395 pushdecl_top_level (decl
);
2404 objc_declare_alias (alias_ident
, class_ident
)
2408 if (!doing_objc_thang
)
2411 if (is_class_name (class_ident
) != class_ident
)
2412 warning ("Cannot find class `%s'", IDENTIFIER_POINTER (class_ident
));
2413 else if (is_class_name (alias_ident
))
2414 warning ("Class `%s' already exists", IDENTIFIER_POINTER (alias_ident
));
2416 alias_chain
= tree_cons (class_ident
, alias_ident
, alias_chain
);
2420 objc_declare_class (ident_list
)
2425 if (!doing_objc_thang
)
2428 for (list
= ident_list
; list
; list
= TREE_CHAIN (list
))
2430 tree ident
= TREE_VALUE (list
);
2433 if ((decl
= lookup_name (ident
)))
2435 error ("`%s' redeclared as different kind of symbol",
2436 IDENTIFIER_POINTER (ident
));
2437 error_with_decl (decl
, "previous declaration of `%s'");
2440 if (! is_class_name (ident
))
2442 tree record
= xref_tag (RECORD_TYPE
, ident
);
2443 TREE_STATIC_TEMPLATE (record
) = 1;
2444 class_chain
= tree_cons (NULL_TREE
, ident
, class_chain
);
2450 is_class_name (ident
)
2455 if (lookup_interface (ident
))
2458 for (chain
= class_chain
; chain
; chain
= TREE_CHAIN (chain
))
2460 if (ident
== TREE_VALUE (chain
))
2464 for (chain
= alias_chain
; chain
; chain
= TREE_CHAIN (chain
))
2466 if (ident
== TREE_VALUE (chain
))
2467 return TREE_PURPOSE (chain
);
2474 lookup_interface (ident
)
2479 for (chain
= interface_chain
; chain
; chain
= TREE_CHAIN (chain
))
2481 if (ident
== CLASS_NAME (chain
))
2488 objc_copy_list (list
, head
)
2492 tree newlist
= NULL_TREE
, tail
= NULL_TREE
;
2496 tail
= copy_node (list
);
2498 /* The following statement fixes a bug when inheriting instance
2499 variables that are declared to be bitfields. finish_struct
2500 expects to find the width of the bitfield in DECL_INITIAL,
2501 which it nulls out after processing the decl of the super
2502 class...rather than change the way finish_struct works (which
2503 is risky), I create the situation it expects...s.naroff
2506 if (DECL_BIT_FIELD (tail
) && DECL_INITIAL (tail
) == 0)
2507 DECL_INITIAL (tail
) = build_int_2 (DECL_FIELD_SIZE (tail
), 0);
2509 newlist
= chainon (newlist
, tail
);
2510 list
= TREE_CHAIN (list
);
2517 /* Used by: build_private_template, get_class_ivars, and
2518 continue_class. COPY is 1 when called from @defs. In this case
2519 copy all fields. Otherwise don't copy leaf ivars since we rely on
2520 them being side-effected exactly once by finish_struct. */
2523 build_ivar_chain (interface
, copy
)
2527 tree my_name
, super_name
, ivar_chain
;
2529 my_name
= CLASS_NAME (interface
);
2530 super_name
= CLASS_SUPER_NAME (interface
);
2532 /* Possibly copy leaf ivars. */
2534 objc_copy_list (CLASS_IVARS (interface
), &ivar_chain
);
2536 ivar_chain
= CLASS_IVARS (interface
);
2541 tree super_interface
= lookup_interface (super_name
);
2543 if (!super_interface
)
2545 /* fatal did not work with 2 args...should fix */
2546 error ("Cannot find interface declaration for `%s', superclass of `%s'",
2547 IDENTIFIER_POINTER (super_name
),
2548 IDENTIFIER_POINTER (my_name
));
2549 exit (FATAL_EXIT_CODE
);
2552 if (super_interface
== interface
)
2554 fatal ("Circular inheritance in interface declaration for `%s'",
2555 IDENTIFIER_POINTER (super_name
));
2558 interface
= super_interface
;
2559 my_name
= CLASS_NAME (interface
);
2560 super_name
= CLASS_SUPER_NAME (interface
);
2562 op1
= CLASS_IVARS (interface
);
2565 tree head
, tail
= objc_copy_list (op1
, &head
);
2567 /* Prepend super class ivars...make a copy of the list, we
2568 do not want to alter the original. */
2569 TREE_CHAIN (tail
) = ivar_chain
;
2576 /* struct <classname> {
2577 struct objc_class *isa;
2582 build_private_template (class)
2587 if (CLASS_STATIC_TEMPLATE (class))
2589 uprivate_record
= CLASS_STATIC_TEMPLATE (class);
2590 ivar_context
= TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2594 uprivate_record
= start_struct (RECORD_TYPE
, CLASS_NAME (class));
2596 ivar_context
= build_ivar_chain (class, 0);
2598 finish_struct (uprivate_record
, ivar_context
, NULL_TREE
);
2600 CLASS_STATIC_TEMPLATE (class) = uprivate_record
;
2602 /* mark this record as class template - for class type checking */
2603 TREE_STATIC_TEMPLATE (uprivate_record
) = 1;
2607 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
2609 build1 (INDIRECT_REF
, NULL_TREE
,
2612 return ivar_context
;
2615 /* Begin code generation for protocols... */
2617 /* struct objc_protocol {
2618 char *protocol_name;
2619 struct objc_protocol **protocol_list;
2620 struct objc_method_desc *instance_methods;
2621 struct objc_method_desc *class_methods;
2625 build_protocol_template ()
2627 tree decl_specs
, field_decl
, field_decl_chain
;
2630 template = start_struct (RECORD_TYPE
, get_identifier (UTAG_PROTOCOL
));
2632 /* struct objc_class *isa; */
2634 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2635 get_identifier (UTAG_CLASS
)));
2636 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
2638 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2639 field_decl_chain
= field_decl
;
2641 /* char *protocol_name; */
2643 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
2645 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_name"));
2647 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2648 chainon (field_decl_chain
, field_decl
);
2650 /* struct objc_protocol **protocol_list; */
2652 decl_specs
= build_tree_list (NULL_TREE
, template);
2654 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
2655 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
2657 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2658 chainon (field_decl_chain
, field_decl
);
2660 /* struct objc_method_list *instance_methods; */
2663 = build_tree_list (NULL_TREE
,
2664 xref_tag (RECORD_TYPE
,
2665 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2667 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
2669 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2670 chainon (field_decl_chain
, field_decl
);
2672 /* struct objc_method_list *class_methods; */
2675 = build_tree_list (NULL_TREE
,
2676 xref_tag (RECORD_TYPE
,
2677 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2679 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
2681 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2682 chainon (field_decl_chain
, field_decl
);
2684 return finish_struct (template, field_decl_chain
, NULL_TREE
);
2688 build_descriptor_table_initializer (type
, entries
)
2692 tree initlist
= NULL_TREE
;
2696 tree eltlist
= NULL_TREE
;
2699 = tree_cons (NULL_TREE
,
2700 build_selector (METHOD_SEL_NAME (entries
)), NULL_TREE
);
2702 = tree_cons (NULL_TREE
,
2703 add_objc_string (METHOD_ENCODING (entries
),
2708 = tree_cons (NULL_TREE
,
2709 build_constructor (type
, nreverse (eltlist
)), initlist
);
2711 entries
= TREE_CHAIN (entries
);
2715 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
2718 /* struct objc_method_prototype_list {
2720 struct objc_method_prototype {
2727 build_method_prototype_list_template (list_type
, size
)
2731 tree objc_ivar_list_record
;
2732 tree decl_specs
, field_decl
, field_decl_chain
;
2734 /* Generate an unnamed struct definition. */
2736 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
2738 /* int method_count; */
2740 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
2741 field_decl
= get_identifier ("method_count");
2744 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2745 field_decl_chain
= field_decl
;
2747 /* struct objc_method method_list[]; */
2749 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
2750 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
2751 build_int_2 (size
, 0));
2754 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2755 chainon (field_decl_chain
, field_decl
);
2757 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
2759 return objc_ivar_list_record
;
2763 build_method_prototype_template ()
2766 tree decl_specs
, field_decl
, field_decl_chain
;
2769 = start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD_PROTOTYPE
));
2771 #ifdef OBJC_INT_SELECTORS
2772 /* unsigned int _cmd; */
2774 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_UNSIGNED
], NULL_TREE
);
2775 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_INT
], decl_specs
);
2776 field_decl
= get_identifier ("_cmd");
2777 #else /* OBJC_INT_SELECTORS */
2778 /* struct objc_selector *_cmd; */
2779 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
2780 get_identifier (TAG_SELECTOR
)), NULL_TREE
);
2781 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
2782 #endif /* OBJC_INT_SELECTORS */
2785 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2786 field_decl_chain
= field_decl
;
2788 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
2790 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_types"));
2792 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2793 chainon (field_decl_chain
, field_decl
);
2795 finish_struct (proto_record
, field_decl_chain
, NULL_TREE
);
2797 return proto_record
;
2800 /* True if last call to forwarding_offset yielded a register offset. */
2801 static int offset_is_register
;
2804 forwarding_offset (parm
)
2807 int offset_in_bytes
;
2809 if (GET_CODE (DECL_INCOMING_RTL (parm
)) == MEM
)
2811 rtx addr
= XEXP (DECL_INCOMING_RTL (parm
), 0);
2813 /* ??? Here we assume that the parm address is indexed
2814 off the frame pointer or arg pointer.
2815 If that is not true, we produce meaningless results,
2816 but do not crash. */
2817 if (GET_CODE (addr
) == PLUS
2818 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
2819 offset_in_bytes
= INTVAL (XEXP (addr
, 1));
2821 offset_in_bytes
= 0;
2823 offset_in_bytes
+= OBJC_FORWARDING_STACK_OFFSET
;
2824 offset_is_register
= 0;
2826 else if (GET_CODE (DECL_INCOMING_RTL (parm
)) == REG
)
2828 int regno
= REGNO (DECL_INCOMING_RTL (parm
));
2829 offset_in_bytes
= apply_args_register_offset (regno
);
2830 offset_is_register
= 1;
2835 /* This is the case where the parm is passed as an int or double
2836 and it is converted to a char, short or float and stored back
2837 in the parmlist. In this case, describe the parm
2838 with the variable's declared type, and adjust the address
2839 if the least significant bytes (which we are using) are not
2841 if (BYTES_BIG_ENDIAN
&& TREE_TYPE (parm
) != DECL_ARG_TYPE (parm
))
2842 offset_in_bytes
+= (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm
)))
2843 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm
))));
2845 return offset_in_bytes
;
2849 encode_method_prototype (method_decl
, func_decl
)
2856 int max_parm_end
= 0;
2860 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2861 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl
)));
2864 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
2865 obstack_object_size (&util_obstack
),
2866 OBJC_ENCODE_INLINE_DEFS
);
2869 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
2870 parms
= TREE_CHAIN (parms
))
2872 int parm_end
= (forwarding_offset (parms
)
2873 + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms
)))
2876 if (!offset_is_register
&& max_parm_end
< parm_end
)
2877 max_parm_end
= parm_end
;
2880 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
2882 sprintf (buf
, "%d", stack_size
);
2883 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2885 user_args
= METHOD_SEL_ARGS (method_decl
);
2887 /* Argument types. */
2888 for (parms
= DECL_ARGUMENTS (func_decl
), i
= 0; parms
;
2889 parms
= TREE_CHAIN (parms
), i
++)
2891 /* Process argument qualifiers for user supplied arguments. */
2894 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args
)));
2895 user_args
= TREE_CHAIN (user_args
);
2899 encode_type (TREE_TYPE (parms
),
2900 obstack_object_size (&util_obstack
),
2901 OBJC_ENCODE_INLINE_DEFS
);
2903 /* Compute offset. */
2904 sprintf (buf
, "%d", forwarding_offset (parms
));
2906 /* Indicate register. */
2907 if (offset_is_register
)
2908 obstack_1grow (&util_obstack
, '+');
2910 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2913 obstack_1grow (&util_obstack
, '\0');
2914 result
= get_identifier (obstack_finish (&util_obstack
));
2915 obstack_free (&util_obstack
, util_firstobj
);
2920 generate_descriptor_table (type
, name
, size
, list
, proto
)
2927 tree sc_spec
, decl_specs
, decl
, initlist
;
2929 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2930 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
2932 decl
= start_decl (synth_id_with_class_suffix (name
, proto
),
2933 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2935 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
2936 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
2938 finish_decl (decl
, build_constructor (type
, nreverse (initlist
)),
2945 generate_method_descriptors (protocol
) /* generate_dispatch_tables */
2948 static tree objc_method_prototype_template
;
2949 tree initlist
, chain
, method_list_template
;
2950 tree cast
, variable_length_type
;
2953 if (!objc_method_prototype_template
)
2954 objc_method_prototype_template
= build_method_prototype_template ();
2956 cast
= build_tree_list (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2957 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
))),
2959 variable_length_type
= groktypename (cast
);
2961 chain
= PROTOCOL_CLS_METHODS (protocol
);
2964 size
= list_length (chain
);
2966 method_list_template
2967 = build_method_prototype_list_template (objc_method_prototype_template
,
2971 = build_descriptor_table_initializer (objc_method_prototype_template
,
2974 UOBJC_CLASS_METHODS_decl
2975 = generate_descriptor_table (method_list_template
,
2976 "_OBJC_PROTOCOL_CLASS_METHODS",
2977 size
, initlist
, protocol
);
2978 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
2981 UOBJC_CLASS_METHODS_decl
= 0;
2983 chain
= PROTOCOL_NST_METHODS (protocol
);
2986 size
= list_length (chain
);
2988 method_list_template
2989 = build_method_prototype_list_template (objc_method_prototype_template
,
2992 = build_descriptor_table_initializer (objc_method_prototype_template
,
2995 UOBJC_INSTANCE_METHODS_decl
2996 = generate_descriptor_table (method_list_template
,
2997 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2998 size
, initlist
, protocol
);
2999 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
3002 UOBJC_INSTANCE_METHODS_decl
= 0;
3006 build_tmp_function_decl ()
3008 tree decl_specs
, expr_decl
, parms
;
3012 /* struct objc_object *objc_xxx (id, SEL, ...); */
3014 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3015 push_parm_decl (build_tree_list
3016 (build_tree_list (decl_specs
,
3017 build1 (INDIRECT_REF
, NULL_TREE
,
3019 build_tree_list (NULL_TREE
, NULL_TREE
)));
3021 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3022 get_identifier (TAG_SELECTOR
)));
3023 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
);
3025 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, expr_decl
),
3026 build_tree_list (NULL_TREE
, NULL_TREE
)));
3027 parms
= get_parm_info (0);
3030 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3031 sprintf (buffer
, "__objc_tmp_%x", xxx
++);
3032 expr_decl
= build_nt (CALL_EXPR
, get_identifier (buffer
), parms
, NULL_TREE
);
3033 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
3035 return define_decl (expr_decl
, decl_specs
);
3039 hack_method_prototype (nst_methods
, tmp_decl
)
3046 /* Hack to avoid problem with static typing of self arg. */
3047 TREE_SET_CODE (nst_methods
, CLASS_METHOD_DECL
);
3048 start_method_def (nst_methods
);
3049 TREE_SET_CODE (nst_methods
, INSTANCE_METHOD_DECL
);
3051 if (METHOD_ADD_ARGS (nst_methods
) == (tree
) 1)
3052 parms
= get_parm_info (0); /* we have a `, ...' */
3054 parms
= get_parm_info (1); /* place a `void_at_end' */
3056 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
3058 /* Usually called from store_parm_decls -> init_function_start. */
3060 DECL_ARGUMENTS (tmp_decl
) = TREE_PURPOSE (parms
);
3061 current_function_decl
= tmp_decl
;
3064 /* Code taken from start_function. */
3065 tree restype
= TREE_TYPE (TREE_TYPE (tmp_decl
));
3066 /* Promote the value to int before returning it. */
3067 if (TREE_CODE (restype
) == INTEGER_TYPE
3068 && TYPE_PRECISION (restype
) < TYPE_PRECISION (integer_type_node
))
3069 restype
= integer_type_node
;
3070 DECL_RESULT (tmp_decl
) = build_decl (RESULT_DECL
, 0, restype
);
3073 for (parm
= DECL_ARGUMENTS (tmp_decl
); parm
; parm
= TREE_CHAIN (parm
))
3074 DECL_CONTEXT (parm
) = tmp_decl
;
3076 init_function_start (tmp_decl
, "objc-act", 0);
3078 /* Typically called from expand_function_start for function definitions. */
3079 assign_parms (tmp_decl
, 0);
3081 /* install return type */
3082 TREE_TYPE (TREE_TYPE (tmp_decl
)) = groktypename (TREE_TYPE (nst_methods
));
3087 generate_protocol_references (plist
)
3092 /* Forward declare protocols referenced. */
3093 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
3095 tree proto
= TREE_VALUE (lproto
);
3097 if (TREE_CODE (proto
) == PROTOCOL_INTERFACE_TYPE
3098 && PROTOCOL_NAME (proto
))
3100 if (! PROTOCOL_FORWARD_DECL (proto
))
3101 build_protocol_reference (proto
);
3103 if (PROTOCOL_LIST (proto
))
3104 generate_protocol_references (PROTOCOL_LIST (proto
));
3110 generate_protocols ()
3112 tree p
, tmp_decl
, encoding
;
3113 tree sc_spec
, decl_specs
, decl
;
3114 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
3115 tree cast_type2
= 0;
3117 tmp_decl
= build_tmp_function_decl ();
3119 if (! objc_protocol_template
)
3120 objc_protocol_template
= build_protocol_template ();
3122 /* If a protocol was directly referenced, pull in indirect references. */
3123 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3124 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
3125 generate_protocol_references (PROTOCOL_LIST (p
));
3127 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3129 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
3130 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
3132 /* If protocol wasn't referenced, don't generate any code. */
3133 if (! PROTOCOL_FORWARD_DECL (p
))
3136 /* Make sure we link in the Protocol class. */
3137 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
3141 if (! METHOD_ENCODING (nst_methods
))
3143 hack_method_prototype (nst_methods
, tmp_decl
);
3144 encoding
= encode_method_prototype (nst_methods
, tmp_decl
);
3145 METHOD_ENCODING (nst_methods
) = encoding
;
3147 nst_methods
= TREE_CHAIN (nst_methods
);
3152 if (! METHOD_ENCODING (cls_methods
))
3154 hack_method_prototype (cls_methods
, tmp_decl
);
3155 encoding
= encode_method_prototype (cls_methods
, tmp_decl
);
3156 METHOD_ENCODING (cls_methods
) = encoding
;
3159 cls_methods
= TREE_CHAIN (cls_methods
);
3161 generate_method_descriptors (p
);
3163 if (PROTOCOL_LIST (p
))
3164 refs_decl
= generate_protocol_list (p
);
3168 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3170 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
],
3172 decl_specs
= tree_cons (NULL_TREE
, objc_protocol_template
, sc_spec
);
3174 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
),
3175 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
3177 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
3184 (build_tree_list (build_tree_list (NULL_TREE
,
3185 objc_protocol_template
),
3186 build1 (INDIRECT_REF
, NULL_TREE
,
3187 build1 (INDIRECT_REF
, NULL_TREE
,
3190 refs_expr
= build_unary_op (ADDR_EXPR
, refs_decl
, 0);
3191 TREE_TYPE (refs_expr
) = cast_type2
;
3194 refs_expr
= build_int_2 (0, 0);
3196 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3197 by generate_method_descriptors, which is called above. */
3198 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
3199 protocol_name_expr
, refs_expr
,
3200 UOBJC_INSTANCE_METHODS_decl
,
3201 UOBJC_CLASS_METHODS_decl
);
3202 finish_decl (decl
, initlist
, NULL_TREE
);
3204 /* Mark the decl as used to avoid "defined but not used" warning. */
3205 TREE_USED (decl
) = 1;
3210 build_protocol_initializer (type
, protocol_name
, protocol_list
,
3211 instance_methods
, class_methods
)
3215 tree instance_methods
;
3218 tree initlist
= NULL_TREE
, expr
;
3219 static tree cast_type
= 0;
3225 (build_tree_list (NULL_TREE
,
3226 xref_tag (RECORD_TYPE
,
3227 get_identifier (UTAG_CLASS
))),
3228 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
3230 /* Filling the "isa" in with one allows the runtime system to
3231 detect that the version change...should remove before final release. */
3233 expr
= build_int_2 (PROTOCOL_VERSION
, 0);
3234 TREE_TYPE (expr
) = cast_type
;
3235 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3236 initlist
= tree_cons (NULL_TREE
, protocol_name
, initlist
);
3237 initlist
= tree_cons (NULL_TREE
, protocol_list
, initlist
);
3239 if (!instance_methods
)
3240 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3243 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
3244 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3248 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3251 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
3252 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3255 return build_constructor (type
, nreverse (initlist
));
3258 /* struct objc_category {
3259 char *category_name;
3261 struct objc_method_list *instance_methods;
3262 struct objc_method_list *class_methods;
3263 struct objc_protocol_list *protocols;
3267 build_category_template ()
3269 tree decl_specs
, field_decl
, field_decl_chain
;
3271 objc_category_template
= start_struct (RECORD_TYPE
,
3272 get_identifier (UTAG_CATEGORY
));
3273 /* char *category_name; */
3275 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3277 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("category_name"));
3279 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3280 field_decl_chain
= field_decl
;
3282 /* char *class_name; */
3284 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3285 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_name"));
3287 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3288 chainon (field_decl_chain
, field_decl
);
3290 /* struct objc_method_list *instance_methods; */
3292 decl_specs
= build_tree_list (NULL_TREE
,
3293 xref_tag (RECORD_TYPE
,
3294 get_identifier (UTAG_METHOD_LIST
)));
3296 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
3298 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3299 chainon (field_decl_chain
, field_decl
);
3301 /* struct objc_method_list *class_methods; */
3303 decl_specs
= build_tree_list (NULL_TREE
,
3304 xref_tag (RECORD_TYPE
,
3305 get_identifier (UTAG_METHOD_LIST
)));
3307 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
3309 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3310 chainon (field_decl_chain
, field_decl
);
3312 /* struct objc_protocol **protocol_list; */
3314 decl_specs
= build_tree_list (NULL_TREE
,
3315 xref_tag (RECORD_TYPE
,
3316 get_identifier (UTAG_PROTOCOL
)));
3318 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3319 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3321 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3322 chainon (field_decl_chain
, field_decl
);
3324 finish_struct (objc_category_template
, field_decl_chain
, NULL_TREE
);
3327 /* struct objc_selector {
3333 build_selector_template ()
3336 tree decl_specs
, field_decl
, field_decl_chain
;
3338 objc_selector_template
3339 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SELECTOR
));
3343 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3344 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3346 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3347 field_decl_chain
= field_decl
;
3349 /* char *sel_type; */
3351 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3352 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_type"));
3354 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3355 chainon (field_decl_chain
, field_decl
);
3357 finish_struct (objc_selector_template
, field_decl_chain
, NULL_TREE
);
3360 /* struct objc_class {
3361 struct objc_class *isa;
3362 struct objc_class *super_class;
3367 struct objc_ivar_list *ivars;
3368 struct objc_method_list *methods;
3369 if (flag_next_runtime)
3370 struct objc_cache *cache;
3372 struct sarray *dtable;
3373 struct objc_class *subclass_list;
3374 struct objc_class *sibling_class;
3376 struct objc_protocol_list *protocols;
3380 build_class_template ()
3382 tree decl_specs
, field_decl
, field_decl_chain
;
3385 = start_struct (RECORD_TYPE
, get_identifier (UTAG_CLASS
));
3387 /* struct objc_class *isa; */
3389 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3390 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
3392 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3393 field_decl_chain
= field_decl
;
3395 /* struct objc_class *super_class; */
3397 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3399 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("super_class"));
3401 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3402 chainon (field_decl_chain
, field_decl
);
3406 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3407 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
3409 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3410 chainon (field_decl_chain
, field_decl
);
3414 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3415 field_decl
= get_identifier ("version");
3417 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3418 chainon (field_decl_chain
, field_decl
);
3422 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3423 field_decl
= get_identifier ("info");
3425 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3426 chainon (field_decl_chain
, field_decl
);
3428 /* long instance_size; */
3430 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3431 field_decl
= get_identifier ("instance_size");
3433 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3434 chainon (field_decl_chain
, field_decl
);
3436 /* struct objc_ivar_list *ivars; */
3438 decl_specs
= build_tree_list (NULL_TREE
,
3439 xref_tag (RECORD_TYPE
,
3440 get_identifier (UTAG_IVAR_LIST
)));
3441 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivars"));
3443 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3444 chainon (field_decl_chain
, field_decl
);
3446 /* struct objc_method_list *methods; */
3448 decl_specs
= build_tree_list (NULL_TREE
,
3449 xref_tag (RECORD_TYPE
,
3450 get_identifier (UTAG_METHOD_LIST
)));
3451 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("methods"));
3453 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3454 chainon (field_decl_chain
, field_decl
);
3456 if (flag_next_runtime
)
3458 /* struct objc_cache *cache; */
3460 decl_specs
= build_tree_list (NULL_TREE
,
3461 xref_tag (RECORD_TYPE
,
3462 get_identifier ("objc_cache")));
3463 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("cache"));
3464 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3465 decl_specs
, NULL_TREE
);
3466 chainon (field_decl_chain
, field_decl
);
3470 /* struct sarray *dtable; */
3472 decl_specs
= build_tree_list (NULL_TREE
,
3473 xref_tag (RECORD_TYPE
,
3474 get_identifier ("sarray")));
3475 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("dtable"));
3476 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3477 decl_specs
, NULL_TREE
);
3478 chainon (field_decl_chain
, field_decl
);
3480 /* struct objc_class *subclass_list; */
3482 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3484 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("subclass_list"));
3485 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3486 decl_specs
, NULL_TREE
);
3487 chainon (field_decl_chain
, field_decl
);
3489 /* struct objc_class *sibling_class; */
3491 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3493 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sibling_class"));
3494 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3495 decl_specs
, NULL_TREE
);
3496 chainon (field_decl_chain
, field_decl
);
3499 /* struct objc_protocol **protocol_list; */
3501 decl_specs
= build_tree_list (NULL_TREE
,
3502 xref_tag (RECORD_TYPE
,
3503 get_identifier (UTAG_PROTOCOL
)));
3505 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3507 = build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3508 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3509 decl_specs
, NULL_TREE
);
3510 chainon (field_decl_chain
, field_decl
);
3513 finish_struct (objc_class_template
, field_decl_chain
, NULL_TREE
);
3516 /* Generate appropriate forward declarations for an implementation. */
3519 synth_forward_declarations ()
3521 tree sc_spec
, decl_specs
, an_id
;
3523 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3525 an_id
= synth_id_with_class_suffix ("_OBJC_CLASS", implementation_context
);
3527 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
3528 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
3529 UOBJC_CLASS_decl
= define_decl (an_id
, decl_specs
);
3530 TREE_USED (UOBJC_CLASS_decl
) = 1;
3531 DECL_ARTIFICIAL (UOBJC_CLASS_decl
) = 1;
3533 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3535 an_id
= synth_id_with_class_suffix ("_OBJC_METACLASS",
3536 implementation_context
);
3538 UOBJC_METACLASS_decl
= define_decl (an_id
, decl_specs
);
3539 TREE_USED (UOBJC_METACLASS_decl
) = 1;
3540 DECL_ARTIFICIAL(UOBJC_METACLASS_decl
) = 1;
3542 /* Pre-build the following entities - for speed/convenience. */
3544 an_id
= get_identifier ("super_class");
3545 ucls_super_ref
= build_component_ref (UOBJC_CLASS_decl
, an_id
);
3546 uucls_super_ref
= build_component_ref (UOBJC_METACLASS_decl
, an_id
);
3550 error_with_ivar (message
, decl
, rawdecl
)
3557 report_error_function (DECL_SOURCE_FILE (decl
));
3559 fprintf (stderr
, "%s:%d: ",
3560 DECL_SOURCE_FILE (decl
), DECL_SOURCE_LINE (decl
));
3561 bzero (errbuf
, BUFSIZE
);
3562 fprintf (stderr
, "%s `%s'\n", message
, gen_declaration (rawdecl
, errbuf
));
3565 #define USERTYPE(t) \
3566 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3567 || TREE_CODE (t) == ENUMERAL_TYPE)
3570 check_ivars (inter
, imp
)
3574 tree intdecls
= CLASS_IVARS (inter
);
3575 tree impdecls
= CLASS_IVARS (imp
);
3576 tree rawintdecls
= CLASS_RAW_IVARS (inter
);
3577 tree rawimpdecls
= CLASS_RAW_IVARS (imp
);
3583 if (intdecls
== 0 && impdecls
== 0)
3585 if (intdecls
== 0 || impdecls
== 0)
3587 error ("inconsistent instance variable specification");
3591 t1
= TREE_TYPE (intdecls
); t2
= TREE_TYPE (impdecls
);
3593 if (!comptypes (t1
, t2
))
3595 if (DECL_NAME (intdecls
) == DECL_NAME (impdecls
))
3597 error_with_ivar ("conflicting instance variable type",
3598 impdecls
, rawimpdecls
);
3599 error_with_ivar ("previous declaration of",
3600 intdecls
, rawintdecls
);
3602 else /* both the type and the name don't match */
3604 error ("inconsistent instance variable specification");
3609 else if (DECL_NAME (intdecls
) != DECL_NAME (impdecls
))
3611 error_with_ivar ("conflicting instance variable name",
3612 impdecls
, rawimpdecls
);
3613 error_with_ivar ("previous declaration of",
3614 intdecls
, rawintdecls
);
3617 intdecls
= TREE_CHAIN (intdecls
);
3618 impdecls
= TREE_CHAIN (impdecls
);
3619 rawintdecls
= TREE_CHAIN (rawintdecls
);
3620 rawimpdecls
= TREE_CHAIN (rawimpdecls
);
3624 /* Set super_type to the data type node for struct objc_super *,
3625 first defining struct objc_super itself.
3626 This needs to be done just once per compilation. */
3629 build_super_template ()
3631 tree record
, decl_specs
, field_decl
, field_decl_chain
;
3633 record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_SUPER
));
3635 /* struct objc_object *self; */
3637 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3638 field_decl
= get_identifier ("self");
3639 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3640 field_decl
= grokfield (input_filename
, lineno
,
3641 field_decl
, decl_specs
, NULL_TREE
);
3642 field_decl_chain
= field_decl
;
3644 /* struct objc_class *class; */
3646 decl_specs
= get_identifier (UTAG_CLASS
);
3647 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
3648 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class"));
3650 field_decl
= grokfield (input_filename
, lineno
,
3651 field_decl
, decl_specs
, NULL_TREE
);
3652 chainon (field_decl_chain
, field_decl
);
3654 finish_struct (record
, field_decl_chain
, NULL_TREE
);
3656 /* `struct objc_super *' */
3657 super_type
= groktypename (build_tree_list (build_tree_list (NULL_TREE
,
3659 build1 (INDIRECT_REF
,
3660 NULL_TREE
, NULL_TREE
)));
3664 /* struct objc_ivar {
3671 build_ivar_template ()
3673 tree objc_ivar_id
, objc_ivar_record
;
3674 tree decl_specs
, field_decl
, field_decl_chain
;
3676 objc_ivar_id
= get_identifier (UTAG_IVAR
);
3677 objc_ivar_record
= start_struct (RECORD_TYPE
, objc_ivar_id
);
3679 /* char *ivar_name; */
3681 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3682 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_name"));
3684 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3685 decl_specs
, NULL_TREE
);
3686 field_decl_chain
= field_decl
;
3688 /* char *ivar_type; */
3690 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3691 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_type"));
3693 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3694 decl_specs
, NULL_TREE
);
3695 chainon (field_decl_chain
, field_decl
);
3697 /* int ivar_offset; */
3699 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3700 field_decl
= get_identifier ("ivar_offset");
3702 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3703 decl_specs
, NULL_TREE
);
3704 chainon (field_decl_chain
, field_decl
);
3706 finish_struct (objc_ivar_record
, field_decl_chain
, NULL_TREE
);
3708 return objc_ivar_record
;
3713 struct objc_ivar ivar_list[ivar_count];
3717 build_ivar_list_template (list_type
, size
)
3721 tree objc_ivar_list_record
;
3722 tree decl_specs
, field_decl
, field_decl_chain
;
3724 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3726 /* int ivar_count; */
3728 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3729 field_decl
= get_identifier ("ivar_count");
3731 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3732 decl_specs
, NULL_TREE
);
3733 field_decl_chain
= field_decl
;
3735 /* struct objc_ivar ivar_list[]; */
3737 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3738 field_decl
= build_nt (ARRAY_REF
, get_identifier ("ivar_list"),
3739 build_int_2 (size
, 0));
3741 field_decl
= grokfield (input_filename
, lineno
,
3742 field_decl
, decl_specs
, NULL_TREE
);
3743 chainon (field_decl_chain
, field_decl
);
3745 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3747 return objc_ivar_list_record
;
3753 struct objc_method method_list[method_count];
3757 build_method_list_template (list_type
, size
)
3761 tree objc_ivar_list_record
;
3762 tree decl_specs
, field_decl
, field_decl_chain
;
3764 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3766 /* int method_next; */
3771 xref_tag (RECORD_TYPE
,
3772 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
3774 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_next"));
3775 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3776 decl_specs
, NULL_TREE
);
3777 field_decl_chain
= field_decl
;
3779 /* int method_count; */
3781 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3782 field_decl
= get_identifier ("method_count");
3784 field_decl
= grokfield (input_filename
, lineno
,
3785 field_decl
, decl_specs
, NULL_TREE
);
3786 chainon (field_decl_chain
, field_decl
);
3788 /* struct objc_method method_list[]; */
3790 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3791 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
3792 build_int_2 (size
, 0));
3794 field_decl
= grokfield (input_filename
, lineno
,
3795 field_decl
, decl_specs
, NULL_TREE
);
3796 chainon (field_decl_chain
, field_decl
);
3798 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3800 return objc_ivar_list_record
;
3804 build_ivar_list_initializer (type
, field_decl
)
3808 tree initlist
= NULL_TREE
;
3812 tree ivar
= NULL_TREE
;
3815 if (DECL_NAME (field_decl
))
3816 ivar
= tree_cons (NULL_TREE
,
3817 add_objc_string (DECL_NAME (field_decl
),
3821 /* Unnamed bit-field ivar (yuck). */
3822 ivar
= tree_cons (NULL_TREE
, build_int_2 (0, 0), ivar
);
3825 encode_field_decl (field_decl
,
3826 obstack_object_size (&util_obstack
),
3827 OBJC_ENCODE_DONT_INLINE_DEFS
);
3829 /* Null terminate string. */
3830 obstack_1grow (&util_obstack
, 0);
3834 add_objc_string (get_identifier (obstack_finish (&util_obstack
)),
3837 obstack_free (&util_obstack
, util_firstobj
);
3843 build_int_2 ((TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl
))
3848 initlist
= tree_cons (NULL_TREE
,
3849 build_constructor (type
, nreverse (ivar
)),
3852 field_decl
= TREE_CHAIN (field_decl
);
3856 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3860 generate_ivars_list (type
, name
, size
, list
)
3866 tree sc_spec
, decl_specs
, decl
, initlist
;
3868 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3869 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
3871 decl
= start_decl (synth_id_with_class_suffix (name
, implementation_context
),
3872 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
3874 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
3875 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3878 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3885 generate_ivar_lists ()
3887 tree initlist
, ivar_list_template
, chain
;
3888 tree cast
, variable_length_type
;
3891 generating_instance_variables
= 1;
3893 if (!objc_ivar_template
)
3894 objc_ivar_template
= build_ivar_template ();
3898 (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3899 get_identifier (UTAG_IVAR_LIST
))),
3901 variable_length_type
= groktypename (cast
);
3903 /* Only generate class variables for the root of the inheritance
3904 hierarchy since these will be the same for every class. */
3906 if (CLASS_SUPER_NAME (implementation_template
) == NULL_TREE
3907 && (chain
= TYPE_FIELDS (objc_class_template
)))
3909 size
= list_length (chain
);
3911 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3912 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3914 UOBJC_CLASS_VARIABLES_decl
3915 = generate_ivars_list (ivar_list_template
, "_OBJC_CLASS_VARIABLES",
3917 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl
) = variable_length_type
;
3920 UOBJC_CLASS_VARIABLES_decl
= 0;
3922 chain
= CLASS_IVARS (implementation_template
);
3925 size
= list_length (chain
);
3926 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3927 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3929 UOBJC_INSTANCE_VARIABLES_decl
3930 = generate_ivars_list (ivar_list_template
, "_OBJC_INSTANCE_VARIABLES",
3932 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl
) = variable_length_type
;
3935 UOBJC_INSTANCE_VARIABLES_decl
= 0;
3937 generating_instance_variables
= 0;
3941 build_dispatch_table_initializer (type
, entries
)
3945 tree initlist
= NULL_TREE
;
3949 tree elemlist
= NULL_TREE
;
3951 elemlist
= tree_cons (NULL_TREE
,
3952 build_selector (METHOD_SEL_NAME (entries
)),
3955 elemlist
= tree_cons (NULL_TREE
,
3956 add_objc_string (METHOD_ENCODING (entries
),
3960 elemlist
= tree_cons (NULL_TREE
,
3961 build_unary_op (ADDR_EXPR
,
3962 METHOD_DEFINITION (entries
), 1),
3965 initlist
= tree_cons (NULL_TREE
,
3966 build_constructor (type
, nreverse (elemlist
)),
3969 entries
= TREE_CHAIN (entries
);
3973 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3976 /* To accomplish method prototyping without generating all kinds of
3977 inane warnings, the definition of the dispatch table entries were
3980 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3982 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3985 build_method_template ()
3988 tree decl_specs
, field_decl
, field_decl_chain
;
3990 _SLT_record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD
));
3992 #ifdef OBJC_INT_SELECTORS
3993 /* unsigned int _cmd; */
3994 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_UNSIGNED
],
3996 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_INT
], decl_specs
);
3997 field_decl
= get_identifier ("_cmd");
3998 #else /* not OBJC_INT_SELECTORS */
3999 /* struct objc_selector *_cmd; */
4000 decl_specs
= tree_cons (NULL_TREE
,
4001 xref_tag (RECORD_TYPE
,
4002 get_identifier (TAG_SELECTOR
)),
4004 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
4005 #endif /* not OBJC_INT_SELECTORS */
4007 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
4008 decl_specs
, NULL_TREE
);
4009 field_decl_chain
= field_decl
;
4011 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
4012 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
,
4013 get_identifier ("method_types"));
4014 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
4015 decl_specs
, NULL_TREE
);
4016 chainon (field_decl_chain
, field_decl
);
4020 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_VOID
], NULL_TREE
);
4021 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_imp"));
4022 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
4023 decl_specs
, NULL_TREE
);
4024 chainon (field_decl_chain
, field_decl
);
4026 finish_struct (_SLT_record
, field_decl_chain
, NULL_TREE
);
4033 generate_dispatch_table (type
, name
, size
, list
)
4039 tree sc_spec
, decl_specs
, decl
, initlist
;
4041 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4042 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
4044 decl
= start_decl (synth_id_with_class_suffix (name
, implementation_context
),
4045 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
4047 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
4048 initlist
= tree_cons (NULL_TREE
, build_int_2 (size
, 0), initlist
);
4049 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
4052 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
4059 generate_dispatch_tables ()
4061 tree initlist
, chain
, method_list_template
;
4062 tree cast
, variable_length_type
;
4065 if (!objc_method_template
)
4066 objc_method_template
= build_method_template ();
4070 (build_tree_list (NULL_TREE
,
4071 xref_tag (RECORD_TYPE
,
4072 get_identifier (UTAG_METHOD_LIST
))),
4075 variable_length_type
= groktypename (cast
);
4077 chain
= CLASS_CLS_METHODS (implementation_context
);
4080 size
= list_length (chain
);
4082 method_list_template
4083 = build_method_list_template (objc_method_template
, size
);
4085 = build_dispatch_table_initializer (objc_method_template
, chain
);
4087 UOBJC_CLASS_METHODS_decl
4088 = generate_dispatch_table (method_list_template
,
4089 ((TREE_CODE (implementation_context
)
4090 == CLASS_IMPLEMENTATION_TYPE
)
4091 ? "_OBJC_CLASS_METHODS"
4092 : "_OBJC_CATEGORY_CLASS_METHODS"),
4094 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
4097 UOBJC_CLASS_METHODS_decl
= 0;
4099 chain
= CLASS_NST_METHODS (implementation_context
);
4102 size
= list_length (chain
);
4104 method_list_template
4105 = build_method_list_template (objc_method_template
, size
);
4107 = build_dispatch_table_initializer (objc_method_template
, chain
);
4109 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
4110 UOBJC_INSTANCE_METHODS_decl
4111 = generate_dispatch_table (method_list_template
,
4112 "_OBJC_INSTANCE_METHODS",
4115 /* We have a category. */
4116 UOBJC_INSTANCE_METHODS_decl
4117 = generate_dispatch_table (method_list_template
,
4118 "_OBJC_CATEGORY_INSTANCE_METHODS",
4120 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
4123 UOBJC_INSTANCE_METHODS_decl
= 0;
4127 generate_protocol_list (i_or_p
)
4130 static tree cast_type
= 0;
4131 tree initlist
, decl_specs
, sc_spec
;
4132 tree refs_decl
, expr_decl
, lproto
, e
, plist
;
4135 if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
4136 || TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4137 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
4138 else if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4139 plist
= PROTOCOL_LIST (i_or_p
);
4147 (build_tree_list (NULL_TREE
,
4148 xref_tag (RECORD_TYPE
,
4149 get_identifier (UTAG_PROTOCOL
))),
4150 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
4153 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4154 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
4155 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
4158 /* Build initializer. */
4159 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), NULL_TREE
);
4161 e
= build_int_2 (size
, 0);
4162 TREE_TYPE (e
) = cast_type
;
4163 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4165 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4167 tree pval
= TREE_VALUE (lproto
);
4169 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
4170 && PROTOCOL_FORWARD_DECL (pval
))
4172 e
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (pval
), 0);
4173 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4177 /* static struct objc_protocol *refs[n]; */
4179 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4180 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
4181 get_identifier (UTAG_PROTOCOL
)),
4184 if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4185 expr_decl
= build_nt (ARRAY_REF
,
4186 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4188 build_int_2 (size
+ 2, 0));
4189 else if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
)
4190 expr_decl
= build_nt (ARRAY_REF
,
4191 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4193 build_int_2 (size
+ 2, 0));
4194 else if (TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4196 = build_nt (ARRAY_REF
,
4197 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4199 build_int_2 (size
+ 2, 0));
4201 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
4203 refs_decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
4205 finish_decl (refs_decl
, build_constructor (TREE_TYPE (refs_decl
),
4206 nreverse (initlist
)),
4213 build_category_initializer (type
, cat_name
, class_name
,
4214 instance_methods
, class_methods
, protocol_list
)
4218 tree instance_methods
;
4222 tree initlist
= NULL_TREE
, expr
;
4224 initlist
= tree_cons (NULL_TREE
, cat_name
, initlist
);
4225 initlist
= tree_cons (NULL_TREE
, class_name
, initlist
);
4227 if (!instance_methods
)
4228 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4231 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
4232 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4235 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4238 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
4239 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4242 /* protocol_list = */
4244 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4247 static tree cast_type2
;
4253 (build_tree_list (NULL_TREE
,
4254 xref_tag (RECORD_TYPE
,
4255 get_identifier (UTAG_PROTOCOL
))),
4256 build1 (INDIRECT_REF
, NULL_TREE
,
4257 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4259 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4260 TREE_TYPE (expr
) = cast_type2
;
4261 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4264 return build_constructor (type
, nreverse (initlist
));
4267 /* struct objc_class {
4268 struct objc_class *isa;
4269 struct objc_class *super_class;
4274 struct objc_ivar_list *ivars;
4275 struct objc_method_list *methods;
4276 if (flag_next_runtime)
4277 struct objc_cache *cache;
4279 struct sarray *dtable;
4280 struct objc_class *subclass_list;
4281 struct objc_class *sibling_class;
4283 struct objc_protocol_list *protocols;
4287 build_shared_structure_initializer (type
, isa
, super
, name
, size
, status
,
4288 dispatch_table
, ivar_list
, protocol_list
)
4295 tree dispatch_table
;
4299 tree initlist
= NULL_TREE
, expr
;
4302 initlist
= tree_cons (NULL_TREE
, isa
, initlist
);
4305 initlist
= tree_cons (NULL_TREE
, super
, initlist
);
4308 initlist
= tree_cons (NULL_TREE
, default_conversion (name
), initlist
);
4311 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4314 initlist
= tree_cons (NULL_TREE
, build_int_2 (status
, 0), initlist
);
4316 /* instance_size = */
4317 initlist
= tree_cons (NULL_TREE
, size
, initlist
);
4319 /* objc_ivar_list = */
4321 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4324 expr
= build_unary_op (ADDR_EXPR
, ivar_list
, 0);
4325 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4328 /* objc_method_list = */
4329 if (!dispatch_table
)
4330 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4333 expr
= build_unary_op (ADDR_EXPR
, dispatch_table
, 0);
4334 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4337 if (flag_next_runtime
)
4338 /* method_cache = */
4339 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4343 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4345 /* subclass_list = */
4346 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4348 /* sibling_class = */
4349 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4352 /* protocol_list = */
4353 if (! protocol_list
)
4354 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4357 static tree cast_type2
;
4363 (build_tree_list (NULL_TREE
,
4364 xref_tag (RECORD_TYPE
,
4365 get_identifier (UTAG_PROTOCOL
))),
4366 build1 (INDIRECT_REF
, NULL_TREE
,
4367 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4369 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4370 TREE_TYPE (expr
) = cast_type2
;
4371 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4374 return build_constructor (type
, nreverse (initlist
));
4377 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4380 generate_category (cat
)
4383 tree sc_spec
, decl_specs
, decl
;
4384 tree initlist
, cat_name_expr
, class_name_expr
;
4385 tree protocol_decl
, category
;
4387 add_class_reference (CLASS_NAME (cat
));
4388 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
4390 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
4392 category
= CLASS_CATEGORY_LIST (implementation_template
);
4394 /* find the category interface from the class it is associated with */
4397 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
4399 category
= CLASS_CATEGORY_LIST (category
);
4402 if (category
&& CLASS_PROTOCOL_LIST (category
))
4404 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
4405 protocol_decl
= generate_protocol_list (category
);
4410 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4411 decl_specs
= tree_cons (NULL_TREE
, objc_category_template
, sc_spec
);
4413 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4414 implementation_context
),
4415 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
4417 initlist
= build_category_initializer (TREE_TYPE (decl
),
4418 cat_name_expr
, class_name_expr
,
4419 UOBJC_INSTANCE_METHODS_decl
,
4420 UOBJC_CLASS_METHODS_decl
,
4423 TREE_USED (decl
) = 1;
4424 finish_decl (decl
, initlist
, NULL_TREE
);
4427 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4428 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4431 generate_shared_structures ()
4433 tree sc_spec
, decl_specs
, decl
;
4434 tree name_expr
, super_expr
, root_expr
;
4435 tree my_root_id
= NULL_TREE
, my_super_id
= NULL_TREE
;
4436 tree cast_type
, initlist
, protocol_decl
;
4438 my_super_id
= CLASS_SUPER_NAME (implementation_template
);
4441 add_class_reference (my_super_id
);
4443 /* Compute "my_root_id" - this is required for code generation.
4444 the "isa" for all meta class structures points to the root of
4445 the inheritance hierarchy (e.g. "__Object")... */
4446 my_root_id
= my_super_id
;
4449 tree my_root_int
= lookup_interface (my_root_id
);
4451 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
4452 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
4459 /* No super class. */
4460 my_root_id
= CLASS_NAME (implementation_template
);
4463 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
4464 objc_class_template
),
4465 build1 (INDIRECT_REF
,
4466 NULL_TREE
, NULL_TREE
)));
4468 name_expr
= add_objc_string (CLASS_NAME (implementation_template
),
4471 /* Install class `isa' and `super' pointers at runtime. */
4474 super_expr
= add_objc_string (my_super_id
, class_names
);
4475 super_expr
= build_c_cast (cast_type
, super_expr
); /* cast! */
4478 super_expr
= build_int_2 (0, 0);
4480 root_expr
= add_objc_string (my_root_id
, class_names
);
4481 root_expr
= build_c_cast (cast_type
, root_expr
); /* cast! */
4483 if (CLASS_PROTOCOL_LIST (implementation_template
))
4485 generate_protocol_references
4486 (CLASS_PROTOCOL_LIST (implementation_template
));
4487 protocol_decl
= generate_protocol_list (implementation_template
);
4492 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4494 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
4495 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
4497 decl
= start_decl (DECL_NAME (UOBJC_METACLASS_decl
), decl_specs
, 1,
4498 NULL_TREE
, NULL_TREE
);
4501 = build_shared_structure_initializer
4503 root_expr
, super_expr
, name_expr
,
4504 build_int_2 ((TREE_INT_CST_LOW (TYPE_SIZE (objc_class_template
))
4508 UOBJC_CLASS_METHODS_decl
,
4509 UOBJC_CLASS_VARIABLES_decl
,
4512 finish_decl (decl
, initlist
, NULL_TREE
);
4514 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4516 decl
= start_decl (DECL_NAME (UOBJC_CLASS_decl
), decl_specs
, 1,
4517 NULL_TREE
, NULL_TREE
);
4520 = build_shared_structure_initializer
4522 build_unary_op (ADDR_EXPR
, UOBJC_METACLASS_decl
, 0),
4523 super_expr
, name_expr
,
4526 (TYPE_SIZE (CLASS_STATIC_TEMPLATE (implementation_template
)))
4530 UOBJC_INSTANCE_METHODS_decl
,
4531 UOBJC_INSTANCE_VARIABLES_decl
,
4534 finish_decl (decl
, initlist
, NULL_TREE
);
4538 synth_id_with_class_suffix (preamble
, ctxt
)
4543 if (TREE_CODE (ctxt
) == CLASS_IMPLEMENTATION_TYPE
4544 || TREE_CODE (ctxt
) == CLASS_INTERFACE_TYPE
)
4547 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
4548 string
= (char *) alloca (strlen (preamble
) + strlen (class_name
) + 3);
4549 sprintf (string
, "%s_%s", preamble
,
4550 IDENTIFIER_POINTER (CLASS_NAME (ctxt
)));
4552 else if (TREE_CODE (ctxt
) == CATEGORY_IMPLEMENTATION_TYPE
4553 || TREE_CODE (ctxt
) == CATEGORY_INTERFACE_TYPE
)
4555 /* We have a category. */
4557 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
4558 char *class_super_name
4559 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
));
4560 string
= (char *) alloca (strlen (preamble
)
4561 + strlen (class_name
)
4562 + strlen (class_super_name
)
4564 sprintf (string
, "%s_%s_%s", preamble
, class_name
, class_super_name
);
4566 else if (TREE_CODE (ctxt
) == PROTOCOL_INTERFACE_TYPE
)
4568 char *protocol_name
= IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt
));
4570 = (char *) alloca (strlen (preamble
) + strlen (protocol_name
) + 3);
4571 sprintf (string
, "%s_%s", preamble
, protocol_name
);
4573 return get_identifier (string
);
4577 is_objc_type_qualifier (node
)
4580 return (TREE_CODE (node
) == IDENTIFIER_NODE
4581 && (node
== ridpointers
[(int) RID_CONST
]
4582 || node
== ridpointers
[(int) RID_VOLATILE
]
4583 || node
== ridpointers
[(int) RID_IN
]
4584 || node
== ridpointers
[(int) RID_OUT
]
4585 || node
== ridpointers
[(int) RID_INOUT
]
4586 || node
== ridpointers
[(int) RID_BYCOPY
]
4587 || node
== ridpointers
[(int) RID_ONEWAY
]));
4590 /* If type is empty or only type qualifiers are present, add default
4591 type of id (otherwise grokdeclarator will default to int). */
4594 adjust_type_for_id_default (type
)
4597 tree declspecs
, chain
;
4600 return build_tree_list (build_tree_list (NULL_TREE
, objc_object_reference
),
4601 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4603 declspecs
= TREE_PURPOSE (type
);
4605 /* Determine if a typespec is present. */
4606 for (chain
= declspecs
;
4608 chain
= TREE_CHAIN (chain
))
4610 if (!is_objc_type_qualifier (TREE_VALUE (chain
)))
4614 return build_tree_list (tree_cons (NULL_TREE
, objc_object_reference
,
4616 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4621 selector ':' '(' typename ')' identifier
4624 Transform an Objective-C keyword argument into
4625 the C equivalent parameter declarator.
4627 In: key_name, an "identifier_node" (optional).
4628 arg_type, a "tree_list" (optional).
4629 arg_name, an "identifier_node".
4631 Note: It would be really nice to strongly type the preceding
4632 arguments in the function prototype; however, then I
4633 could not use the "accessor" macros defined in "tree.h".
4635 Out: an instance of "keyword_decl". */
4638 build_keyword_decl (key_name
, arg_type
, arg_name
)
4645 /* If no type is specified, default to "id". */
4646 arg_type
= adjust_type_for_id_default (arg_type
);
4648 keyword_decl
= make_node (KEYWORD_DECL
);
4650 TREE_TYPE (keyword_decl
) = arg_type
;
4651 KEYWORD_ARG_NAME (keyword_decl
) = arg_name
;
4652 KEYWORD_KEY_NAME (keyword_decl
) = key_name
;
4654 return keyword_decl
;
4657 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4660 build_keyword_selector (selector
)
4664 tree key_chain
, key_name
;
4667 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4669 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4670 key_name
= KEYWORD_KEY_NAME (key_chain
);
4671 else if (TREE_CODE (selector
) == TREE_LIST
)
4672 key_name
= TREE_PURPOSE (key_chain
);
4675 len
+= IDENTIFIER_LENGTH (key_name
) + 1;
4677 /* Just a ':' arg. */
4681 buf
= (char *)alloca (len
+ 1);
4682 bzero (buf
, len
+ 1);
4684 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4686 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4687 key_name
= KEYWORD_KEY_NAME (key_chain
);
4688 else if (TREE_CODE (selector
) == TREE_LIST
)
4689 key_name
= TREE_PURPOSE (key_chain
);
4692 strcat (buf
, IDENTIFIER_POINTER (key_name
));
4696 return get_identifier (buf
);
4699 /* Used for declarations and definitions. */
4702 build_method_decl (code
, ret_type
, selector
, add_args
)
4703 enum tree_code code
;
4710 /* If no type is specified, default to "id". */
4711 ret_type
= adjust_type_for_id_default (ret_type
);
4713 method_decl
= make_node (code
);
4714 TREE_TYPE (method_decl
) = ret_type
;
4716 /* If we have a keyword selector, create an identifier_node that
4717 represents the full selector name (`:' included)... */
4718 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4720 METHOD_SEL_NAME (method_decl
) = build_keyword_selector (selector
);
4721 METHOD_SEL_ARGS (method_decl
) = selector
;
4722 METHOD_ADD_ARGS (method_decl
) = add_args
;
4726 METHOD_SEL_NAME (method_decl
) = selector
;
4727 METHOD_SEL_ARGS (method_decl
) = NULL_TREE
;
4728 METHOD_ADD_ARGS (method_decl
) = NULL_TREE
;
4734 #define METHOD_DEF 0
4735 #define METHOD_REF 1
4737 /* Used by `build_message_expr' and `comp_method_types'. Return an
4738 argument list for method METH. CONTEXT is either METHOD_DEF or
4739 METHOD_REF, saying whether we are trying to define a method or call
4740 one. SUPERFLAG says this is for a send to super; this makes a
4741 difference for the NeXT calling sequence in which the lookup and
4742 the method call are done together. */
4745 get_arg_type_list (meth
, context
, superflag
)
4752 /* Receiver type. */
4753 if (flag_next_runtime
&& superflag
)
4754 arglist
= build_tree_list (NULL_TREE
, super_type
);
4755 else if (context
== METHOD_DEF
)
4756 arglist
= build_tree_list (NULL_TREE
, TREE_TYPE (self_decl
));
4758 arglist
= build_tree_list (NULL_TREE
, id_type
);
4760 /* Selector type - will eventually change to `int'. */
4761 chainon (arglist
, build_tree_list (NULL_TREE
, selector_type
));
4763 /* Build a list of argument types. */
4764 for (akey
= METHOD_SEL_ARGS (meth
); akey
; akey
= TREE_CHAIN (akey
))
4766 tree arg_decl
= groktypename_in_parm_context (TREE_TYPE (akey
));
4767 chainon (arglist
, build_tree_list (NULL_TREE
, TREE_TYPE (arg_decl
)));
4770 if (METHOD_ADD_ARGS (meth
) == (tree
)1)
4771 /* We have a `, ...' immediately following the selector,
4772 finalize the arglist...simulate get_parm_info (0). */
4774 else if (METHOD_ADD_ARGS (meth
))
4776 /* we have a variable length selector */
4777 tree add_arg_list
= TREE_CHAIN (METHOD_ADD_ARGS (meth
));
4778 chainon (arglist
, add_arg_list
);
4781 /* finalize the arglist...simulate get_parm_info (1) */
4782 chainon (arglist
, build_tree_list (NULL_TREE
, void_type_node
));
4788 check_duplicates (hsh
)
4791 tree meth
= NULL_TREE
;
4799 /* We have two methods with the same name and different types. */
4801 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
) ? '-' : '+';
4803 warning ("multiple declarations for method `%s'",
4804 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
4806 warn_with_method ("using", type
, meth
);
4807 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
4808 warn_with_method ("also found", type
, loop
->value
);
4814 /* If RECEIVER is a class reference, return the identifier node for the
4815 referenced class. RECEIVER is created by get_class_reference, so we
4816 check the exact form created depending on which runtimes are used. */
4819 receiver_is_class_object (receiver
)
4822 tree chain
, exp
, arg
;
4823 if (flag_next_runtime
)
4825 /* The receiver is a variable created by build_class_reference_decl. */
4826 if (TREE_CODE (receiver
) == VAR_DECL
4827 && TREE_TYPE (receiver
) == objc_class_type
)
4828 /* Look up the identifier. */
4829 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
4830 if (TREE_PURPOSE (chain
) == receiver
)
4831 return TREE_VALUE (chain
);
4835 /* The receiver is a function call that returns an id. Check if
4836 it is a call to objc_getClass, if so, pick up the class name. */
4837 if ((exp
= TREE_OPERAND (receiver
, 0))
4838 && TREE_CODE (exp
) == ADDR_EXPR
4839 && (exp
= TREE_OPERAND (exp
, 0))
4840 && TREE_CODE (exp
) == FUNCTION_DECL
4841 && exp
== objc_get_class_decl
4842 /* we have a call to objc_getClass! */
4843 && (arg
= TREE_OPERAND (receiver
, 1))
4844 && TREE_CODE (arg
) == TREE_LIST
4845 && (arg
= TREE_VALUE (arg
)))
4848 if (TREE_CODE (arg
) == ADDR_EXPR
4849 && (arg
= TREE_OPERAND (arg
, 0))
4850 && TREE_CODE (arg
) == STRING_CST
)
4851 /* Finally, we have the class name. */
4852 return get_identifier (TREE_STRING_POINTER (arg
));
4858 /* If we are currently building a message expr, this holds
4859 the identifier of the selector of the message. This is
4860 used when printing warnings about argument mismatches. */
4862 static tree building_objc_message_expr
= 0;
4865 maybe_building_objc_message_expr ()
4867 return building_objc_message_expr
;
4870 /* Construct an expression for sending a message.
4871 MESS has the object to send to in TREE_PURPOSE
4872 and the argument list (including selector) in TREE_VALUE.
4874 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4875 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4878 build_message_expr (mess
)
4881 tree receiver
= TREE_PURPOSE (mess
);
4882 tree selector
, self_object
;
4883 tree rtype
, sel_name
;
4884 tree args
= TREE_VALUE (mess
);
4885 tree method_params
= NULL_TREE
;
4886 tree method_prototype
= NULL_TREE
;
4888 int statically_typed
= 0, statically_allocated
= 0;
4889 tree class_ident
= 0;
4891 /* 1 if this is sending to the superclass. */
4894 if (!doing_objc_thang
)
4897 if (TREE_CODE (receiver
) == ERROR_MARK
)
4898 return error_mark_node
;
4900 /* Determine receiver type. */
4901 rtype
= TREE_TYPE (receiver
);
4902 super
= IS_SUPER (rtype
);
4906 if (TREE_STATIC_TEMPLATE (rtype
))
4907 statically_allocated
= 1;
4908 else if (TREE_CODE (rtype
) == POINTER_TYPE
4909 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype
)))
4910 statically_typed
= 1;
4911 else if ((flag_next_runtime
4912 || (TREE_CODE (receiver
) == CALL_EXPR
&& IS_ID (rtype
)))
4913 && (class_ident
= receiver_is_class_object (receiver
)))
4915 else if (! IS_ID (rtype
)
4916 /* Allow any type that matches objc_class_type. */
4917 && ! comptypes (rtype
, objc_class_type
))
4919 bzero (errbuf
, BUFSIZE
);
4920 warning ("invalid receiver type `%s'",
4921 gen_declaration (rtype
, errbuf
));
4924 if (statically_allocated
)
4925 receiver
= build_unary_op (ADDR_EXPR
, receiver
, 0);
4927 /* Don't evaluate the receiver twice. */
4928 receiver
= save_expr (receiver
);
4929 self_object
= receiver
;
4932 /* If sending to `super', use current self as the object. */
4933 self_object
= self_decl
;
4935 /* Obtain the full selector name. */
4937 if (TREE_CODE (args
) == IDENTIFIER_NODE
)
4938 /* A unary selector. */
4940 else if (TREE_CODE (args
) == TREE_LIST
)
4941 sel_name
= build_keyword_selector (args
);
4943 /* Build the parameter list to give to the method. */
4945 method_params
= NULL_TREE
;
4946 if (TREE_CODE (args
) == TREE_LIST
)
4948 tree chain
= args
, prev
= NULL_TREE
;
4950 /* We have a keyword selector--check for comma expressions. */
4953 tree element
= TREE_VALUE (chain
);
4955 /* We have a comma expression, must collapse... */
4956 if (TREE_CODE (element
) == TREE_LIST
)
4959 TREE_CHAIN (prev
) = element
;
4964 chain
= TREE_CHAIN (chain
);
4966 method_params
= args
;
4969 /* Determine operation return type. */
4971 if (IS_SUPER (rtype
))
4975 if (CLASS_SUPER_NAME (implementation_template
))
4978 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
4980 if (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
)
4981 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4983 method_prototype
= lookup_class_method_static (iface
, sel_name
);
4985 if (iface
&& !method_prototype
)
4986 warning ("`%s' does not respond to `%s'",
4987 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template
)),
4988 IDENTIFIER_POINTER (sel_name
));
4992 error ("no super class declared in interface for `%s'",
4993 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
4994 return error_mark_node
;
4998 else if (statically_allocated
)
5000 tree ctype
= TREE_TYPE (rtype
);
5001 tree iface
= lookup_interface (TYPE_NAME (rtype
));
5004 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5006 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
5008 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
5011 if (!method_prototype
)
5012 warning ("`%s' does not respond to `%s'",
5013 IDENTIFIER_POINTER (TYPE_NAME (rtype
)),
5014 IDENTIFIER_POINTER (sel_name
));
5016 else if (statically_typed
)
5018 tree ctype
= TREE_TYPE (rtype
);
5020 /* `self' is now statically_typed. All methods should be visible
5021 within the context of the implementation. */
5022 if (implementation_context
5023 && CLASS_NAME (implementation_context
) == TYPE_NAME (ctype
))
5026 = lookup_instance_method_static (implementation_template
,
5029 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
5031 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
5034 if (! method_prototype
5035 && implementation_template
!= implementation_context
)
5036 /* The method is not published in the interface. Check
5039 = lookup_method (CLASS_NST_METHODS (implementation_context
),
5046 if ((iface
= lookup_interface (TYPE_NAME (ctype
))))
5047 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5049 if (! method_prototype
)
5051 tree protocol_list
= TYPE_PROTOCOL_LIST (ctype
);
5054 = lookup_method_in_protocol_list (protocol_list
,
5059 if (!method_prototype
)
5060 warning ("`%s' does not respond to `%s'",
5061 IDENTIFIER_POINTER (TYPE_NAME (ctype
)),
5062 IDENTIFIER_POINTER (sel_name
));
5064 else if (class_ident
)
5066 if (implementation_context
5067 && CLASS_NAME (implementation_context
) == class_ident
)
5070 = lookup_class_method_static (implementation_template
, sel_name
);
5072 if (!method_prototype
5073 && implementation_template
!= implementation_context
)
5074 /* The method is not published in the interface. Check
5077 = lookup_method (CLASS_CLS_METHODS (implementation_context
),
5084 if ((iface
= lookup_interface (class_ident
)))
5085 method_prototype
= lookup_class_method_static (iface
, sel_name
);
5088 if (!method_prototype
)
5090 warning ("cannot find class (factory) method.");
5091 warning ("return type for `%s' defaults to id",
5092 IDENTIFIER_POINTER (sel_name
));
5095 else if (IS_PROTOCOL_QUALIFIED_ID (rtype
))
5097 /* An anonymous object that has been qualified with a protocol. */
5099 tree protocol_list
= TYPE_PROTOCOL_LIST (rtype
);
5101 method_prototype
= lookup_method_in_protocol_list (protocol_list
,
5104 if (!method_prototype
)
5108 warning ("method `%s' not implemented by protocol.",
5109 IDENTIFIER_POINTER (sel_name
));
5111 /* Try and find the method signature in the global pools. */
5113 if (!(hsh
= hash_lookup (nst_method_hash_list
, sel_name
)))
5114 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5116 if (!(method_prototype
= check_duplicates (hsh
)))
5117 warning ("return type defaults to id");
5124 /* We think we have an instance...loophole: extern id Object; */
5125 hsh
= hash_lookup (nst_method_hash_list
, sel_name
);
5127 /* For various loopholes, like sending messages to self in a
5129 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5131 method_prototype
= check_duplicates (hsh
);
5132 if (!method_prototype
)
5134 warning ("cannot find method.");
5135 warning ("return type for `%s' defaults to id",
5136 IDENTIFIER_POINTER (sel_name
));
5140 /* Save the selector name for printing error messages. */
5141 building_objc_message_expr
= sel_name
;
5143 /* Build the parameters list for looking up the method.
5144 These are the object itself and the selector. */
5146 if (flag_typed_selectors
)
5147 selector
= build_typed_selector_reference (sel_name
, method_prototype
);
5149 selector
= build_selector_reference (sel_name
);
5151 retval
= build_objc_method_call (super
, method_prototype
,
5152 receiver
, self_object
,
5153 selector
, method_params
);
5155 building_objc_message_expr
= 0;
5160 /* Build a tree expression to send OBJECT the operation SELECTOR,
5161 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5162 assuming the method has prototype METHOD_PROTOTYPE.
5163 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5164 Use METHOD_PARAMS as list of args to pass to the method.
5165 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5168 build_objc_method_call (super_flag
, method_prototype
, lookup_object
, object
,
5169 selector
, method_params
)
5171 tree method_prototype
, lookup_object
, object
, selector
, method_params
;
5173 tree sender
= (super_flag
? umsg_super_decl
: umsg_decl
);
5174 tree rcv_p
= (super_flag
5175 ? build_pointer_type (xref_tag (RECORD_TYPE
,
5176 get_identifier (TAG_SUPER
)))
5179 if (flag_next_runtime
)
5181 if (! method_prototype
)
5183 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5184 tree_cons (NULL_TREE
, selector
,
5186 assemble_external (sender
);
5187 return build_function_call (sender
, method_params
);
5191 /* This is a real kludge, but it is used only for the Next.
5192 Clobber the data type of SENDER temporarily to accept
5193 all the arguments for this operation, and to return
5194 whatever this operation returns. */
5195 tree arglist
= NULL_TREE
;
5198 /* Save the proper contents of SENDER's data type. */
5199 tree savarg
= TYPE_ARG_TYPES (TREE_TYPE (sender
));
5200 tree savret
= TREE_TYPE (TREE_TYPE (sender
));
5202 /* Install this method's argument types. */
5203 arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5205 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = arglist
;
5207 /* Install this method's return type. */
5208 TREE_TYPE (TREE_TYPE (sender
))
5209 = groktypename (TREE_TYPE (method_prototype
));
5211 /* Call SENDER with all the parameters. This will do type
5212 checking using the arg types for this method. */
5213 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5214 tree_cons (NULL_TREE
, selector
,
5216 assemble_external (sender
);
5217 retval
= build_function_call (sender
, method_params
);
5219 /* Restore SENDER's return/argument types. */
5220 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = savarg
;
5221 TREE_TYPE (TREE_TYPE (sender
)) = savret
;
5227 /* This is the portable way.
5228 First call the lookup function to get a pointer to the method,
5229 then cast the pointer, then call it with the method arguments. */
5232 /* Avoid trouble since we may evaluate each of these twice. */
5233 object
= save_expr (object
);
5234 selector
= save_expr (selector
);
5236 lookup_object
= build_c_cast (rcv_p
, lookup_object
);
5238 assemble_external (sender
);
5240 = build_function_call (sender
,
5241 tree_cons (NULL_TREE
, lookup_object
,
5242 tree_cons (NULL_TREE
, selector
,
5245 /* If we have a method prototype, construct the data type this
5246 method needs, and cast what we got from SENDER into a pointer
5248 if (method_prototype
)
5250 tree arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5252 tree valtype
= groktypename (TREE_TYPE (method_prototype
));
5253 tree fake_function_type
= build_function_type (valtype
, arglist
);
5254 TREE_TYPE (method
) = build_pointer_type (fake_function_type
);
5258 = build_pointer_type (build_function_type (ptr_type_node
, NULL_TREE
));
5260 /* Pass the object to the method. */
5261 assemble_external (method
);
5262 return build_function_call (method
,
5263 tree_cons (NULL_TREE
, object
,
5264 tree_cons (NULL_TREE
, selector
,
5270 build_protocol_reference (p
)
5273 tree decl
, ident
, ptype
;
5275 push_obstacks_nochange ();
5276 end_temporary_allocation ();
5278 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5280 ident
= synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
);
5282 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
5283 objc_protocol_template
),
5286 if (IDENTIFIER_GLOBAL_VALUE (ident
))
5287 decl
= IDENTIFIER_GLOBAL_VALUE (ident
); /* Set by pushdecl. */
5290 decl
= build_decl (VAR_DECL
, ident
, ptype
);
5291 DECL_EXTERNAL (decl
) = 1;
5292 TREE_PUBLIC (decl
) = 1;
5293 TREE_USED (decl
) = 1;
5294 DECL_ARTIFICIAL (decl
) = 1;
5296 make_decl_rtl (decl
, 0, 1);
5297 pushdecl_top_level (decl
);
5300 PROTOCOL_FORWARD_DECL (p
) = decl
;
5305 build_protocol_expr (protoname
)
5311 if (!doing_objc_thang
)
5314 p
= lookup_protocol (protoname
);
5318 error ("Cannot find protocol declaration for `%s'",
5319 IDENTIFIER_POINTER (protoname
));
5320 return error_mark_node
;
5323 if (!PROTOCOL_FORWARD_DECL (p
))
5324 build_protocol_reference (p
);
5326 expr
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
5328 TREE_TYPE (expr
) = protocol_type
;
5334 build_selector_expr (selnamelist
)
5339 if (!doing_objc_thang
)
5342 /* Obtain the full selector name. */
5343 if (TREE_CODE (selnamelist
) == IDENTIFIER_NODE
)
5344 /* A unary selector. */
5345 selname
= selnamelist
;
5346 else if (TREE_CODE (selnamelist
) == TREE_LIST
)
5347 selname
= build_keyword_selector (selnamelist
);
5349 if (flag_typed_selectors
)
5350 return build_typed_selector_reference (selname
, 0);
5352 return build_selector_reference (selname
);
5356 build_encode_expr (type
)
5362 if (!doing_objc_thang
)
5365 encode_type (type
, obstack_object_size (&util_obstack
),
5366 OBJC_ENCODE_INLINE_DEFS
);
5367 obstack_1grow (&util_obstack
, 0); /* null terminate string */
5368 string
= obstack_finish (&util_obstack
);
5370 /* Synthesize a string that represents the encoded struct/union. */
5371 result
= my_build_string (strlen (string
) + 1, string
);
5372 obstack_free (&util_obstack
, util_firstobj
);
5377 build_ivar_reference (id
)
5380 if (TREE_CODE (method_context
) == CLASS_METHOD_DECL
)
5382 /* Historically, a class method that produced objects (factory
5383 method) would assign `self' to the instance that it
5384 allocated. This would effectively turn the class method into
5385 an instance method. Following this assignment, the instance
5386 variables could be accessed. That practice, while safe,
5387 violates the simple rule that a class method should not refer
5388 to an instance variable. It's better to catch the cases
5389 where this is done unknowingly than to support the above
5391 warning ("instance variable `%s' accessed in class method",
5392 IDENTIFIER_POINTER (id
));
5393 TREE_TYPE (self_decl
) = instance_type
; /* cast */
5396 return build_component_ref (build_indirect_ref (self_decl
, "->"), id
);
5399 #define HASH_ALLOC_LIST_SIZE 170
5400 #define ATTR_ALLOC_LIST_SIZE 170
5401 #define SIZEHASHTABLE 257
5404 #define HASHFUNCTION(key) ((HOST_WIDE_INT) key & 0x7fffffff)
5409 nst_method_hash_list
= (hash
*)xmalloc (SIZEHASHTABLE
* sizeof (hash
));
5410 cls_method_hash_list
= (hash
*)xmalloc (SIZEHASHTABLE
* sizeof (hash
));
5412 if (!nst_method_hash_list
|| !cls_method_hash_list
)
5413 perror ("unable to allocate space in objc-tree.c");
5418 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
5420 nst_method_hash_list
[i
] = 0;
5421 cls_method_hash_list
[i
] = 0;
5427 hash_enter (hashlist
, method
)
5431 static hash hash_alloc_list
= 0;
5432 static int hash_alloc_index
= 0;
5434 int slot
= HASHFUNCTION (METHOD_SEL_NAME (method
)) % SIZEHASHTABLE
;
5436 if (! hash_alloc_list
|| hash_alloc_index
>= HASH_ALLOC_LIST_SIZE
)
5438 hash_alloc_index
= 0;
5439 hash_alloc_list
= (hash
) xmalloc (sizeof (struct hashed_entry
)
5440 * HASH_ALLOC_LIST_SIZE
);
5441 if (! hash_alloc_list
)
5442 perror ("unable to allocate in objc-tree.c");
5444 obj
= &hash_alloc_list
[hash_alloc_index
++];
5446 obj
->next
= hashlist
[slot
];
5449 hashlist
[slot
] = obj
; /* append to front */
5453 hash_lookup (hashlist
, sel_name
)
5459 target
= hashlist
[HASHFUNCTION (sel_name
) % SIZEHASHTABLE
];
5463 if (sel_name
== METHOD_SEL_NAME (target
->key
))
5466 target
= target
->next
;
5472 hash_add_attr (entry
, value
)
5476 static attr attr_alloc_list
= 0;
5477 static int attr_alloc_index
= 0;
5480 if (! attr_alloc_list
|| attr_alloc_index
>= ATTR_ALLOC_LIST_SIZE
)
5482 attr_alloc_index
= 0;
5483 attr_alloc_list
= (attr
) xmalloc (sizeof (struct hashed_attribute
)
5484 * ATTR_ALLOC_LIST_SIZE
);
5485 if (! attr_alloc_list
)
5486 perror ("unable to allocate in objc-tree.c");
5488 obj
= &attr_alloc_list
[attr_alloc_index
++];
5489 obj
->next
= entry
->list
;
5492 entry
->list
= obj
; /* append to front */
5496 lookup_method (mchain
, method
)
5502 if (TREE_CODE (method
) == IDENTIFIER_NODE
)
5505 key
= METHOD_SEL_NAME (method
);
5509 if (METHOD_SEL_NAME (mchain
) == key
)
5511 mchain
= TREE_CHAIN (mchain
);
5517 lookup_instance_method_static (interface
, ident
)
5521 tree inter
= interface
;
5522 tree chain
= CLASS_NST_METHODS (inter
);
5523 tree meth
= NULL_TREE
;
5527 if ((meth
= lookup_method (chain
, ident
)))
5530 if (CLASS_CATEGORY_LIST (inter
))
5532 tree category
= CLASS_CATEGORY_LIST (inter
);
5533 chain
= CLASS_NST_METHODS (category
);
5537 if ((meth
= lookup_method (chain
, ident
)))
5540 /* Check for instance methods in protocols in categories. */
5541 if (CLASS_PROTOCOL_LIST (category
))
5543 if ((meth
= (lookup_method_in_protocol_list
5544 (CLASS_PROTOCOL_LIST (category
), ident
, 0))))
5548 if ((category
= CLASS_CATEGORY_LIST (category
)))
5549 chain
= CLASS_NST_METHODS (category
);
5554 if (CLASS_PROTOCOL_LIST (inter
))
5556 if ((meth
= (lookup_method_in_protocol_list
5557 (CLASS_PROTOCOL_LIST (inter
), ident
, 0))))
5561 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5562 chain
= CLASS_NST_METHODS (inter
);
5570 lookup_class_method_static (interface
, ident
)
5574 tree inter
= interface
;
5575 tree chain
= CLASS_CLS_METHODS (inter
);
5576 tree meth
= NULL_TREE
;
5577 tree root_inter
= NULL_TREE
;
5581 if ((meth
= lookup_method (chain
, ident
)))
5584 if (CLASS_CATEGORY_LIST (inter
))
5586 tree category
= CLASS_CATEGORY_LIST (inter
);
5587 chain
= CLASS_CLS_METHODS (category
);
5591 if ((meth
= lookup_method (chain
, ident
)))
5594 /* Check for class methods in protocols in categories. */
5595 if (CLASS_PROTOCOL_LIST (category
))
5597 if ((meth
= (lookup_method_in_protocol_list
5598 (CLASS_PROTOCOL_LIST (category
), ident
, 1))))
5602 if ((category
= CLASS_CATEGORY_LIST (category
)))
5603 chain
= CLASS_CLS_METHODS (category
);
5608 /* Check for class methods in protocols. */
5609 if (CLASS_PROTOCOL_LIST (inter
))
5611 if ((meth
= (lookup_method_in_protocol_list
5612 (CLASS_PROTOCOL_LIST (inter
), ident
, 1))))
5617 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5618 chain
= CLASS_CLS_METHODS (inter
);
5622 /* Simulate wrap around. */
5623 return lookup_instance_method_static (root_inter
, ident
);
5627 add_class_method (class, method
)
5634 /* We will have allocated the method parameter declarations on the
5635 maybepermanent_obstack. Need to make sure they stick around! */
5638 if (!(mth
= lookup_method (CLASS_CLS_METHODS (class), method
)))
5640 /* put method on list in reverse order */
5641 TREE_CHAIN (method
) = CLASS_CLS_METHODS (class);
5642 CLASS_CLS_METHODS (class) = method
;
5646 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5647 error ("duplicate definition of class method `%s'.",
5648 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5651 /* Check types; if different, complain. */
5652 if (!comp_proto_with_proto (method
, mth
))
5653 error ("duplicate declaration of class method `%s'.",
5654 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5658 if (!(hsh
= hash_lookup (cls_method_hash_list
, METHOD_SEL_NAME (method
))))
5660 /* Install on a global chain. */
5661 hash_enter (cls_method_hash_list
, method
);
5665 /* Check types; if different, add to a list. */
5666 if (!comp_proto_with_proto (method
, hsh
->key
))
5667 hash_add_attr (hsh
, method
);
5673 add_instance_method (class, method
)
5680 /* We will have allocated the method parameter declarations on the
5681 maybepermanent_obstack. Need to make sure they stick around! */
5684 if (!(mth
= lookup_method (CLASS_NST_METHODS (class), method
)))
5686 /* Put method on list in reverse order. */
5687 TREE_CHAIN (method
) = CLASS_NST_METHODS (class);
5688 CLASS_NST_METHODS (class) = method
;
5692 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5693 error ("duplicate definition of instance method `%s'.",
5694 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5697 /* Check types; if different, complain. */
5698 if (!comp_proto_with_proto (method
, mth
))
5699 error ("duplicate declaration of instance method `%s'.",
5700 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5704 if (!(hsh
= hash_lookup (nst_method_hash_list
, METHOD_SEL_NAME (method
))))
5706 /* Install on a global chain. */
5707 hash_enter (nst_method_hash_list
, method
);
5711 /* Check types; if different, add to a list. */
5712 if (!comp_proto_with_proto (method
, hsh
->key
))
5713 hash_add_attr (hsh
, method
);
5722 /* Put interfaces on list in reverse order. */
5723 TREE_CHAIN (class) = interface_chain
;
5724 interface_chain
= class;
5725 return interface_chain
;
5729 add_category (class, category
)
5733 /* Put categories on list in reverse order. */
5734 tree cat
= CLASS_CATEGORY_LIST (class);
5738 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
5739 warning ("duplicate interface declaration for category `%s(%s)'",
5740 IDENTIFIER_POINTER (CLASS_NAME (class)),
5741 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category
)));
5742 cat
= CLASS_CATEGORY_LIST (cat
);
5745 CLASS_CATEGORY_LIST (category
) = CLASS_CATEGORY_LIST (class);
5746 CLASS_CATEGORY_LIST (class) = category
;
5749 /* Called after parsing each instance variable declaration. Necessary to
5750 preserve typedefs and implement public/private...
5752 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5755 add_instance_variable (class, public, declarator
, declspecs
, width
)
5762 tree field_decl
, raw_decl
;
5764 raw_decl
= build_tree_list (declspecs
, declarator
);
5766 if (CLASS_RAW_IVARS (class))
5767 chainon (CLASS_RAW_IVARS (class), raw_decl
);
5769 CLASS_RAW_IVARS (class) = raw_decl
;
5771 field_decl
= grokfield (input_filename
, lineno
,
5772 declarator
, declspecs
, width
);
5774 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5778 TREE_PUBLIC (field_decl
) = 0;
5779 TREE_PRIVATE (field_decl
) = 0;
5780 TREE_PROTECTED (field_decl
) = 1;
5784 TREE_PUBLIC (field_decl
) = 1;
5785 TREE_PRIVATE (field_decl
) = 0;
5786 TREE_PROTECTED (field_decl
) = 0;
5790 TREE_PUBLIC (field_decl
) = 0;
5791 TREE_PRIVATE (field_decl
) = 1;
5792 TREE_PROTECTED (field_decl
) = 0;
5797 if (CLASS_IVARS (class))
5798 chainon (CLASS_IVARS (class), field_decl
);
5800 CLASS_IVARS (class) = field_decl
;
5806 is_ivar (decl_chain
, ident
)
5810 for ( ; decl_chain
; decl_chain
= TREE_CHAIN (decl_chain
))
5811 if (DECL_NAME (decl_chain
) == ident
)
5816 /* True if the ivar is private and we are not in its implementation. */
5822 if (TREE_PRIVATE (decl
)
5823 && ! is_ivar (CLASS_IVARS (implementation_template
), DECL_NAME (decl
)))
5825 error ("instance variable `%s' is declared private",
5826 IDENTIFIER_POINTER (DECL_NAME (decl
)));
5833 /* We have an instance variable reference;, check to see if it is public. */
5836 is_public (expr
, identifier
)
5840 tree basetype
= TREE_TYPE (expr
);
5841 enum tree_code code
= TREE_CODE (basetype
);
5844 if (code
== RECORD_TYPE
)
5846 if (TREE_STATIC_TEMPLATE (basetype
))
5848 if (!lookup_interface (TYPE_NAME (basetype
)))
5850 error ("Cannot find interface declaration for `%s'",
5851 IDENTIFIER_POINTER (TYPE_NAME (basetype
)));
5855 if ((decl
= is_ivar (TYPE_FIELDS (basetype
), identifier
)))
5857 if (TREE_PUBLIC (decl
))
5860 /* Important difference between the Stepstone translator:
5861 all instance variables should be public within the context
5862 of the implementation. */
5863 if (implementation_context
5864 && (((TREE_CODE (implementation_context
)
5865 == CLASS_IMPLEMENTATION_TYPE
)
5866 || (TREE_CODE (implementation_context
)
5867 == CATEGORY_IMPLEMENTATION_TYPE
))
5868 && (CLASS_NAME (implementation_context
)
5869 == TYPE_NAME (basetype
))))
5870 return ! is_private (decl
);
5872 error ("instance variable `%s' is declared %s",
5873 IDENTIFIER_POINTER (identifier
),
5874 TREE_PRIVATE (decl
) ? "private" : "protected");
5879 else if (implementation_context
&& (basetype
== objc_object_reference
))
5881 TREE_TYPE (expr
) = uprivate_record
;
5882 warning ("static access to object of type `id'");
5889 /* Implement @defs (<classname>) within struct bodies. */
5892 get_class_ivars (interface
)
5895 if (!doing_objc_thang
)
5898 return build_ivar_chain (interface
, 1);
5901 /* Make sure all entries in CHAIN are also in LIST. */
5904 check_methods (chain
, list
, mtype
)
5913 if (!lookup_method (list
, chain
))
5917 if (TREE_CODE (implementation_context
)
5918 == CLASS_IMPLEMENTATION_TYPE
)
5919 warning ("incomplete implementation of class `%s'",
5920 IDENTIFIER_POINTER (CLASS_NAME (implementation_context
)));
5921 else if (TREE_CODE (implementation_context
)
5922 == CATEGORY_IMPLEMENTATION_TYPE
)
5923 warning ("incomplete implementation of category `%s'",
5924 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
5928 warning ("method definition for `%c%s' not found",
5929 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
5932 chain
= TREE_CHAIN (chain
);
5939 conforms_to_protocol (class, protocol
)
5945 tree p
= CLASS_PROTOCOL_LIST (class);
5947 while (p
&& TREE_VALUE (p
) != TREE_VALUE (protocol
))
5952 tree super
= (CLASS_SUPER_NAME (class)
5953 ? lookup_interface (CLASS_SUPER_NAME (class))
5955 int tmp
= super
? conforms_to_protocol (super
, protocol
) : 0;
5960 protocol
= TREE_CHAIN (protocol
);
5966 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5967 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5970 check_methods_accessible (chain
, context
, mtype
)
5977 tree base_context
= context
;
5981 context
= base_context
;
5985 list
= CLASS_CLS_METHODS (context
);
5987 list
= CLASS_NST_METHODS (context
);
5989 if (lookup_method (list
, chain
))
5992 else if (TREE_CODE (context
) == CLASS_IMPLEMENTATION_TYPE
5993 || TREE_CODE (context
) == CLASS_INTERFACE_TYPE
)
5994 context
= (CLASS_SUPER_NAME (context
)
5995 ? lookup_interface (CLASS_SUPER_NAME (context
))
5998 else if (TREE_CODE (context
) == CATEGORY_IMPLEMENTATION_TYPE
5999 || TREE_CODE (context
) == CATEGORY_INTERFACE_TYPE
)
6000 context
= (CLASS_NAME (context
)
6001 ? lookup_interface (CLASS_NAME (context
))
6007 if (context
== NULL_TREE
)
6011 if (TREE_CODE (implementation_context
)
6012 == CLASS_IMPLEMENTATION_TYPE
)
6013 warning ("incomplete implementation of class `%s'",
6015 (CLASS_NAME (implementation_context
)));
6016 else if (TREE_CODE (implementation_context
)
6017 == CATEGORY_IMPLEMENTATION_TYPE
)
6018 warning ("incomplete implementation of category `%s'",
6020 (CLASS_SUPER_NAME (implementation_context
)));
6023 warning ("method definition for `%c%s' not found",
6024 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
6027 chain
= TREE_CHAIN (chain
); /* next method... */
6033 check_protocols (proto_list
, type
, name
)
6038 for ( ; proto_list
; proto_list
= TREE_CHAIN (proto_list
))
6040 tree p
= TREE_VALUE (proto_list
);
6042 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
6046 /* Ensure that all protocols have bodies. */
6047 if (flag_warn_protocol
) {
6048 f1
= check_methods (PROTOCOL_CLS_METHODS (p
),
6049 CLASS_CLS_METHODS (implementation_context
),
6051 f2
= check_methods (PROTOCOL_NST_METHODS (p
),
6052 CLASS_NST_METHODS (implementation_context
),
6055 f1
= check_methods_accessible (PROTOCOL_CLS_METHODS (p
),
6056 implementation_context
,
6058 f2
= check_methods_accessible (PROTOCOL_NST_METHODS (p
),
6059 implementation_context
,
6064 warning ("%s `%s' does not fully implement the `%s' protocol",
6065 type
, name
, IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
6070 ; /* An identifier if we could not find a protocol. */
6073 /* Check protocols recursively. */
6074 if (PROTOCOL_LIST (p
))
6077 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
6078 if (! conforms_to_protocol (super_class
, PROTOCOL_LIST (p
)))
6079 check_protocols (PROTOCOL_LIST (p
), type
, name
);
6084 /* Make sure that the class CLASS_NAME is defined
6085 CODE says which kind of thing CLASS_NAME ought to be.
6086 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6087 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE.
6089 If CODE is CLASS_INTERFACE_TYPE, we also do a push_obstacks_nochange
6090 whose matching pop is in continue_class. */
6093 start_class (code
, class_name
, super_name
, protocol_list
)
6094 enum tree_code code
;
6101 if (code
== CLASS_INTERFACE_TYPE
)
6103 push_obstacks_nochange ();
6104 end_temporary_allocation ();
6107 if (!doing_objc_thang
)
6110 class = make_node (code
);
6111 TYPE_BINFO (class) = make_tree_vec (5);
6113 CLASS_NAME (class) = class_name
;
6114 CLASS_SUPER_NAME (class) = super_name
;
6115 CLASS_CLS_METHODS (class) = NULL_TREE
;
6117 if (! is_class_name (class_name
) && (decl
= lookup_name (class_name
)))
6119 error ("`%s' redeclared as different kind of symbol",
6120 IDENTIFIER_POINTER (class_name
));
6121 error_with_decl (decl
, "previous declaration of `%s'");
6124 if (code
== CLASS_IMPLEMENTATION_TYPE
)
6127 static tree implemented_classes
= 0;
6128 tree chain
= implemented_classes
;
6129 for (chain
= implemented_classes
; chain
; chain
= TREE_CHAIN (chain
))
6130 if (TREE_VALUE (chain
) == class_name
)
6132 error ("reimplementation of class `%s'",
6133 IDENTIFIER_POINTER (class_name
));
6134 return error_mark_node
;
6136 implemented_classes
= perm_tree_cons (NULL_TREE
, class_name
,
6137 implemented_classes
);
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 implementation_context
= class;
6156 /* Lookup the interface for this implementation. */
6158 if (!(implementation_template
= lookup_interface (class_name
)))
6160 warning ("Cannot find interface declaration for `%s'",
6161 IDENTIFIER_POINTER (class_name
));
6162 add_class (implementation_template
= implementation_context
);
6165 /* If a super class has been specified in the implementation,
6166 insure it conforms to the one specified in the interface. */
6169 && (super_name
!= CLASS_SUPER_NAME (implementation_template
)))
6171 tree previous_name
= CLASS_SUPER_NAME (implementation_template
);
6172 char *name
= previous_name
? IDENTIFIER_POINTER (previous_name
) : "";
6173 error ("conflicting super class name `%s'",
6174 IDENTIFIER_POINTER (super_name
));
6175 error ("previous declaration of `%s'", name
);
6178 else if (! super_name
)
6180 CLASS_SUPER_NAME (implementation_context
)
6181 = CLASS_SUPER_NAME (implementation_template
);
6185 else if (code
== CLASS_INTERFACE_TYPE
)
6187 if (lookup_interface (class_name
))
6188 warning ("duplicate interface declaration for class `%s'",
6189 IDENTIFIER_POINTER (class_name
));
6194 CLASS_PROTOCOL_LIST (class)
6195 = lookup_and_install_protocols (protocol_list
);
6198 else if (code
== CATEGORY_INTERFACE_TYPE
)
6200 tree class_category_is_assoc_with
;
6202 /* For a category, class_name is really the name of the class that
6203 the following set of methods will be associated with. We must
6204 find the interface so that can derive the objects template. */
6206 if (!(class_category_is_assoc_with
= lookup_interface (class_name
)))
6208 error ("Cannot find interface declaration for `%s'",
6209 IDENTIFIER_POINTER (class_name
));
6210 exit (FATAL_EXIT_CODE
);
6213 add_category (class_category_is_assoc_with
, class);
6216 CLASS_PROTOCOL_LIST (class)
6217 = lookup_and_install_protocols (protocol_list
);
6220 else if (code
== CATEGORY_IMPLEMENTATION_TYPE
)
6222 /* Pre-build the following entities for speed/convenience. */
6224 self_id
= get_identifier ("self");
6226 ucmd_id
= get_identifier ("_cmd");
6229 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6230 if (!objc_super_template
)
6231 objc_super_template
= build_super_template ();
6233 /* Reset for multiple classes per file. */
6236 implementation_context
= class;
6238 /* For a category, class_name is really the name of the class that
6239 the following set of methods will be associated with. We must
6240 find the interface so that can derive the objects template. */
6242 if (!(implementation_template
= lookup_interface (class_name
)))
6244 error ("Cannot find interface declaration for `%s'",
6245 IDENTIFIER_POINTER (class_name
));
6246 exit (FATAL_EXIT_CODE
);
6253 continue_class (class)
6256 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6257 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6259 struct imp_entry
*imp_entry
;
6262 /* Check consistency of the instance variables. */
6264 if (CLASS_IVARS (class))
6265 check_ivars (implementation_template
, class);
6267 /* code generation */
6269 ivar_context
= build_private_template (implementation_template
);
6271 if (!objc_class_template
)
6272 build_class_template ();
6275 = (struct imp_entry
*) xmalloc (sizeof (struct imp_entry
))))
6276 perror ("unable to allocate in objc-tree.c");
6278 imp_entry
->next
= imp_list
;
6279 imp_entry
->imp_context
= class;
6280 imp_entry
->imp_template
= implementation_template
;
6282 synth_forward_declarations ();
6283 imp_entry
->class_decl
= UOBJC_CLASS_decl
;
6284 imp_entry
->meta_decl
= UOBJC_METACLASS_decl
;
6286 /* Append to front and increment count. */
6287 imp_list
= imp_entry
;
6288 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6293 return ivar_context
;
6296 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6298 tree record
= xref_tag (RECORD_TYPE
, CLASS_NAME (class));
6300 if (!TYPE_FIELDS (record
))
6302 finish_struct (record
, build_ivar_chain (class, 0), NULL_TREE
);
6303 CLASS_STATIC_TEMPLATE (class) = record
;
6305 /* Mark this record as a class template for static typing. */
6306 TREE_STATIC_TEMPLATE (record
) = 1;
6313 return error_mark_node
;
6316 /* This is called once we see the "@end" in an interface/implementation. */
6319 finish_class (class)
6322 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6324 /* All code generation is done in finish_objc. */
6326 if (implementation_template
!= implementation_context
)
6328 /* Ensure that all method listed in the interface contain bodies. */
6329 check_methods (CLASS_CLS_METHODS (implementation_template
),
6330 CLASS_CLS_METHODS (implementation_context
), '+');
6331 check_methods (CLASS_NST_METHODS (implementation_template
),
6332 CLASS_NST_METHODS (implementation_context
), '-');
6334 if (CLASS_PROTOCOL_LIST (implementation_template
))
6335 check_protocols (CLASS_PROTOCOL_LIST (implementation_template
),
6337 IDENTIFIER_POINTER (CLASS_NAME (implementation_context
)));
6341 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6343 tree category
= CLASS_CATEGORY_LIST (implementation_template
);
6345 /* Find the category interface from the class it is associated with. */
6348 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category
))
6350 category
= CLASS_CATEGORY_LIST (category
);
6355 /* Ensure all method listed in the interface contain bodies. */
6356 check_methods (CLASS_CLS_METHODS (category
),
6357 CLASS_CLS_METHODS (implementation_context
), '+');
6358 check_methods (CLASS_NST_METHODS (category
),
6359 CLASS_NST_METHODS (implementation_context
), '-');
6361 if (CLASS_PROTOCOL_LIST (category
))
6362 check_protocols (CLASS_PROTOCOL_LIST (category
),
6364 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
6368 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6371 char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (class));
6372 char *string
= (char *) alloca (strlen (class_name
) + 3);
6374 /* extern struct objc_object *_<my_name>; */
6376 sprintf (string
, "_%s", class_name
);
6378 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
6379 decl_specs
= tree_cons (NULL_TREE
, objc_object_reference
, decl_specs
);
6380 define_decl (build1 (INDIRECT_REF
, NULL_TREE
, get_identifier (string
)),
6386 add_protocol (protocol
)
6389 /* Put protocol on list in reverse order. */
6390 TREE_CHAIN (protocol
) = protocol_chain
;
6391 protocol_chain
= protocol
;
6392 return protocol_chain
;
6396 lookup_protocol (ident
)
6401 for (chain
= protocol_chain
; chain
; chain
= TREE_CHAIN (chain
))
6403 if (ident
== PROTOCOL_NAME (chain
))
6411 start_protocol (code
, name
, list
)
6412 enum tree_code code
;
6418 if (!doing_objc_thang
)
6421 /* This is as good a place as any. Need to invoke push_tag_toplevel. */
6422 if (!objc_protocol_template
)
6423 objc_protocol_template
= build_protocol_template ();
6425 protocol
= make_node (code
);
6426 TYPE_BINFO (protocol
) = make_tree_vec (2);
6428 PROTOCOL_NAME (protocol
) = name
;
6429 PROTOCOL_LIST (protocol
) = list
;
6431 lookup_and_install_protocols (list
);
6433 if (lookup_protocol (name
))
6434 warning ("duplicate declaration for protocol `%s'",
6435 IDENTIFIER_POINTER (name
));
6437 add_protocol (protocol
);
6439 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6445 finish_protocol (protocol
)
6446 tree protocol ATTRIBUTE_UNUSED
;
6451 /* "Encode" a data type into a string, which grows in util_obstack.
6452 ??? What is the FORMAT? Someone please document this! */
6455 encode_type_qualifiers (declspecs
)
6460 for (spec
= declspecs
; spec
; spec
= TREE_CHAIN (spec
))
6462 if (ridpointers
[(int) RID_CONST
] == TREE_VALUE (spec
))
6463 obstack_1grow (&util_obstack
, 'r');
6464 else if (ridpointers
[(int) RID_IN
] == TREE_VALUE (spec
))
6465 obstack_1grow (&util_obstack
, 'n');
6466 else if (ridpointers
[(int) RID_INOUT
] == TREE_VALUE (spec
))
6467 obstack_1grow (&util_obstack
, 'N');
6468 else if (ridpointers
[(int) RID_OUT
] == TREE_VALUE (spec
))
6469 obstack_1grow (&util_obstack
, 'o');
6470 else if (ridpointers
[(int) RID_BYCOPY
] == TREE_VALUE (spec
))
6471 obstack_1grow (&util_obstack
, 'O');
6472 else if (ridpointers
[(int) RID_ONEWAY
] == TREE_VALUE (spec
))
6473 obstack_1grow (&util_obstack
, 'V');
6477 /* Encode a pointer type. */
6480 encode_pointer (type
, curtype
, format
)
6485 tree pointer_to
= TREE_TYPE (type
);
6487 if (TREE_CODE (pointer_to
) == RECORD_TYPE
)
6489 if (TYPE_NAME (pointer_to
)
6490 && TREE_CODE (TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
)
6492 char *name
= IDENTIFIER_POINTER (TYPE_NAME (pointer_to
));
6494 if (strcmp (name
, TAG_OBJECT
) == 0) /* '@' */
6496 obstack_1grow (&util_obstack
, '@');
6499 else if (TREE_STATIC_TEMPLATE (pointer_to
))
6501 if (generating_instance_variables
)
6503 obstack_1grow (&util_obstack
, '@');
6504 obstack_1grow (&util_obstack
, '"');
6505 obstack_grow (&util_obstack
, name
, strlen (name
));
6506 obstack_1grow (&util_obstack
, '"');
6511 obstack_1grow (&util_obstack
, '@');
6515 else if (strcmp (name
, TAG_CLASS
) == 0) /* '#' */
6517 obstack_1grow (&util_obstack
, '#');
6520 #ifndef OBJC_INT_SELECTORS
6521 else if (strcmp (name
, TAG_SELECTOR
) == 0) /* ':' */
6523 obstack_1grow (&util_obstack
, ':');
6526 #endif /* OBJC_INT_SELECTORS */
6529 else if (TREE_CODE (pointer_to
) == INTEGER_TYPE
6530 && TYPE_MODE (pointer_to
) == QImode
)
6532 obstack_1grow (&util_obstack
, '*');
6536 /* We have a type that does not get special treatment. */
6538 /* NeXT extension */
6539 obstack_1grow (&util_obstack
, '^');
6540 encode_type (pointer_to
, curtype
, format
);
6544 encode_array (type
, curtype
, format
)
6549 tree an_int_cst
= TYPE_SIZE (type
);
6550 tree array_of
= TREE_TYPE (type
);
6553 /* An incomplete array is treated like a pointer. */
6554 if (an_int_cst
== NULL
)
6556 encode_pointer (type
, curtype
, format
);
6560 sprintf (buffer
, "[%d",
6561 (TREE_INT_CST_LOW (an_int_cst
)
6562 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
6564 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6565 encode_type (array_of
, curtype
, format
);
6566 obstack_1grow (&util_obstack
, ']');
6571 encode_aggregate_within (type
, curtype
, format
, left
, right
)
6578 if (obstack_object_size (&util_obstack
) > 0
6579 && *(obstack_next_free (&util_obstack
) - 1) == '^')
6581 tree name
= TYPE_NAME (type
);
6583 /* we have a reference; this is a NeXT extension. */
6585 if (obstack_object_size (&util_obstack
) - curtype
== 1
6586 && format
== OBJC_ENCODE_INLINE_DEFS
)
6588 /* Output format of struct for first level only. */
6589 tree fields
= TYPE_FIELDS (type
);
6591 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6593 obstack_1grow (&util_obstack
, left
);
6594 obstack_grow (&util_obstack
,
6595 IDENTIFIER_POINTER (name
),
6596 strlen (IDENTIFIER_POINTER (name
)));
6597 obstack_1grow (&util_obstack
, '=');
6601 obstack_1grow (&util_obstack
, left
);
6602 obstack_grow (&util_obstack
, "?=", 2);
6605 for ( ; fields
; fields
= TREE_CHAIN (fields
))
6606 encode_field_decl (fields
, curtype
, format
);
6608 obstack_1grow (&util_obstack
, right
);
6611 else if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6613 obstack_1grow (&util_obstack
, left
);
6614 obstack_grow (&util_obstack
,
6615 IDENTIFIER_POINTER (name
),
6616 strlen (IDENTIFIER_POINTER (name
)));
6617 obstack_1grow (&util_obstack
, right
);
6622 /* We have an untagged structure or a typedef. */
6623 obstack_1grow (&util_obstack
, left
);
6624 obstack_1grow (&util_obstack
, '?');
6625 obstack_1grow (&util_obstack
, right
);
6631 tree name
= TYPE_NAME (type
);
6632 tree fields
= TYPE_FIELDS (type
);
6634 if (format
== OBJC_ENCODE_INLINE_DEFS
6635 || generating_instance_variables
)
6637 obstack_1grow (&util_obstack
, left
);
6638 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6639 obstack_grow (&util_obstack
,
6640 IDENTIFIER_POINTER (name
),
6641 strlen (IDENTIFIER_POINTER (name
)));
6643 obstack_1grow (&util_obstack
, '?');
6645 obstack_1grow (&util_obstack
, '=');
6647 for (; fields
; fields
= TREE_CHAIN (fields
))
6649 if (generating_instance_variables
)
6651 tree fname
= DECL_NAME (fields
);
6653 obstack_1grow (&util_obstack
, '"');
6654 if (fname
&& TREE_CODE (fname
) == IDENTIFIER_NODE
)
6656 obstack_grow (&util_obstack
,
6657 IDENTIFIER_POINTER (fname
),
6658 strlen (IDENTIFIER_POINTER (fname
)));
6661 obstack_1grow (&util_obstack
, '"');
6664 encode_field_decl (fields
, curtype
, format
);
6667 obstack_1grow (&util_obstack
, right
);
6672 obstack_1grow (&util_obstack
, left
);
6673 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6674 obstack_grow (&util_obstack
,
6675 IDENTIFIER_POINTER (name
),
6676 strlen (IDENTIFIER_POINTER (name
)));
6678 /* We have an untagged structure or a typedef. */
6679 obstack_1grow (&util_obstack
, '?');
6681 obstack_1grow (&util_obstack
, right
);
6687 encode_aggregate (type
, curtype
, format
)
6692 enum tree_code code
= TREE_CODE (type
);
6698 encode_aggregate_within(type
, curtype
, format
, '{', '}');
6703 encode_aggregate_within(type
, curtype
, format
, '(', ')');
6708 obstack_1grow (&util_obstack
, 'i');
6716 /* Support bitfields. The current version of Objective-C does not support
6717 them. The string will consist of one or more "b:n"'s where n is an
6718 integer describing the width of the bitfield. Currently, classes in
6719 the kit implement a method "-(char *)describeBitfieldStruct:" that
6720 simulates this. If they do not implement this method, the archiver
6721 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6722 according to the GNU compiler. After looking at the "kit", it appears
6723 that all classes currently rely on this default behavior, rather than
6724 hand generating this string (which is tedious). */
6727 encode_bitfield (width
, format
)
6732 sprintf (buffer
, "b%d", width
);
6733 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6736 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6739 encode_type (type
, curtype
, format
)
6744 enum tree_code code
= TREE_CODE (type
);
6746 if (code
== INTEGER_TYPE
)
6748 if (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type
)) == 0
6749 && TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type
)) == 0)
6751 /* Unsigned integer types. */
6753 if (TYPE_MODE (type
) == QImode
)
6754 obstack_1grow (&util_obstack
, 'C');
6755 else if (TYPE_MODE (type
) == HImode
)
6756 obstack_1grow (&util_obstack
, 'S');
6757 else if (TYPE_MODE (type
) == SImode
)
6759 if (type
== long_unsigned_type_node
)
6760 obstack_1grow (&util_obstack
, 'L');
6762 obstack_1grow (&util_obstack
, 'I');
6764 else if (TYPE_MODE (type
) == DImode
)
6765 obstack_1grow (&util_obstack
, 'Q');
6769 /* Signed integer types. */
6771 if (TYPE_MODE (type
) == QImode
)
6772 obstack_1grow (&util_obstack
, 'c');
6773 else if (TYPE_MODE (type
) == HImode
)
6774 obstack_1grow (&util_obstack
, 's');
6775 else if (TYPE_MODE (type
) == SImode
)
6777 if (type
== long_integer_type_node
)
6778 obstack_1grow (&util_obstack
, 'l');
6780 obstack_1grow (&util_obstack
, 'i');
6783 else if (TYPE_MODE (type
) == DImode
)
6784 obstack_1grow (&util_obstack
, 'q');
6788 else if (code
== REAL_TYPE
)
6790 /* Floating point types. */
6792 if (TYPE_MODE (type
) == SFmode
)
6793 obstack_1grow (&util_obstack
, 'f');
6794 else if (TYPE_MODE (type
) == DFmode
6795 || TYPE_MODE (type
) == TFmode
)
6796 obstack_1grow (&util_obstack
, 'd');
6799 else if (code
== VOID_TYPE
)
6800 obstack_1grow (&util_obstack
, 'v');
6802 else if (code
== ARRAY_TYPE
)
6803 encode_array (type
, curtype
, format
);
6805 else if (code
== POINTER_TYPE
)
6806 encode_pointer (type
, curtype
, format
);
6808 else if (code
== RECORD_TYPE
|| code
== UNION_TYPE
|| code
== ENUMERAL_TYPE
)
6809 encode_aggregate (type
, curtype
, format
);
6811 else if (code
== FUNCTION_TYPE
) /* '?' */
6812 obstack_1grow (&util_obstack
, '?');
6816 encode_field_decl (field_decl
, curtype
, format
)
6823 /* If this field is obviously a bitfield, or is a bitfield that has been
6824 clobbered to look like a ordinary integer mode, go ahead and generate
6825 the bitfield typing information. */
6826 type
= TREE_TYPE (field_decl
);
6827 if (DECL_BIT_FIELD (field_decl
))
6828 encode_bitfield (DECL_FIELD_SIZE (field_decl
), format
);
6829 else if (TREE_CODE (TYPE_SIZE (type
)) == INTEGER_CST
6830 && DECL_FIELD_SIZE (field_decl
)
6831 && TYPE_MODE (type
) > DECL_MODE (field_decl
))
6832 encode_bitfield (DECL_FIELD_SIZE (field_decl
), format
);
6834 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6838 expr_last (complex_expr
)
6844 while ((next
= TREE_OPERAND (complex_expr
, 0)))
6845 complex_expr
= next
;
6847 return complex_expr
;
6850 /* The selector of the current method,
6851 or NULL if we aren't compiling a method. */
6854 maybe_objc_method_name (decl
)
6858 return METHOD_SEL_NAME (method_context
);
6863 /* Transform a method definition into a function definition as follows:
6864 - synthesize the first two arguments, "self" and "_cmd". */
6867 start_method_def (method
)
6872 /* Required to implement _msgSuper. */
6873 method_context
= method
;
6874 UOBJC_SUPER_decl
= NULL_TREE
;
6876 /* Must be called BEFORE start_function. */
6879 /* Generate prototype declarations for arguments..."new-style". */
6881 if (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
)
6882 decl_specs
= build_tree_list (NULL_TREE
, uprivate_record
);
6884 /* Really a `struct objc_class *'. However, we allow people to
6885 assign to self, which changes its type midstream. */
6886 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
6888 push_parm_decl (build_tree_list
6889 (build_tree_list (decl_specs
,
6890 build1 (INDIRECT_REF
, NULL_TREE
, self_id
)),
6891 build_tree_list (unused_list
, NULL_TREE
)));
6893 #ifdef OBJC_INT_SELECTORS
6894 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_UNSIGNED
]);
6895 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_INT
], decl_specs
);
6896 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, ucmd_id
),
6897 build_tree_list (unused_list
, NULL_TREE
)));
6898 #else /* not OBJC_INT_SELECTORS */
6899 decl_specs
= build_tree_list (NULL_TREE
,
6900 xref_tag (RECORD_TYPE
,
6901 get_identifier (TAG_SELECTOR
)));
6902 push_parm_decl (build_tree_list
6903 (build_tree_list (decl_specs
,
6904 build1 (INDIRECT_REF
, NULL_TREE
, ucmd_id
)),
6905 build_tree_list (unused_list
, NULL_TREE
)));
6906 #endif /* not OBJC_INT_SELECTORS */
6908 /* Generate argument declarations if a keyword_decl. */
6909 if (METHOD_SEL_ARGS (method
))
6911 tree arglist
= METHOD_SEL_ARGS (method
);
6914 tree arg_spec
= TREE_PURPOSE (TREE_TYPE (arglist
));
6915 tree arg_decl
= TREE_VALUE (TREE_TYPE (arglist
));
6919 tree last_expr
= expr_last (arg_decl
);
6921 /* Unite the abstract decl with its name. */
6922 TREE_OPERAND (last_expr
, 0) = KEYWORD_ARG_NAME (arglist
);
6923 push_parm_decl (build_tree_list
6924 (build_tree_list (arg_spec
, arg_decl
),
6925 build_tree_list (NULL_TREE
, NULL_TREE
)));
6927 /* Unhook: restore the abstract declarator. */
6928 TREE_OPERAND (last_expr
, 0) = NULL_TREE
;
6932 push_parm_decl (build_tree_list
6933 (build_tree_list (arg_spec
,
6934 KEYWORD_ARG_NAME (arglist
)),
6935 build_tree_list (NULL_TREE
, NULL_TREE
)));
6937 arglist
= TREE_CHAIN (arglist
);
6942 if (METHOD_ADD_ARGS (method
) > (tree
)1)
6944 /* We have a variable length selector - in "prototype" format. */
6945 tree akey
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
6948 /* This must be done prior to calling pushdecl. pushdecl is
6949 going to change our chain on us. */
6950 tree nextkey
= TREE_CHAIN (akey
);
6958 warn_with_method (message
, mtype
, method
)
6963 if (count_error (1) == 0)
6966 report_error_function (DECL_SOURCE_FILE (method
));
6968 fprintf (stderr
, "%s:%d: warning: ",
6969 DECL_SOURCE_FILE (method
), DECL_SOURCE_LINE (method
));
6970 bzero (errbuf
, BUFSIZE
);
6971 fprintf (stderr
, "%s `%c%s'\n",
6972 message
, mtype
, gen_method_decl (method
, errbuf
));
6975 /* Return 1 if METHOD is consistent with PROTO. */
6978 comp_method_with_proto (method
, proto
)
6981 static tree function_type
= 0;
6983 /* Create a function_type node once. */
6986 push_obstacks_nochange ();
6987 end_temporary_allocation ();
6988 function_type
= make_node (FUNCTION_TYPE
);
6992 /* Install argument types - normally set by build_function_type. */
6993 TYPE_ARG_TYPES (function_type
) = get_arg_type_list (proto
, METHOD_DEF
, 0);
6995 /* install return type */
6996 TREE_TYPE (function_type
) = groktypename (TREE_TYPE (proto
));
6998 return comptypes (TREE_TYPE (METHOD_DEFINITION (method
)), function_type
);
7001 /* Return 1 if PROTO1 is consistent with PROTO2. */
7004 comp_proto_with_proto (proto1
, proto2
)
7005 tree proto1
, proto2
;
7007 static tree function_type1
= 0, function_type2
= 0;
7009 /* Create a couple function_type node's once. */
7010 if (!function_type1
)
7012 push_obstacks_nochange ();
7013 end_temporary_allocation ();
7014 function_type1
= make_node (FUNCTION_TYPE
);
7015 function_type2
= make_node (FUNCTION_TYPE
);
7019 /* Install argument types; normally set by build_function_type. */
7020 TYPE_ARG_TYPES (function_type1
) = get_arg_type_list (proto1
, METHOD_REF
, 0);
7021 TYPE_ARG_TYPES (function_type2
) = get_arg_type_list (proto2
, METHOD_REF
, 0);
7023 /* Install return type. */
7024 TREE_TYPE (function_type1
) = groktypename (TREE_TYPE (proto1
));
7025 TREE_TYPE (function_type2
) = groktypename (TREE_TYPE (proto2
));
7027 return comptypes (function_type1
, function_type2
);
7030 /* - Generate an identifier for the function. the format is "_n_cls",
7031 where 1 <= n <= nMethods, and cls is the name the implementation we
7033 - Install the return type from the method declaration.
7034 - If we have a prototype, check for type consistency. */
7037 really_start_method (method
, parmlist
)
7038 tree method
, parmlist
;
7040 tree sc_spec
, ret_spec
, ret_decl
, decl_specs
;
7041 tree method_decl
, method_id
;
7042 char *buf
, *sel_name
, *class_name
, *cat_name
;
7044 /* Synth the storage class & assemble the return type. */
7045 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
7046 ret_spec
= TREE_PURPOSE (TREE_TYPE (method
));
7047 decl_specs
= chainon (sc_spec
, ret_spec
);
7049 sel_name
= IDENTIFIER_POINTER (METHOD_SEL_NAME (method
));
7050 class_name
= IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
7051 cat_name
= ((TREE_CODE (implementation_context
)
7052 == CLASS_IMPLEMENTATION_TYPE
)
7054 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
7057 /* Make sure this is big enough for any plausible method label. */
7058 buf
= (char *) alloca (50 + strlen (sel_name
) + strlen (class_name
)
7059 + (cat_name
? strlen (cat_name
) : 0));
7061 OBJC_GEN_METHOD_LABEL (buf
, TREE_CODE (method
) == INSTANCE_METHOD_DECL
,
7062 class_name
, cat_name
, sel_name
, method_slot
);
7064 method_id
= get_identifier (buf
);
7066 method_decl
= build_nt (CALL_EXPR
, method_id
, parmlist
, NULL_TREE
);
7068 /* Check the declarator portion of the return type for the method. */
7069 if ((ret_decl
= TREE_VALUE (TREE_TYPE (method
))))
7071 /* Unite the complex decl (specified in the abstract decl) with the
7072 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7073 tree save_expr
= expr_last (ret_decl
);
7075 TREE_OPERAND (save_expr
, 0) = method_decl
;
7076 method_decl
= ret_decl
;
7078 /* Fool the parser into thinking it is starting a function. */
7079 start_function (decl_specs
, method_decl
, NULL_TREE
, NULL_TREE
, 0);
7081 /* Unhook: this has the effect of restoring the abstract declarator. */
7082 TREE_OPERAND (save_expr
, 0) = NULL_TREE
;
7087 TREE_VALUE (TREE_TYPE (method
)) = method_decl
;
7089 /* Fool the parser into thinking it is starting a function. */
7090 start_function (decl_specs
, method_decl
, NULL_TREE
, NULL_TREE
, 0);
7092 /* Unhook: this has the effect of restoring the abstract declarator. */
7093 TREE_VALUE (TREE_TYPE (method
)) = NULL_TREE
;
7096 METHOD_DEFINITION (method
) = current_function_decl
;
7098 if (implementation_template
!= implementation_context
)
7102 if (TREE_CODE (method
) == INSTANCE_METHOD_DECL
)
7103 proto
= lookup_instance_method_static (implementation_template
,
7104 METHOD_SEL_NAME (method
));
7106 proto
= lookup_class_method_static (implementation_template
,
7107 METHOD_SEL_NAME (method
));
7109 if (proto
&& ! comp_method_with_proto (method
, proto
))
7111 char type
= (TREE_CODE (method
) == INSTANCE_METHOD_DECL
? '-' : '+');
7113 warn_with_method ("conflicting types for", type
, method
);
7114 warn_with_method ("previous declaration of", type
, proto
);
7119 /* The following routine is always called...this "architecture" is to
7120 accommodate "old-style" variable length selectors.
7122 - a:a b:b // prototype ; id c; id d; // old-style. */
7125 continue_method_def ()
7129 if (METHOD_ADD_ARGS (method_context
) == (tree
)1)
7130 /* We have a `, ...' immediately following the selector. */
7131 parmlist
= get_parm_info (0);
7133 parmlist
= get_parm_info (1); /* place a `void_at_end' */
7135 /* Set self_decl from the first argument...this global is used by
7136 build_ivar_reference calling build_indirect_ref. */
7137 self_decl
= TREE_PURPOSE (parmlist
);
7140 really_start_method (method_context
, parmlist
);
7141 store_parm_decls ();
7144 /* Called by the parser, from the `pushlevel' production. */
7149 if (!UOBJC_SUPER_decl
)
7151 UOBJC_SUPER_decl
= start_decl (get_identifier (UTAG_SUPER
),
7152 build_tree_list (NULL_TREE
,
7153 objc_super_template
),
7154 0, NULL_TREE
, NULL_TREE
);
7156 finish_decl (UOBJC_SUPER_decl
, NULL_TREE
, NULL_TREE
);
7158 /* This prevents `unused variable' warnings when compiling with -Wall. */
7159 TREE_USED (UOBJC_SUPER_decl
) = 1;
7160 DECL_ARTIFICIAL (UOBJC_SUPER_decl
) = 1;
7164 /* _n_Method (id self, SEL sel, ...)
7166 struct objc_super _S;
7167 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7171 get_super_receiver ()
7175 tree super_expr
, super_expr_list
;
7177 /* Set receiver to self. */
7178 super_expr
= build_component_ref (UOBJC_SUPER_decl
, self_id
);
7179 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, self_decl
);
7180 super_expr_list
= build_tree_list (NULL_TREE
, super_expr
);
7182 /* Set class to begin searching. */
7183 super_expr
= build_component_ref (UOBJC_SUPER_decl
,
7184 get_identifier ("class"));
7186 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
7188 /* [_cls, __cls]Super are "pre-built" in
7189 synth_forward_declarations. */
7191 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
,
7192 ((TREE_CODE (method_context
)
7193 == INSTANCE_METHOD_DECL
)
7195 : uucls_super_ref
));
7199 /* We have a category. */
7201 tree super_name
= CLASS_SUPER_NAME (implementation_template
);
7206 error ("no super class declared in interface for `%s'",
7207 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
7208 return error_mark_node
;
7211 if (flag_next_runtime
)
7213 super_class
= get_class_reference (super_name
);
7214 if (TREE_CODE (method_context
) == CLASS_METHOD_DECL
)
7216 = build_component_ref (build_indirect_ref (super_class
, "->"),
7217 get_identifier ("isa"));
7221 add_class_reference (super_name
);
7222 super_class
= (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
7223 ? objc_get_class_decl
: objc_get_meta_class_decl
);
7224 assemble_external (super_class
);
7226 = build_function_call
7230 my_build_string (IDENTIFIER_LENGTH (super_name
) + 1,
7231 IDENTIFIER_POINTER (super_name
))));
7234 TREE_TYPE (super_class
) = TREE_TYPE (ucls_super_ref
);
7235 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, super_class
);
7238 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7240 super_expr
= build_unary_op (ADDR_EXPR
, UOBJC_SUPER_decl
, 0);
7241 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7243 return build_compound_expr (super_expr_list
);
7247 error ("[super ...] must appear in a method context");
7248 return error_mark_node
;
7253 encode_method_def (func_decl
)
7258 int max_parm_end
= 0;
7263 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
7264 obstack_object_size (&util_obstack
),
7265 OBJC_ENCODE_INLINE_DEFS
);
7268 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7269 parms
= TREE_CHAIN (parms
))
7271 int parm_end
= (forwarding_offset (parms
)
7272 + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms
)))
7275 if (!offset_is_register
&& parm_end
> max_parm_end
)
7276 max_parm_end
= parm_end
;
7279 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
7281 sprintf (buffer
, "%d", stack_size
);
7282 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7284 /* Argument types. */
7285 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7286 parms
= TREE_CHAIN (parms
))
7289 encode_type (TREE_TYPE (parms
),
7290 obstack_object_size (&util_obstack
),
7291 OBJC_ENCODE_INLINE_DEFS
);
7293 /* Compute offset. */
7294 sprintf (buffer
, "%d", forwarding_offset (parms
));
7296 /* Indicate register. */
7297 if (offset_is_register
)
7298 obstack_1grow (&util_obstack
, '+');
7300 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7303 obstack_1grow (&util_obstack
, 0);
7304 result
= get_identifier (obstack_finish (&util_obstack
));
7305 obstack_free (&util_obstack
, util_firstobj
);
7310 finish_method_def ()
7312 METHOD_ENCODING (method_context
) = encode_method_def (current_function_decl
);
7314 finish_function (0);
7316 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7317 since the optimizer may find "may be used before set" errors. */
7318 method_context
= NULL_TREE
;
7323 lang_report_error_function (decl
)
7328 fprintf (stderr
, "In method `%s'\n",
7329 IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context
)));
7339 is_complex_decl (type
)
7342 return (TREE_CODE (type
) == ARRAY_TYPE
7343 || TREE_CODE (type
) == FUNCTION_TYPE
7344 || (TREE_CODE (type
) == POINTER_TYPE
&& ! IS_ID (type
)));
7348 /* Code to convert a decl node into text for a declaration in C. */
7350 static char tmpbuf
[256];
7353 adorn_decl (decl
, str
)
7357 enum tree_code code
= TREE_CODE (decl
);
7359 if (code
== ARRAY_REF
)
7361 tree an_int_cst
= TREE_OPERAND (decl
, 1);
7363 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_CST
)
7364 sprintf (str
+ strlen (str
), "[%d]", TREE_INT_CST_LOW (an_int_cst
));
7369 else if (code
== ARRAY_TYPE
)
7371 tree an_int_cst
= TYPE_SIZE (decl
);
7372 tree array_of
= TREE_TYPE (decl
);
7374 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_TYPE
)
7375 sprintf (str
+ strlen (str
), "[%d]",
7376 (TREE_INT_CST_LOW (an_int_cst
)
7377 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
7382 else if (code
== CALL_EXPR
)
7384 tree chain
= TREE_PURPOSE (TREE_OPERAND (decl
, 1));
7389 gen_declaration (chain
, str
);
7390 chain
= TREE_CHAIN (chain
);
7397 else if (code
== FUNCTION_TYPE
)
7399 tree chain
= TYPE_ARG_TYPES (decl
);
7402 while (chain
&& TREE_VALUE (chain
) != void_type_node
)
7404 gen_declaration (TREE_VALUE (chain
), str
);
7405 chain
= TREE_CHAIN (chain
);
7406 if (chain
&& TREE_VALUE (chain
) != void_type_node
)
7412 else if (code
== INDIRECT_REF
)
7414 strcpy (tmpbuf
, "*");
7415 if (TREE_TYPE (decl
) && TREE_CODE (TREE_TYPE (decl
)) == TREE_LIST
)
7419 for (chain
= nreverse (copy_list (TREE_TYPE (decl
)));
7421 chain
= TREE_CHAIN (chain
))
7423 if (TREE_CODE (TREE_VALUE (chain
)) == IDENTIFIER_NODE
)
7425 strcat (tmpbuf
, " ");
7426 strcat (tmpbuf
, IDENTIFIER_POINTER (TREE_VALUE (chain
)));
7430 strcat (tmpbuf
, " ");
7432 strcat (tmpbuf
, str
);
7433 strcpy (str
, tmpbuf
);
7436 else if (code
== POINTER_TYPE
)
7438 strcpy (tmpbuf
, "*");
7439 if (TREE_READONLY (decl
) || TYPE_VOLATILE (decl
))
7441 if (TREE_READONLY (decl
))
7442 strcat (tmpbuf
, " const");
7443 if (TYPE_VOLATILE (decl
))
7444 strcat (tmpbuf
, " volatile");
7446 strcat (tmpbuf
, " ");
7448 strcat (tmpbuf
, str
);
7449 strcpy (str
, tmpbuf
);
7454 gen_declarator (decl
, buf
, name
)
7461 enum tree_code code
= TREE_CODE (decl
);
7471 op
= TREE_OPERAND (decl
, 0);
7473 /* We have a pointer to a function or array...(*)(), (*)[] */
7474 if ((code
== ARRAY_REF
|| code
== CALL_EXPR
)
7475 && op
&& TREE_CODE (op
) == INDIRECT_REF
)
7478 str
= gen_declarator (op
, buf
, name
);
7482 strcpy (tmpbuf
, "(");
7483 strcat (tmpbuf
, str
);
7484 strcat (tmpbuf
, ")");
7485 strcpy (str
, tmpbuf
);
7488 adorn_decl (decl
, str
);
7497 /* This clause is done iteratively rather than recursively. */
7500 op
= (is_complex_decl (TREE_TYPE (decl
))
7501 ? TREE_TYPE (decl
) : NULL_TREE
);
7503 adorn_decl (decl
, str
);
7505 /* We have a pointer to a function or array...(*)(), (*)[] */
7506 if (code
== POINTER_TYPE
7507 && op
&& (TREE_CODE (op
) == FUNCTION_TYPE
7508 || TREE_CODE (op
) == ARRAY_TYPE
))
7510 strcpy (tmpbuf
, "(");
7511 strcat (tmpbuf
, str
);
7512 strcat (tmpbuf
, ")");
7513 strcpy (str
, tmpbuf
);
7516 decl
= (is_complex_decl (TREE_TYPE (decl
))
7517 ? TREE_TYPE (decl
) : NULL_TREE
);
7520 while (decl
&& (code
= TREE_CODE (decl
)))
7525 case IDENTIFIER_NODE
:
7526 /* Will only happen if we are processing a "raw" expr-decl. */
7527 strcpy (buf
, IDENTIFIER_POINTER (decl
));
7538 /* We have an abstract declarator or a _DECL node. */
7546 gen_declspecs (declspecs
, buf
, raw
)
7555 for (chain
= nreverse (copy_list (declspecs
));
7556 chain
; chain
= TREE_CHAIN (chain
))
7558 tree aspec
= TREE_VALUE (chain
);
7560 if (TREE_CODE (aspec
) == IDENTIFIER_NODE
)
7561 strcat (buf
, IDENTIFIER_POINTER (aspec
));
7562 else if (TREE_CODE (aspec
) == RECORD_TYPE
)
7564 if (TYPE_NAME (aspec
))
7566 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7568 if (! TREE_STATIC_TEMPLATE (aspec
))
7569 strcat (buf
, "struct ");
7570 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7575 tree chain
= protocol_list
;
7582 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7583 chain
= TREE_CHAIN (chain
);
7592 strcat (buf
, "untagged struct");
7595 else if (TREE_CODE (aspec
) == UNION_TYPE
)
7597 if (TYPE_NAME (aspec
))
7599 if (! TREE_STATIC_TEMPLATE (aspec
))
7600 strcat (buf
, "union ");
7601 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7604 strcat (buf
, "untagged union");
7607 else if (TREE_CODE (aspec
) == ENUMERAL_TYPE
)
7609 if (TYPE_NAME (aspec
))
7611 if (! TREE_STATIC_TEMPLATE (aspec
))
7612 strcat (buf
, "enum ");
7613 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7616 strcat (buf
, "untagged enum");
7619 else if (TREE_CODE (aspec
) == TYPE_DECL
&& DECL_NAME (aspec
))
7620 strcat (buf
, IDENTIFIER_POINTER (DECL_NAME (aspec
)));
7622 else if (IS_ID (aspec
))
7624 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7629 tree chain
= protocol_list
;
7636 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7637 chain
= TREE_CHAIN (chain
);
7644 if (TREE_CHAIN (chain
))
7650 /* Type qualifiers. */
7651 if (TREE_READONLY (declspecs
))
7652 strcat (buf
, "const ");
7653 if (TYPE_VOLATILE (declspecs
))
7654 strcat (buf
, "volatile ");
7656 switch (TREE_CODE (declspecs
))
7658 /* Type specifiers. */
7661 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7663 /* Signed integer types. */
7665 if (declspecs
== short_integer_type_node
)
7666 strcat (buf
, "short int ");
7667 else if (declspecs
== integer_type_node
)
7668 strcat (buf
, "int ");
7669 else if (declspecs
== long_integer_type_node
)
7670 strcat (buf
, "long int ");
7671 else if (declspecs
== long_long_integer_type_node
)
7672 strcat (buf
, "long long int ");
7673 else if (declspecs
== signed_char_type_node
7674 || declspecs
== char_type_node
)
7675 strcat (buf
, "char ");
7677 /* Unsigned integer types. */
7679 else if (declspecs
== short_unsigned_type_node
)
7680 strcat (buf
, "unsigned short ");
7681 else if (declspecs
== unsigned_type_node
)
7682 strcat (buf
, "unsigned int ");
7683 else if (declspecs
== long_unsigned_type_node
)
7684 strcat (buf
, "unsigned long ");
7685 else if (declspecs
== long_long_unsigned_type_node
)
7686 strcat (buf
, "unsigned long long ");
7687 else if (declspecs
== unsigned_char_type_node
)
7688 strcat (buf
, "unsigned char ");
7692 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7694 if (declspecs
== float_type_node
)
7695 strcat (buf
, "float ");
7696 else if (declspecs
== double_type_node
)
7697 strcat (buf
, "double ");
7698 else if (declspecs
== long_double_type_node
)
7699 strcat (buf
, "long double ");
7703 if (TYPE_NAME (declspecs
)
7704 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7706 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7708 if (! TREE_STATIC_TEMPLATE (declspecs
))
7709 strcat (buf
, "struct ");
7710 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7714 tree chain
= protocol_list
;
7721 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7722 chain
= TREE_CHAIN (chain
);
7731 strcat (buf
, "untagged struct");
7737 if (TYPE_NAME (declspecs
)
7738 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7740 strcat (buf
, "union ");
7741 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7746 strcat (buf
, "untagged union ");
7750 if (TYPE_NAME (declspecs
)
7751 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7753 strcat (buf
, "enum ");
7754 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7759 strcat (buf
, "untagged enum ");
7763 strcat (buf
, "void ");
7768 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7773 tree chain
= protocol_list
;
7780 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7781 chain
= TREE_CHAIN (chain
);
7798 gen_declaration (atype_or_adecl
, buf
)
7799 tree atype_or_adecl
;
7804 if (TREE_CODE (atype_or_adecl
) == TREE_LIST
)
7806 tree declspecs
; /* "identifier_node", "record_type" */
7807 tree declarator
; /* "array_ref", "indirect_ref", "call_expr"... */
7809 /* We have a "raw", abstract declarator (typename). */
7810 declarator
= TREE_VALUE (atype_or_adecl
);
7811 declspecs
= TREE_PURPOSE (atype_or_adecl
);
7813 gen_declspecs (declspecs
, buf
, 1);
7817 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7824 tree declspecs
; /* "integer_type", "real_type", "record_type"... */
7825 tree declarator
; /* "array_type", "function_type", "pointer_type". */
7827 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7828 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7829 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7830 atype
= TREE_TYPE (atype_or_adecl
);
7832 /* Assume we have a *_type node. */
7833 atype
= atype_or_adecl
;
7835 if (is_complex_decl (atype
))
7839 /* Get the declaration specifier; it is at the end of the list. */
7840 declarator
= chain
= atype
;
7842 chain
= TREE_TYPE (chain
); /* not TREE_CHAIN (chain); */
7843 while (is_complex_decl (chain
));
7850 declarator
= NULL_TREE
;
7853 gen_declspecs (declspecs
, buf
, 0);
7855 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7856 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7857 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7859 char *decl_name
= (DECL_NAME (atype_or_adecl
)
7860 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl
))
7866 strcat (buf
, gen_declarator (declarator
, declbuf
, decl_name
));
7869 else if (decl_name
[0])
7872 strcat (buf
, decl_name
);
7875 else if (declarator
)
7878 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7885 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7888 gen_method_decl (method
, buf
)
7894 if (RAW_TYPESPEC (method
) != objc_object_reference
)
7897 gen_declaration (TREE_TYPE (method
), buf
);
7901 chain
= METHOD_SEL_ARGS (method
);
7904 /* We have a chain of keyword_decls. */
7907 if (KEYWORD_KEY_NAME (chain
))
7908 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain
)));
7911 if (RAW_TYPESPEC (chain
) != objc_object_reference
)
7914 gen_declaration (TREE_TYPE (chain
), buf
);
7918 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain
)));
7919 if ((chain
= TREE_CHAIN (chain
)))
7924 if (METHOD_ADD_ARGS (method
) == (tree
)1)
7925 strcat (buf
, ", ...");
7926 else if (METHOD_ADD_ARGS (method
))
7928 /* We have a tree list node as generate by get_parm_info. */
7929 chain
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
7931 /* Know we have a chain of parm_decls. */
7935 gen_declaration (chain
, buf
);
7936 chain
= TREE_CHAIN (chain
);
7942 /* We have a unary selector. */
7943 strcat (buf
, IDENTIFIER_POINTER (METHOD_SEL_NAME (method
)));
7951 dump_interface (fp
, chain
)
7955 char *buf
= (char *)xmalloc (256);
7956 char *my_name
= IDENTIFIER_POINTER (CLASS_NAME (chain
));
7957 tree ivar_decls
= CLASS_RAW_IVARS (chain
);
7958 tree nst_methods
= CLASS_NST_METHODS (chain
);
7959 tree cls_methods
= CLASS_CLS_METHODS (chain
);
7961 fprintf (fp
, "\n@interface %s", my_name
);
7963 if (CLASS_SUPER_NAME (chain
))
7965 char *super_name
= IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain
));
7966 fprintf (fp
, " : %s\n", super_name
);
7973 fprintf (fp
, "{\n");
7977 fprintf (fp
, "\t%s;\n", gen_declaration (ivar_decls
, buf
));
7978 ivar_decls
= TREE_CHAIN (ivar_decls
);
7981 fprintf (fp
, "}\n");
7987 fprintf (fp
, "- %s;\n", gen_method_decl (nst_methods
, buf
));
7988 nst_methods
= TREE_CHAIN (nst_methods
);
7994 fprintf (fp
, "+ %s;\n", gen_method_decl (cls_methods
, buf
));
7995 cls_methods
= TREE_CHAIN (cls_methods
);
7997 fprintf (fp
, "\n@end");
8000 /* Demangle function for Objective-C */
8002 objc_demangle (mangled
)
8003 const char *mangled
;
8005 char *demangled
, *cp
;
8007 if (mangled
[0] == '_' &&
8008 (mangled
[1] == 'i' || mangled
[1] == 'c') &&
8011 cp
= demangled
= xmalloc(strlen(mangled
) + 2);
8012 if (mangled
[1] == 'i')
8013 *cp
++ = '-'; /* for instance method */
8015 *cp
++ = '+'; /* for class method */
8016 *cp
++ = '['; /* opening left brace */
8017 strcpy(cp
, mangled
+3); /* tack on the rest of the mangled name */
8018 while (*cp
&& *cp
== '_')
8019 cp
++; /* skip any initial underbars in class name */
8020 cp
= strchr(cp
, '_'); /* find first non-initial underbar */
8023 free(demangled
); /* not mangled name */
8026 if (cp
[1] == '_') /* easy case: no category name */
8028 *cp
++ = ' '; /* replace two '_' with one ' ' */
8029 strcpy(cp
, mangled
+ (cp
- demangled
) + 2);
8033 *cp
++ = '('; /* less easy case: category name */
8034 cp
= strchr(cp
, '_');
8037 free(demangled
); /* not mangled name */
8041 *cp
++ = ' '; /* overwriting 1st char of method name... */
8042 strcpy(cp
, mangled
+ (cp
- demangled
)); /* get it back */
8044 while (*cp
&& *cp
== '_')
8045 cp
++; /* skip any initial underbars in method name */
8048 *cp
= ':'; /* replace remaining '_' with ':' */
8049 *cp
++ = ']'; /* closing right brace */
8050 *cp
++ = 0; /* string terminator */
8054 return mangled
; /* not an objc mangled name */
8058 objc_printable_name (decl
, kind
)
8062 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl
)));
8068 /* Add the special tree codes of Objective C to the tables. */
8070 #define LAST_CODE LAST_AND_UNUSED_TREE_CODE
8072 gcc_obstack_init (&util_obstack
);
8073 util_firstobj
= (char *) obstack_finish (&util_obstack
);
8075 bcopy (objc_tree_code_type
,
8076 tree_code_type
+ (int) LAST_CODE
,
8077 (int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
);
8078 bcopy ((char *) objc_tree_code_length
,
8079 (char *) (tree_code_length
+ (int) LAST_CODE
),
8080 (((int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
)
8082 bcopy ((char *) objc_tree_code_name
,
8083 (char *) (tree_code_name
+ (int) LAST_CODE
),
8084 (((int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
)
8085 * sizeof (char *)));
8087 errbuf
= (char *)xmalloc (BUFSIZE
);
8089 synth_module_prologue ();
8091 /* Change the default error function */
8092 decl_printable_name
= (char* (*)()) objc_printable_name
;
8098 struct imp_entry
*impent
;
8100 /* The internally generated initializers appear to have missing braces.
8101 Don't warn about this. */
8102 int save_warn_missing_braces
= warn_missing_braces
;
8103 warn_missing_braces
= 0;
8105 generate_forward_declaration_to_string_table ();
8107 #ifdef OBJC_PROLOGUE
8111 /* Process the static instances here because initialization of objc_symtab
8113 if (objc_static_instances
)
8114 generate_static_references ();
8116 if (implementation_context
|| class_names_chain
8117 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8118 generate_objc_symtab_decl ();
8120 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8122 implementation_context
= impent
->imp_context
;
8123 implementation_template
= impent
->imp_template
;
8125 UOBJC_CLASS_decl
= impent
->class_decl
;
8126 UOBJC_METACLASS_decl
= impent
->meta_decl
;
8128 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
8130 /* all of the following reference the string pool... */
8131 generate_ivar_lists ();
8132 generate_dispatch_tables ();
8133 generate_shared_structures ();
8137 generate_dispatch_tables ();
8138 generate_category (implementation_context
);
8142 /* If we are using an array of selectors, we must always
8143 finish up the array decl even if no selectors were used. */
8144 if (! flag_next_runtime
|| sel_ref_chain
)
8145 build_selector_translation_table ();
8148 generate_protocols ();
8150 if (implementation_context
|| class_names_chain
|| objc_static_instances
8151 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8153 /* Arrange for Objc data structures to be initialized at run time. */
8154 char *init_name
= build_module_descriptor ();
8156 assemble_constructor (init_name
);
8159 /* Dump the class references. This forces the appropriate classes
8160 to be linked into the executable image, preserving unix archive
8161 semantics. This can be removed when we move to a more dynamically
8162 linked environment. */
8164 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
8166 handle_class_ref (chain
);
8167 if (TREE_PURPOSE (chain
))
8168 generate_classref_translation_entry (chain
);
8171 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8172 handle_impent (impent
);
8174 /* Dump the string table last. */
8176 generate_strings ();
8178 if (flag_gen_declaration
)
8180 add_class (implementation_context
);
8181 dump_interface (gen_declaration_file
, implementation_context
);
8189 /* Run through the selector hash tables and print a warning for any
8190 selector which has multiple methods. */
8192 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8193 for (hsh
= cls_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8196 tree meth
= hsh
->key
;
8197 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8201 warning ("potential selector conflict for method `%s'",
8202 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8203 warn_with_method ("found", type
, meth
);
8204 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8205 warn_with_method ("found", type
, loop
->value
);
8208 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8209 for (hsh
= nst_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8212 tree meth
= hsh
->key
;
8213 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8217 warning ("potential selector conflict for method `%s'",
8218 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8219 warn_with_method ("found", type
, meth
);
8220 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8221 warn_with_method ("found", type
, loop
->value
);
8225 warn_missing_braces
= save_warn_missing_braces
;
8228 /* Subroutines of finish_objc. */
8231 generate_classref_translation_entry (chain
)
8234 tree expr
, name
, decl_specs
, decl
, sc_spec
;
8237 type
= TREE_TYPE (TREE_PURPOSE (chain
));
8239 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
8240 expr
= build_c_cast (type
, expr
); /* cast! */
8242 name
= DECL_NAME (TREE_PURPOSE (chain
));
8244 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
8246 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8247 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
8249 /* The decl that is returned from start_decl is the one that we
8250 forward declared in build_class_reference. */
8251 decl
= start_decl (name
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
8252 finish_decl (decl
, expr
, NULL_TREE
);
8257 handle_class_ref (chain
)
8260 char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
8261 if (! flag_next_runtime
)
8264 char *string
= (char *) alloca (strlen (name
) + 30);
8267 sprintf (string
, "%sobjc_class_name_%s",
8268 (flag_next_runtime
? "." : "__"), name
);
8270 /* Make a decl for this name, so we can use its address in a tree. */
8271 decl
= build_decl (VAR_DECL
, get_identifier (string
), char_type_node
);
8272 DECL_EXTERNAL (decl
) = 1;
8273 TREE_PUBLIC (decl
) = 1;
8276 rest_of_decl_compilation (decl
, 0, 0, 0);
8278 /* Make following constant read-only (why not)? */
8279 readonly_data_section ();
8281 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
8283 /* Align the section properly. */
8284 assemble_constant_align (exp
);
8286 /* Inform the assembler about this new external thing. */
8287 assemble_external (decl
);
8289 /* Output a constant to reference this address. */
8290 output_constant (exp
, int_size_in_bytes (string_type_node
));
8294 /* This overreliance on our assembler (i.e. lack of portability)
8295 should be dealt with at some point. The GNU strategy (above)
8296 won't work either, but it is a start. */
8297 char *string
= (char *) alloca (strlen (name
) + 30);
8298 sprintf (string
, ".reference .objc_class_name_%s", name
);
8299 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8304 handle_impent (impent
)
8305 struct imp_entry
*impent
;
8307 implementation_context
= impent
->imp_context
;
8308 implementation_template
= impent
->imp_template
;
8310 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
8312 char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8313 char *string
= (char *) alloca (strlen (class_name
) + 30);
8315 if (flag_next_runtime
)
8317 /* Grossly unportable.
8318 People should know better than to assume
8319 such things about assembler syntax! */
8320 sprintf (string
, ".objc_class_name_%s=0", class_name
);
8321 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8323 sprintf (string
, ".globl .objc_class_name_%s", class_name
);
8324 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8329 sprintf (string
, "%sobjc_class_name_%s",
8330 (flag_next_runtime
? "." : "__"), class_name
);
8331 assemble_global (string
);
8332 assemble_label (string
);
8336 else if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
8338 char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8339 char *class_super_name
8340 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
8341 char *string
= (char *) alloca (strlen (class_name
)
8342 + strlen (class_super_name
) + 30);
8344 /* Do the same for categories. Even though no references to these
8345 symbols are generated automatically by the compiler, it gives
8346 you a handle to pull them into an archive by hand. */
8347 if (flag_next_runtime
)
8349 /* Grossly unportable. */
8350 sprintf (string
, ".objc_category_name_%s_%s=0",
8351 class_name
, class_super_name
);
8352 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8354 sprintf (string
, ".globl .objc_category_name_%s_%s",
8355 class_name
, class_super_name
);
8356 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8361 sprintf (string
, "%sobjc_category_name_%s_%s",
8362 (flag_next_runtime
? "." : "__"),
8363 class_name
, class_super_name
);
8364 assemble_global (string
);
8365 assemble_label (string
);
8376 char *buf
= (char *)xmalloc (256);
8378 { /* dump function prototypes */
8379 tree loop
= UOBJC_MODULES_decl
;
8381 fprintf (fp
, "\n\nfunction prototypes:\n");
8384 if (TREE_CODE (loop
) == FUNCTION_DECL
&& DECL_INITIAL (loop
))
8386 /* We have a function definition: generate prototype. */
8387 bzero (errbuf
, BUFSIZE
);
8388 gen_declaration (loop
, errbuf
);
8389 fprintf (fp
, "%s;\n", errbuf
);
8391 loop
= TREE_CHAIN (loop
);
8395 /* Dump global chains. */
8397 int i
, index
= 0, offset
= 0;
8400 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
8402 if (hashlist
= nst_method_hash_list
[i
])
8404 fprintf (fp
, "\n\nnst_method_hash_list[%d]:\n", i
);
8408 fprintf (fp
, "-%s;\n", gen_method_decl (hashlist
->key
, buf
));
8409 hashlist
= hashlist
->next
;
8415 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
8417 if (hashlist
= cls_method_hash_list
[i
])
8419 fprintf (fp
, "\n\ncls_method_hash_list[%d]:\n", i
);
8423 fprintf (fp
, "-%s;\n", gen_method_decl (hashlist
->key
, buf
));
8424 hashlist
= hashlist
->next
;
8430 fprintf (fp
, "\nsel_refdef_chain:\n");
8431 for (loop
= sel_refdef_chain
; loop
; loop
= TREE_CHAIN (loop
))
8433 fprintf (fp
, "(index: %4d offset: %4d) %s\n", index
, offset
,
8434 IDENTIFIER_POINTER (TREE_VALUE (loop
)));
8436 /* add one for the '\0' character */
8437 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (loop
)) + 1;
8440 fprintf (fp
, "\n (max_selector_index: %4d.\n", max_selector_index
);
8446 print_lang_statistics ()