1 /* Implement classes and message passing for Objective C.
2 Copyright (C) 1992, 93-95, 97, 1998 Free Software Foundation, Inc.
3 Contributed by Steve Naroff.
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* Purpose: This module implements the Objective-C 4.0 language.
24 compatibility issues (with the Stepstone translator):
26 - does not recognize the following 3.3 constructs.
27 @requires, @classes, @messages, = (...)
28 - methods with variable arguments must conform to ANSI standard.
29 - tagged structure definitions that appear in BOTH the interface
30 and implementation are not allowed.
31 - public/private: all instance variables are public within the
32 context of the implementation...I consider this to be a bug in
34 - statically allocated objects are not supported. the user will
35 receive an error if this service is requested.
37 code generation `options':
39 - OBJC_INT_SELECTORS */
56 extern cpp_reader parse_in
;
57 extern cpp_options parse_options
;
60 /* This is the default way of generating a method name. */
61 /* I am not sure it is really correct.
62 Perhaps there's a danger that it will make name conflicts
63 if method names contain underscores. -- rms. */
64 #ifndef OBJC_GEN_METHOD_LABEL
65 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
68 sprintf ((BUF), "_%s_%s_%s_%s", \
69 ((IS_INST) ? "i" : "c"), \
71 ((CAT_NAME)? (CAT_NAME) : ""), \
73 for (temp = (BUF); *temp; temp++) \
74 if (*temp == ':') *temp = '_'; \
78 /* These need specifying. */
79 #ifndef OBJC_FORWARDING_STACK_OFFSET
80 #define OBJC_FORWARDING_STACK_OFFSET 0
83 #ifndef OBJC_FORWARDING_MIN_OFFSET
84 #define OBJC_FORWARDING_MIN_OFFSET 0
87 /* Define the special tree codes that we use. */
89 /* Table indexed by tree code giving a string containing a character
90 classifying the tree code. Possibilities are
91 t, d, s, c, r, <, 1 and 2. See objc-tree.def for details. */
93 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
95 static const char objc_tree_code_type
[] = {
97 #include "objc-tree.def"
101 /* Table indexed by tree code giving number of expression
102 operands beyond the fixed part of the node structure.
103 Not used for types or decls. */
105 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
107 static const int objc_tree_code_length
[] = {
109 #include "objc-tree.def"
113 /* Names of tree components.
114 Used for printing out the tree and error messages. */
115 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
117 static const char * const objc_tree_code_name
[] = {
119 #include "objc-tree.def"
123 /* Set up for use of obstacks. */
127 #define obstack_chunk_alloc xmalloc
128 #define obstack_chunk_free free
130 /* This obstack is used to accumulate the encoding of a data type. */
131 static struct obstack util_obstack
;
132 /* This points to the beginning of obstack contents,
133 so we can free the whole contents. */
136 /* List of classes with list of their static instances. */
137 static tree objc_static_instances
= NULL_TREE
;
139 /* The declaration of the array administrating the static instances. */
140 static tree static_instances_decl
= NULL_TREE
;
142 /* for encode_method_def */
146 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
147 #define PROTOCOL_VERSION 2
149 #define OBJC_ENCODE_INLINE_DEFS 0
150 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
152 /*** Private Interface (procedures) ***/
154 /* Used by compile_file. */
156 static void init_objc
PROTO((void));
157 static void finish_objc
PROTO((void));
159 /* Code generation. */
161 static void synth_module_prologue
PROTO((void));
162 static tree build_constructor
PROTO((tree
, tree
));
163 static char *build_module_descriptor
PROTO((void));
164 static tree init_module_descriptor
PROTO((tree
));
165 static tree build_objc_method_call
PROTO((int, tree
, tree
,
167 static void generate_strings
PROTO((void));
168 static tree get_proto_encoding
PROTO((tree
));
169 static void build_selector_translation_table
PROTO((void));
170 static tree build_ivar_chain
PROTO((tree
, int));
172 static tree objc_add_static_instance
PROTO((tree
, tree
));
174 static tree build_ivar_template
PROTO((void));
175 static tree build_method_template
PROTO((void));
176 static tree build_private_template
PROTO((tree
));
177 static void build_class_template
PROTO((void));
178 static void build_selector_template
PROTO((void));
179 static void build_category_template
PROTO((void));
180 static tree build_super_template
PROTO((void));
181 static tree build_category_initializer
PROTO((tree
, tree
, tree
,
183 static tree build_protocol_initializer
PROTO((tree
, tree
, tree
,
186 static void synth_forward_declarations
PROTO((void));
187 static void generate_ivar_lists
PROTO((void));
188 static void generate_dispatch_tables
PROTO((void));
189 static void generate_shared_structures
PROTO((void));
190 static tree generate_protocol_list
PROTO((tree
));
191 static void generate_forward_declaration_to_string_table
PROTO((void));
192 static void build_protocol_reference
PROTO((tree
));
195 static tree init_selector
PROTO((int));
197 static tree build_keyword_selector
PROTO((tree
));
198 static tree synth_id_with_class_suffix
PROTO((const char *, tree
));
200 static void generate_static_references
PROTO((void));
201 static int check_methods_accessible
PROTO((tree
, tree
,
203 static void encode_aggregate_within
PROTO((tree
, int, int,
205 static const char *objc_demangle
PROTO((const char *));
206 static const char *objc_printable_name
PROTO((tree
, int));
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((enum string_section
));
247 static tree build_selector_reference_decl
PROTO((void));
249 /* Protocol additions. */
251 static tree add_protocol
PROTO((tree
));
252 static tree lookup_protocol
PROTO((tree
));
253 static tree lookup_and_install_protocols
PROTO((tree
));
257 static void encode_type_qualifiers
PROTO((tree
));
258 static void encode_pointer
PROTO((tree
, int, int));
259 static void encode_array
PROTO((tree
, int, int));
260 static void encode_aggregate
PROTO((tree
, int, int));
261 static void encode_bitfield
PROTO((int));
262 static void encode_type
PROTO((tree
, int, int));
263 static void encode_field_decl
PROTO((tree
, int, int));
265 static void really_start_method
PROTO((tree
, tree
));
266 static int comp_method_with_proto
PROTO((tree
, tree
));
267 static int comp_proto_with_proto
PROTO((tree
, tree
));
268 static tree get_arg_type_list
PROTO((tree
, int, int));
269 static tree expr_last
PROTO((tree
));
271 /* Utilities for debugging and error diagnostics. */
273 static void warn_with_method
PROTO((const char *, int, tree
));
274 static void error_with_ivar
PROTO((const char *, tree
, tree
));
275 static char *gen_method_decl
PROTO((tree
, char *));
276 static char *gen_declaration
PROTO((tree
, char *));
277 static char *gen_declarator
PROTO((tree
, 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))
287 static tree define_decl
PROTO((tree
, tree
));
288 static tree lookup_method_in_protocol_list
PROTO((tree
, tree
, int));
289 static tree lookup_protocol_in_reflist
PROTO((tree
, tree
));
290 static tree create_builtin_decl
PROTO((enum tree_code
,
291 tree
, const char *));
292 static tree my_build_string
PROTO((int, const char *));
293 static void build_objc_symtab_template
PROTO((void));
294 static tree init_def_list
PROTO((tree
));
295 static tree init_objc_symtab
PROTO((tree
));
296 static void forward_declare_categories
PROTO((void));
297 static void generate_objc_symtab_decl
PROTO((void));
298 static tree build_selector
PROTO((tree
));
300 static tree build_msg_pool_reference
PROTO((int));
302 static tree build_typed_selector_reference
PROTO((tree
, tree
));
303 static tree build_selector_reference
PROTO((tree
));
304 static tree build_class_reference_decl
PROTO((void));
305 static void add_class_reference
PROTO((tree
));
306 static tree objc_copy_list
PROTO((tree
, tree
*));
307 static tree build_protocol_template
PROTO((void));
308 static tree build_descriptor_table_initializer
PROTO((tree
, tree
));
309 static tree build_method_prototype_list_template
PROTO((tree
, int));
310 static tree build_method_prototype_template
PROTO((void));
311 static int forwarding_offset
PROTO((tree
));
312 static tree encode_method_prototype
PROTO((tree
, tree
));
313 static tree generate_descriptor_table
PROTO((tree
, const char *,
315 static void generate_method_descriptors
PROTO((tree
));
316 static tree build_tmp_function_decl
PROTO((void));
317 static void hack_method_prototype
PROTO((tree
, tree
));
318 static void generate_protocol_references
PROTO((tree
));
319 static void generate_protocols
PROTO((void));
320 static void check_ivars
PROTO((tree
, tree
));
321 static tree build_ivar_list_template
PROTO((tree
, int));
322 static tree build_method_list_template
PROTO((tree
, int));
323 static tree build_ivar_list_initializer
PROTO((tree
, tree
));
324 static tree generate_ivars_list
PROTO((tree
, const char *,
326 static tree build_dispatch_table_initializer
PROTO((tree
, tree
));
327 static tree generate_dispatch_table
PROTO((tree
, const char *,
329 static tree build_shared_structure_initializer
PROTO((tree
, tree
, tree
, tree
,
330 tree
, int, tree
, tree
,
332 static void generate_category
PROTO((tree
));
333 static int is_objc_type_qualifier
PROTO((tree
));
334 static tree adjust_type_for_id_default
PROTO((tree
));
335 static tree check_duplicates
PROTO((hash
));
336 static tree receiver_is_class_object
PROTO((tree
));
337 static int check_methods
PROTO((tree
, tree
, int));
338 static int conforms_to_protocol
PROTO((tree
, tree
));
339 static void check_protocols
PROTO((tree
, const char *,
341 static tree encode_method_def
PROTO((tree
));
342 static void gen_declspecs
PROTO((tree
, char *, int));
343 static void generate_classref_translation_entry
PROTO((tree
));
344 static void handle_class_ref
PROTO((tree
));
345 static void generate_struct_by_value_array
PROTO((void))
348 /*** Private Interface (data) ***/
350 /* Reserved tag definitions. */
353 #define TAG_OBJECT "objc_object"
354 #define TAG_CLASS "objc_class"
355 #define TAG_SUPER "objc_super"
356 #define TAG_SELECTOR "objc_selector"
358 #define UTAG_CLASS "_objc_class"
359 #define UTAG_IVAR "_objc_ivar"
360 #define UTAG_IVAR_LIST "_objc_ivar_list"
361 #define UTAG_METHOD "_objc_method"
362 #define UTAG_METHOD_LIST "_objc_method_list"
363 #define UTAG_CATEGORY "_objc_category"
364 #define UTAG_MODULE "_objc_module"
365 #define UTAG_STATICS "_objc_statics"
366 #define UTAG_SYMTAB "_objc_symtab"
367 #define UTAG_SUPER "_objc_super"
368 #define UTAG_SELECTOR "_objc_selector"
370 #define UTAG_PROTOCOL "_objc_protocol"
371 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
372 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
373 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
375 #define STRING_OBJECT_CLASS_NAME "NXConstantString"
376 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
378 static const char *TAG_GETCLASS
;
379 static const char *TAG_GETMETACLASS
;
380 static const char *TAG_MSGSEND
;
381 static const char *TAG_MSGSENDSUPER
;
382 static const char *TAG_EXECCLASS
;
384 /* Set by `continue_class' and checked by `is_public'. */
386 #define TREE_STATIC_TEMPLATE(record_type) (TREE_PUBLIC (record_type))
387 #define TYPED_OBJECT(type) \
388 (TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type))
390 /* Some commonly used instances of "identifier_node". */
392 static tree self_id
, ucmd_id
;
393 static tree unused_list
;
395 static tree self_decl
, umsg_decl
, umsg_super_decl
;
396 static tree objc_get_class_decl
, objc_get_meta_class_decl
;
398 static tree super_type
, selector_type
, id_type
, objc_class_type
;
399 static tree instance_type
, protocol_type
;
401 /* Type checking macros. */
403 #define IS_ID(TYPE) \
404 (TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (id_type))
405 #define IS_PROTOCOL_QUALIFIED_ID(TYPE) \
406 (IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE))
407 #define IS_SUPER(TYPE) \
408 (super_type && TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (super_type))
410 static tree class_chain
= NULL_TREE
;
411 static tree alias_chain
= NULL_TREE
;
412 static tree interface_chain
= NULL_TREE
;
413 static tree protocol_chain
= NULL_TREE
;
415 /* Chains to manage selectors that are referenced and defined in the
418 static tree cls_ref_chain
= NULL_TREE
; /* Classes referenced. */
419 static tree sel_ref_chain
= NULL_TREE
; /* Selectors referenced. */
421 /* Chains to manage uniquing of strings. */
423 static tree class_names_chain
= NULL_TREE
;
424 static tree meth_var_names_chain
= NULL_TREE
;
425 static tree meth_var_types_chain
= NULL_TREE
;
427 /* Hash tables to manage the global pool of method prototypes. */
429 static hash
*nst_method_hash_list
= 0;
430 static hash
*cls_method_hash_list
= 0;
432 /* Backend data declarations. */
434 static tree UOBJC_SYMBOLS_decl
;
435 static tree UOBJC_INSTANCE_VARIABLES_decl
, UOBJC_CLASS_VARIABLES_decl
;
436 static tree UOBJC_INSTANCE_METHODS_decl
, UOBJC_CLASS_METHODS_decl
;
437 static tree UOBJC_CLASS_decl
, UOBJC_METACLASS_decl
;
438 static tree UOBJC_SELECTOR_TABLE_decl
;
439 static tree UOBJC_MODULES_decl
;
440 static tree UOBJC_STRINGS_decl
;
442 /* The following are used when compiling a class implementation.
443 implementation_template will normally be an interface, however if
444 none exists this will be equal to implementation_context...it is
445 set in start_class. */
447 static tree implementation_context
= NULL_TREE
;
448 static tree implementation_template
= NULL_TREE
;
452 struct imp_entry
*next
;
455 tree class_decl
; /* _OBJC_CLASS_<my_name>; */
456 tree meta_decl
; /* _OBJC_METACLASS_<my_name>; */
459 static void handle_impent
PROTO((struct imp_entry
*));
461 static struct imp_entry
*imp_list
= 0;
462 static int imp_count
= 0; /* `@implementation' */
463 static int cat_count
= 0; /* `@category' */
465 static tree objc_class_template
, objc_category_template
, uprivate_record
;
466 static tree objc_protocol_template
, objc_selector_template
;
467 static tree ucls_super_ref
, uucls_super_ref
;
469 static tree objc_method_template
, objc_ivar_template
;
470 static tree objc_symtab_template
, objc_module_template
;
471 static tree objc_super_template
, objc_object_reference
;
473 static tree objc_object_id
, objc_class_id
, objc_id_id
;
474 static tree constant_string_id
;
475 static tree constant_string_type
;
476 static tree UOBJC_SUPER_decl
;
478 static tree method_context
= NULL_TREE
;
479 static int method_slot
= 0; /* Used by start_method_def, */
483 static char *errbuf
; /* Buffer for error diagnostics */
485 /* Data imported from tree.c. */
487 extern enum debug_info_type write_symbols
;
489 /* Data imported from toplev.c. */
491 extern const char *dump_base_name
;
493 /* Generate code for GNU or NeXT runtime environment. */
495 #ifdef NEXT_OBJC_RUNTIME
496 int flag_next_runtime
= 1;
498 int flag_next_runtime
= 0;
501 int flag_typed_selectors
;
503 /* Open and close the file for outputting class declarations, if requested. */
505 int flag_gen_declaration
= 0;
507 FILE *gen_declaration_file
;
509 /* Warn if multiple methods are seen for the same selector, but with
510 different argument types. */
512 int warn_selector
= 0;
514 /* Warn if methods required by a protocol are not implemented in the
515 class adopting it. When turned off, methods inherited to that
516 class are also considered implemented */
518 int flag_warn_protocol
= 1;
520 /* Tells "encode_pointer/encode_aggregate" whether we are generating
521 type descriptors for instance variables (as opposed to methods).
522 Type descriptors for instance variables contain more information
523 than methods (for static typing and embedded structures). This
524 was added to support features being planned for dbkit2. */
526 static int generating_instance_variables
= 0;
528 /* Tells the compiler that this is a special run. Do not perform
529 any compiling, instead we are to test some platform dependent
530 features and output a C header file with appropriate definitions. */
532 static int print_struct_values
= 0;
534 /* Some platforms pass small structures through registers versus through
535 an invisible pointer. Determine at what size structure is the
536 transition point between the two possibilities. */
539 generate_struct_by_value_array ()
542 tree field_decl
, field_decl_chain
;
544 int aggregate_in_mem
[32];
547 /* Presumbaly no platform passes 32 byte structures in a register. */
548 for (i
= 1; i
< 32; i
++)
552 /* Create an unnamed struct that has `i' character components */
553 type
= start_struct (RECORD_TYPE
, NULL_TREE
);
555 strcpy (buffer
, "c1");
556 field_decl
= create_builtin_decl (FIELD_DECL
,
559 field_decl_chain
= field_decl
;
561 for (j
= 1; j
< i
; j
++)
563 sprintf (buffer
, "c%d", j
+ 1);
564 field_decl
= create_builtin_decl (FIELD_DECL
,
567 chainon (field_decl_chain
, field_decl
);
569 finish_struct (type
, field_decl_chain
, NULL_TREE
);
571 aggregate_in_mem
[i
] = aggregate_value_p (type
);
572 if (!aggregate_in_mem
[i
])
576 /* We found some structures that are returned in registers instead of memory
577 so output the necessary data. */
580 for (i
= 31; i
>= 0; i
--)
581 if (!aggregate_in_mem
[i
])
583 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i
);
585 /* The first member of the structure is always 0 because we don't handle
586 structures with 0 members */
587 printf ("static int struct_forward_array[] = {\n 0");
589 for (j
= 1; j
<= i
; j
++)
590 printf (", %d", aggregate_in_mem
[j
]);
605 cpp_reader_init (&parse_in
);
606 parse_in
.opts
= &parse_options
;
607 cpp_options_init (&parse_options
);
615 /* The beginning of the file is a new line; check for #.
616 With luck, we discover the real source file's name from that
617 and put it in input_filename. */
618 ungetc (check_newline (), finput
);
624 /* The line number can be -1 if we had -g3 and the input file
625 had a directive specifying line 0. But we want predefined
626 functions to have a line number of 0, not -1. */
630 /* If gen_declaration desired, open the output file. */
631 if (flag_gen_declaration
)
633 register char * const dumpname
= concat (dumpname
, ".decl", NULL
);
634 gen_declaration_file
= fopen (dumpname
, "w");
635 if (gen_declaration_file
== 0)
636 pfatal_with_name (dumpname
);
640 if (flag_next_runtime
)
642 TAG_GETCLASS
= "objc_getClass";
643 TAG_GETMETACLASS
= "objc_getMetaClass";
644 TAG_MSGSEND
= "objc_msgSend";
645 TAG_MSGSENDSUPER
= "objc_msgSendSuper";
646 TAG_EXECCLASS
= "__objc_execClass";
650 TAG_GETCLASS
= "objc_get_class";
651 TAG_GETMETACLASS
= "objc_get_meta_class";
652 TAG_MSGSEND
= "objc_msg_lookup";
653 TAG_MSGSENDSUPER
= "objc_msg_lookup_super";
654 TAG_EXECCLASS
= "__objc_exec_class";
655 flag_typed_selectors
= 1;
658 if (doing_objc_thang
)
661 if (print_struct_values
)
662 generate_struct_by_value_array ();
668 fatal ("Objective-C text in C source file");
674 if (doing_objc_thang
)
675 finish_objc (); /* Objective-C finalization */
677 if (gen_declaration_file
)
678 fclose (gen_declaration_file
);
693 lang_decode_option (argc
, argv
)
697 const char *p
= argv
[0];
698 if (!strcmp (p
, "-lang-objc"))
699 doing_objc_thang
= 1;
700 else if (!strcmp (p
, "-gen-decls"))
701 flag_gen_declaration
= 1;
702 else if (!strcmp (p
, "-Wselector"))
704 else if (!strcmp (p
, "-Wno-selector"))
706 else if (!strcmp (p
, "-Wprotocol"))
707 flag_warn_protocol
= 1;
708 else if (!strcmp (p
, "-Wno-protocol"))
709 flag_warn_protocol
= 0;
710 else if (!strcmp (p
, "-fgnu-runtime"))
711 flag_next_runtime
= 0;
712 else if (!strcmp (p
, "-fno-next-runtime"))
713 flag_next_runtime
= 0;
714 else if (!strcmp (p
, "-fno-gnu-runtime"))
715 flag_next_runtime
= 1;
716 else if (!strcmp (p
, "-fnext-runtime"))
717 flag_next_runtime
= 1;
718 else if (!strcmp (p
, "-print-objc-runtime-info"))
719 print_struct_values
= 1;
721 return c_decode_option (argc
, argv
);
726 /* used by print-tree.c */
729 lang_print_xnode (file
, node
, indent
)
730 FILE *file ATTRIBUTE_UNUSED
;
731 tree node ATTRIBUTE_UNUSED
;
732 int indent ATTRIBUTE_UNUSED
;
738 define_decl (declarator
, declspecs
)
742 tree decl
= start_decl (declarator
, declspecs
, 0, NULL_TREE
, NULL_TREE
);
743 finish_decl (decl
, NULL_TREE
, NULL_TREE
);
747 /* Return 1 if LHS and RHS are compatible types for assignment or
748 various other operations. Return 0 if they are incompatible, and
749 return -1 if we choose to not decide. When the operation is
750 REFLEXIVE, check for compatibility in either direction.
752 For statically typed objects, an assignment of the form `a' = `b'
756 `a' and `b' are the same class type, or
757 `a' and `b' are of class types A and B such that B is a descendant of A. */
760 maybe_objc_comptypes (lhs
, rhs
, reflexive
)
764 if (doing_objc_thang
)
765 return objc_comptypes (lhs
, rhs
, reflexive
);
770 lookup_method_in_protocol_list (rproto_list
, sel_name
, class_meth
)
778 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
780 p
= TREE_VALUE (rproto
);
782 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
784 if ((fnd
= lookup_method (class_meth
785 ? PROTOCOL_CLS_METHODS (p
)
786 : PROTOCOL_NST_METHODS (p
), sel_name
)))
788 else if (PROTOCOL_LIST (p
))
789 fnd
= lookup_method_in_protocol_list (PROTOCOL_LIST (p
),
790 sel_name
, class_meth
);
794 ; /* An identifier...if we could not find a protocol. */
805 lookup_protocol_in_reflist (rproto_list
, lproto
)
811 /* Make sure the protocol is support by the object on the rhs. */
812 if (TREE_CODE (lproto
) == PROTOCOL_INTERFACE_TYPE
)
815 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
817 p
= TREE_VALUE (rproto
);
819 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
824 else if (PROTOCOL_LIST (p
))
825 fnd
= lookup_protocol_in_reflist (PROTOCOL_LIST (p
), lproto
);
834 ; /* An identifier...if we could not find a protocol. */
840 /* Return 1 if LHS and RHS are compatible types for assignment
841 or various other operations. Return 0 if they are incompatible,
842 and return -1 if we choose to not decide. When the operation
843 is REFLEXIVE, check for compatibility in either direction. */
846 objc_comptypes (lhs
, rhs
, reflexive
)
851 /* New clause for protocols. */
853 if (TREE_CODE (lhs
) == POINTER_TYPE
854 && TREE_CODE (TREE_TYPE (lhs
)) == RECORD_TYPE
855 && TREE_CODE (rhs
) == POINTER_TYPE
856 && TREE_CODE (TREE_TYPE (rhs
)) == RECORD_TYPE
)
858 int lhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (lhs
);
859 int rhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (rhs
);
863 tree lproto
, lproto_list
= TYPE_PROTOCOL_LIST (lhs
);
864 tree rproto
, rproto_list
;
869 rproto_list
= TYPE_PROTOCOL_LIST (rhs
);
871 /* Make sure the protocol is supported by the object
873 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
875 p
= TREE_VALUE (lproto
);
876 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
879 warning ("object does not conform to the `%s' protocol",
880 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
883 else if (TYPED_OBJECT (TREE_TYPE (rhs
)))
885 tree rname
= TYPE_NAME (TREE_TYPE (rhs
));
888 /* Make sure the protocol is supported by the object
890 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
892 p
= TREE_VALUE (lproto
);
894 rinter
= lookup_interface (rname
);
896 while (rinter
&& !rproto
)
900 rproto_list
= CLASS_PROTOCOL_LIST (rinter
);
901 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
903 /* Check for protocols adopted by categories. */
904 cat
= CLASS_CATEGORY_LIST (rinter
);
905 while (cat
&& !rproto
)
907 rproto_list
= CLASS_PROTOCOL_LIST (cat
);
908 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
910 cat
= CLASS_CATEGORY_LIST (cat
);
913 rinter
= lookup_interface (CLASS_SUPER_NAME (rinter
));
917 warning ("class `%s' does not implement the `%s' protocol",
918 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs
))),
919 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
923 /* May change...based on whether there was any mismatch */
926 else if (rhs_is_proto
)
927 /* Lhs is not a protocol...warn if it is statically typed */
928 return (TYPED_OBJECT (TREE_TYPE (lhs
)) != 0);
931 /* Defer to comptypes .*/
935 else if (TREE_CODE (lhs
) == RECORD_TYPE
&& TREE_CODE (rhs
) == RECORD_TYPE
)
936 ; /* Fall thru. This is the case we have been handling all along */
938 /* Defer to comptypes. */
941 /* `id' = `<class> *', `<class> *' = `id' */
943 if ((TYPE_NAME (lhs
) == objc_object_id
&& TYPED_OBJECT (rhs
))
944 || (TYPE_NAME (rhs
) == objc_object_id
&& TYPED_OBJECT (lhs
)))
947 /* `id' = `Class', `Class' = `id' */
949 else if ((TYPE_NAME (lhs
) == objc_object_id
950 && TYPE_NAME (rhs
) == objc_class_id
)
951 || (TYPE_NAME (lhs
) == objc_class_id
952 && TYPE_NAME (rhs
) == objc_object_id
))
955 /* `<class> *' = `<class> *' */
957 else if (TYPED_OBJECT (lhs
) && TYPED_OBJECT (rhs
))
959 tree lname
= TYPE_NAME (lhs
);
960 tree rname
= TYPE_NAME (rhs
);
966 /* If the left hand side is a super class of the right hand side,
968 for (inter
= lookup_interface (rname
); inter
;
969 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
970 if (lname
== CLASS_SUPER_NAME (inter
))
973 /* Allow the reverse when reflexive. */
975 for (inter
= lookup_interface (lname
); inter
;
976 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
977 if (rname
== CLASS_SUPER_NAME (inter
))
983 /* Defer to comptypes. */
987 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
990 objc_check_decl (decl
)
993 tree type
= TREE_TYPE (decl
);
995 if (TREE_CODE (type
) == RECORD_TYPE
996 && TREE_STATIC_TEMPLATE (type
)
997 && type
!= constant_string_type
)
999 error_with_decl (decl
, "`%s' cannot be statically allocated");
1000 fatal ("statically allocated objects not supported");
1005 maybe_objc_check_decl (decl
)
1008 if (doing_objc_thang
)
1009 objc_check_decl (decl
);
1012 /* Implement static typing. At this point, we know we have an interface. */
1015 get_static_reference (interface
, protocols
)
1019 tree type
= xref_tag (RECORD_TYPE
, interface
);
1023 tree t
, m
= TYPE_MAIN_VARIANT (type
);
1025 push_obstacks_nochange ();
1026 end_temporary_allocation ();
1027 t
= copy_node (type
);
1028 TYPE_BINFO (t
) = make_tree_vec (2);
1031 /* Add this type to the chain of variants of TYPE. */
1032 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
1033 TYPE_NEXT_VARIANT (m
) = t
;
1035 /* Look up protocols and install in lang specific list. */
1036 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
1038 /* This forces a new pointer type to be created later
1039 (in build_pointer_type)...so that the new template
1040 we just created will actually be used...what a hack! */
1041 if (TYPE_POINTER_TO (t
))
1042 TYPE_POINTER_TO (t
) = 0;
1051 get_object_reference (protocols
)
1054 tree type_decl
= lookup_name (objc_id_id
);
1057 if (type_decl
&& TREE_CODE (type_decl
) == TYPE_DECL
)
1059 type
= TREE_TYPE (type_decl
);
1060 if (TYPE_MAIN_VARIANT (type
) != id_type
)
1061 warning ("Unexpected type for `id' (%s)",
1062 gen_declaration (type
, errbuf
));
1065 fatal ("Undefined type `id', please import <objc/objc.h>");
1067 /* This clause creates a new pointer type that is qualified with
1068 the protocol specification...this info is used later to do more
1069 elaborate type checking. */
1073 tree t
, m
= TYPE_MAIN_VARIANT (type
);
1075 push_obstacks_nochange ();
1076 end_temporary_allocation ();
1077 t
= copy_node (type
);
1078 TYPE_BINFO (t
) = make_tree_vec (2);
1081 /* Add this type to the chain of variants of TYPE. */
1082 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
1083 TYPE_NEXT_VARIANT (m
) = t
;
1085 /* Look up protocols...and install in lang specific list */
1086 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
1088 /* This forces a new pointer type to be created later
1089 (in build_pointer_type)...so that the new template
1090 we just created will actually be used...what a hack! */
1091 if (TYPE_POINTER_TO (t
))
1092 TYPE_POINTER_TO (t
) = NULL
;
1100 lookup_and_install_protocols (protocols
)
1105 tree return_value
= protocols
;
1107 for (proto
= protocols
; proto
; proto
= TREE_CHAIN (proto
))
1109 tree ident
= TREE_VALUE (proto
);
1110 tree p
= lookup_protocol (ident
);
1114 error ("Cannot find protocol declaration for `%s'",
1115 IDENTIFIER_POINTER (ident
));
1117 TREE_CHAIN (prev
) = TREE_CHAIN (proto
);
1119 return_value
= TREE_CHAIN (proto
);
1123 /* Replace identifier with actual protocol node. */
1124 TREE_VALUE (proto
) = p
;
1129 return return_value
;
1132 /* Create and push a decl for a built-in external variable or field NAME.
1134 TYPE is its data type. */
1137 create_builtin_decl (code
, type
, name
)
1138 enum tree_code code
;
1142 tree decl
= build_decl (code
, get_identifier (name
), type
);
1144 if (code
== VAR_DECL
)
1146 TREE_STATIC (decl
) = 1;
1147 make_decl_rtl (decl
, 0, 1);
1151 DECL_ARTIFICIAL (decl
) = 1;
1155 /* Purpose: "play" parser, creating/installing representations
1156 of the declarations that are required by Objective-C.
1160 type_spec--------->sc_spec
1161 (tree_list) (tree_list)
1164 identifier_node identifier_node */
1167 synth_module_prologue ()
1172 /* Defined in `objc.h' */
1173 objc_object_id
= get_identifier (TAG_OBJECT
);
1175 objc_object_reference
= xref_tag (RECORD_TYPE
, objc_object_id
);
1177 id_type
= build_pointer_type (objc_object_reference
);
1179 objc_id_id
= get_identifier (TYPE_ID
);
1180 objc_class_id
= get_identifier (TAG_CLASS
);
1182 objc_class_type
= build_pointer_type (xref_tag (RECORD_TYPE
, objc_class_id
));
1183 protocol_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
1184 get_identifier (PROTOCOL_OBJECT_CLASS_NAME
)));
1186 /* Declare type of selector-objects that represent an operation name. */
1188 #ifdef OBJC_INT_SELECTORS
1189 /* `unsigned int' */
1190 selector_type
= unsigned_type_node
;
1192 /* `struct objc_selector *' */
1194 = build_pointer_type (xref_tag (RECORD_TYPE
,
1195 get_identifier (TAG_SELECTOR
)));
1196 #endif /* not OBJC_INT_SELECTORS */
1198 /* Forward declare type, or else the prototype for msgSendSuper will
1201 super_p
= build_pointer_type (xref_tag (RECORD_TYPE
,
1202 get_identifier (TAG_SUPER
)));
1205 /* id objc_msgSend (id, SEL, ...); */
1208 = build_function_type (id_type
,
1209 tree_cons (NULL_TREE
, id_type
,
1210 tree_cons (NULL_TREE
, selector_type
,
1213 if (! flag_next_runtime
)
1215 umsg_decl
= build_decl (FUNCTION_DECL
,
1216 get_identifier (TAG_MSGSEND
), temp_type
);
1217 DECL_EXTERNAL (umsg_decl
) = 1;
1218 TREE_PUBLIC (umsg_decl
) = 1;
1219 DECL_INLINE (umsg_decl
) = 1;
1220 DECL_ARTIFICIAL (umsg_decl
) = 1;
1222 if (flag_traditional
&& TAG_MSGSEND
[0] != '_')
1223 DECL_BUILT_IN_NONANSI (umsg_decl
) = 1;
1225 make_decl_rtl (umsg_decl
, NULL_PTR
, 1);
1226 pushdecl (umsg_decl
);
1229 umsg_decl
= builtin_function (TAG_MSGSEND
, temp_type
, 0, NOT_BUILT_IN
, 0);
1231 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1234 = build_function_type (id_type
,
1235 tree_cons (NULL_TREE
, super_p
,
1236 tree_cons (NULL_TREE
, selector_type
,
1239 umsg_super_decl
= builtin_function (TAG_MSGSENDSUPER
,
1240 temp_type
, 0, NOT_BUILT_IN
, 0);
1242 /* id objc_getClass (const char *); */
1244 temp_type
= build_function_type (id_type
,
1245 tree_cons (NULL_TREE
,
1246 const_string_type_node
,
1247 tree_cons (NULL_TREE
, void_type_node
,
1251 = builtin_function (TAG_GETCLASS
, temp_type
, 0, NOT_BUILT_IN
, 0);
1253 /* id objc_getMetaClass (const char *); */
1255 objc_get_meta_class_decl
1256 = builtin_function (TAG_GETMETACLASS
, temp_type
, 0, NOT_BUILT_IN
, 0);
1258 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1260 if (! flag_next_runtime
)
1262 if (flag_typed_selectors
)
1264 /* Suppress outputting debug symbols, because
1265 dbxout_init hasn'r been called yet. */
1266 enum debug_info_type save_write_symbols
= write_symbols
;
1267 write_symbols
= NO_DEBUG
;
1269 build_selector_template ();
1270 temp_type
= build_array_type (objc_selector_template
, NULL_TREE
);
1272 write_symbols
= save_write_symbols
;
1275 temp_type
= build_array_type (selector_type
, NULL_TREE
);
1277 layout_type (temp_type
);
1278 UOBJC_SELECTOR_TABLE_decl
1279 = create_builtin_decl (VAR_DECL
, temp_type
,
1280 "_OBJC_SELECTOR_TABLE");
1282 /* Avoid warning when not sending messages. */
1283 TREE_USED (UOBJC_SELECTOR_TABLE_decl
) = 1;
1286 generate_forward_declaration_to_string_table ();
1288 /* Forward declare constant_string_id and constant_string_type. */
1289 constant_string_id
= get_identifier (STRING_OBJECT_CLASS_NAME
);
1290 constant_string_type
= xref_tag (RECORD_TYPE
, constant_string_id
);
1293 /* Custom build_string which sets TREE_TYPE! */
1296 my_build_string (len
, str
)
1301 tree a_string
= build_string (len
, str
);
1303 /* Some code from combine_strings, which is local to c-parse.y. */
1304 if (TREE_TYPE (a_string
) == int_array_type_node
)
1307 TREE_TYPE (a_string
)
1308 = build_array_type (wide_flag
? integer_type_node
: char_type_node
,
1309 build_index_type (build_int_2 (len
- 1, 0)));
1311 TREE_CONSTANT (a_string
) = 1; /* Puts string in the readonly segment */
1312 TREE_STATIC (a_string
) = 1;
1317 /* Return a newly constructed OBJC_STRING_CST node whose value is
1318 the LEN characters at STR.
1319 The TREE_TYPE is not initialized. */
1322 build_objc_string (len
, str
)
1326 tree s
= build_string (len
, str
);
1328 TREE_SET_CODE (s
, OBJC_STRING_CST
);
1332 /* Given a chain of OBJC_STRING_CST's, build a static instance of
1333 NXConstanString which points at the concatenation of those strings.
1334 We place the string object in the __string_objects section of the
1335 __OBJC segment. The Objective-C runtime will initialize the isa
1336 pointers of the string objects to point at the NXConstandString class
1340 build_objc_string_object (strings
)
1343 tree string
, initlist
, constructor
;
1346 if (!doing_objc_thang
)
1349 if (lookup_interface (constant_string_id
) == NULL_TREE
)
1351 error ("Cannot find interface declaration for `%s'",
1352 IDENTIFIER_POINTER (constant_string_id
));
1353 return error_mark_node
;
1356 add_class_reference (constant_string_id
);
1358 /* Combine_strings will work for OBJC_STRING_CST's too. */
1359 string
= combine_strings (strings
);
1360 TREE_SET_CODE (string
, STRING_CST
);
1361 length
= TREE_STRING_LENGTH (string
) - 1;
1363 if (! flag_next_runtime
)
1365 push_obstacks_nochange ();
1366 end_temporary_allocation ();
1367 if (! TREE_PERMANENT (strings
))
1368 string
= my_build_string (length
+ 1,
1369 TREE_STRING_POINTER (string
));
1372 /* & ((NXConstantString) {0, string, length}) */
1374 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1376 = tree_cons (NULL_TREE
, copy_node (build_unary_op (ADDR_EXPR
, string
, 1)),
1378 initlist
= tree_cons (NULL_TREE
, build_int_2 (length
, 0), initlist
);
1379 constructor
= build_constructor (constant_string_type
, nreverse (initlist
));
1381 if (!flag_next_runtime
)
1384 = objc_add_static_instance (constructor
, constant_string_type
);
1388 return (build_unary_op (ADDR_EXPR
, constructor
, 1));
1391 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1394 objc_add_static_instance (constructor
, class_decl
)
1395 tree constructor
, class_decl
;
1397 static int num_static_inst
;
1401 push_obstacks_nochange ();
1402 end_temporary_allocation ();
1404 /* Find the list of static instances for the CLASS_DECL. Create one if
1406 for (chain
= &objc_static_instances
;
1407 *chain
&& TREE_VALUE (*chain
) != class_decl
;
1408 chain
= &TREE_CHAIN (*chain
));
1411 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
1412 add_objc_string (TYPE_NAME (class_decl
), class_names
);
1415 sprintf (buf
, "_OBJC_INSTANCE_%d", num_static_inst
++);
1416 decl
= build_decl (VAR_DECL
, get_identifier (buf
), class_decl
);
1417 DECL_COMMON (decl
) = 1;
1418 TREE_STATIC (decl
) = 1;
1419 DECL_ARTIFICIAL (decl
) = 1;
1420 pushdecl_top_level (decl
);
1421 rest_of_decl_compilation (decl
, 0, 1, 0);
1423 /* Do this here so it gets output later instead of possibly
1424 inside something else we are writing. */
1425 DECL_INITIAL (decl
) = constructor
;
1427 /* Add the DECL to the head of this CLASS' list. */
1428 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
1434 /* Build a static constant CONSTRUCTOR
1435 with type TYPE and elements ELTS. */
1438 build_constructor (type
, elts
)
1441 tree constructor
= build (CONSTRUCTOR
, type
, NULL_TREE
, elts
);
1443 TREE_CONSTANT (constructor
) = 1;
1444 TREE_STATIC (constructor
) = 1;
1445 TREE_READONLY (constructor
) = 1;
1450 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1452 /* Predefine the following data type:
1460 void *defs[cls_def_cnt + cat_def_cnt];
1464 build_objc_symtab_template ()
1466 tree field_decl
, field_decl_chain
, index
;
1468 objc_symtab_template
1469 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SYMTAB
));
1471 /* long sel_ref_cnt; */
1473 field_decl
= create_builtin_decl (FIELD_DECL
,
1474 long_integer_type_node
,
1476 field_decl_chain
= field_decl
;
1480 field_decl
= create_builtin_decl (FIELD_DECL
,
1481 build_pointer_type (selector_type
),
1483 chainon (field_decl_chain
, field_decl
);
1485 /* short cls_def_cnt; */
1487 field_decl
= create_builtin_decl (FIELD_DECL
,
1488 short_integer_type_node
,
1490 chainon (field_decl_chain
, field_decl
);
1492 /* short cat_def_cnt; */
1494 field_decl
= create_builtin_decl (FIELD_DECL
,
1495 short_integer_type_node
,
1497 chainon (field_decl_chain
, field_decl
);
1499 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1501 if (!flag_next_runtime
)
1502 index
= build_index_type (build_int_2 (imp_count
+ cat_count
, 0));
1504 index
= build_index_type (build_int_2 (imp_count
+ cat_count
- 1,
1505 imp_count
== 0 && cat_count
== 0
1507 field_decl
= create_builtin_decl (FIELD_DECL
,
1508 build_array_type (ptr_type_node
, index
),
1510 chainon (field_decl_chain
, field_decl
);
1512 finish_struct (objc_symtab_template
, field_decl_chain
, NULL_TREE
);
1515 /* Create the initial value for the `defs' field of _objc_symtab.
1516 This is a CONSTRUCTOR. */
1519 init_def_list (type
)
1522 tree expr
, initlist
= NULL_TREE
;
1523 struct imp_entry
*impent
;
1526 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1528 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
1530 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1531 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1536 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1538 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1540 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1541 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1545 if (!flag_next_runtime
)
1547 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1550 if (static_instances_decl
)
1551 expr
= build_unary_op (ADDR_EXPR
, static_instances_decl
, 0);
1553 expr
= build_int_2 (0, 0);
1555 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1558 return build_constructor (type
, nreverse (initlist
));
1561 /* Construct the initial value for all of _objc_symtab. */
1564 init_objc_symtab (type
)
1569 /* sel_ref_cnt = { ..., 5, ... } */
1571 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1573 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1575 if (flag_next_runtime
|| ! sel_ref_chain
)
1576 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1578 initlist
= tree_cons (NULL_TREE
,
1579 build_unary_op (ADDR_EXPR
,
1580 UOBJC_SELECTOR_TABLE_decl
, 1),
1583 /* cls_def_cnt = { ..., 5, ... } */
1585 initlist
= tree_cons (NULL_TREE
, build_int_2 (imp_count
, 0), initlist
);
1587 /* cat_def_cnt = { ..., 5, ... } */
1589 initlist
= tree_cons (NULL_TREE
, build_int_2 (cat_count
, 0), initlist
);
1591 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1593 if (imp_count
|| cat_count
|| static_instances_decl
)
1596 tree field
= TYPE_FIELDS (type
);
1597 field
= TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field
))));
1599 initlist
= tree_cons (NULL_TREE
, init_def_list (TREE_TYPE (field
)),
1603 return build_constructor (type
, nreverse (initlist
));
1606 /* Push forward-declarations of all the categories
1607 so that init_def_list can use them in a CONSTRUCTOR. */
1610 forward_declare_categories ()
1612 struct imp_entry
*impent
;
1613 tree sav
= implementation_context
;
1615 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1617 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1619 /* Set an invisible arg to synth_id_with_class_suffix. */
1620 implementation_context
= impent
->imp_context
;
1622 = create_builtin_decl (VAR_DECL
, objc_category_template
,
1623 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", implementation_context
)));
1626 implementation_context
= sav
;
1629 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1630 and initialized appropriately. */
1633 generate_objc_symtab_decl ()
1637 if (!objc_category_template
)
1638 build_category_template ();
1640 /* forward declare categories */
1642 forward_declare_categories ();
1644 if (!objc_symtab_template
)
1645 build_objc_symtab_template ();
1647 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
1649 UOBJC_SYMBOLS_decl
= start_decl (get_identifier ("_OBJC_SYMBOLS"),
1650 tree_cons (NULL_TREE
,
1651 objc_symtab_template
, sc_spec
),
1653 NULL_TREE
, NULL_TREE
);
1655 TREE_USED (UOBJC_SYMBOLS_decl
) = 1;
1656 DECL_IGNORED_P (UOBJC_SYMBOLS_decl
) = 1;
1657 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl
) = 1;
1658 finish_decl (UOBJC_SYMBOLS_decl
,
1659 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)),
1664 init_module_descriptor (type
)
1667 tree initlist
, expr
;
1669 /* version = { 1, ... } */
1671 expr
= build_int_2 (OBJC_VERSION
, 0);
1672 initlist
= build_tree_list (NULL_TREE
, expr
);
1674 /* size = { ..., sizeof (struct objc_module), ... } */
1676 expr
= size_in_bytes (objc_module_template
);
1677 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1679 /* name = { ..., "foo.m", ... } */
1681 expr
= add_objc_string (get_identifier (input_filename
), class_names
);
1682 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1684 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1686 if (UOBJC_SYMBOLS_decl
)
1687 expr
= build_unary_op (ADDR_EXPR
, UOBJC_SYMBOLS_decl
, 0);
1689 expr
= build_int_2 (0, 0);
1690 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1692 return build_constructor (type
, nreverse (initlist
));
1695 /* Write out the data structures to describe Objective C classes defined.
1696 If appropriate, compile and output a setup function to initialize them.
1697 Return a string which is the name of a function to call to initialize
1698 the Objective C data structures for this file (and perhaps for other files
1701 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1704 build_module_descriptor ()
1706 tree decl_specs
, field_decl
, field_decl_chain
;
1708 objc_module_template
1709 = start_struct (RECORD_TYPE
, get_identifier (UTAG_MODULE
));
1713 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1714 field_decl
= get_identifier ("version");
1716 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1717 field_decl_chain
= field_decl
;
1721 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1722 field_decl
= get_identifier ("size");
1724 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1725 chainon (field_decl_chain
, field_decl
);
1729 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
1730 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
1732 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1733 chainon (field_decl_chain
, field_decl
);
1735 /* struct objc_symtab *symtab; */
1737 decl_specs
= get_identifier (UTAG_SYMTAB
);
1738 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
1739 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("symtab"));
1741 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1742 chainon (field_decl_chain
, field_decl
);
1744 finish_struct (objc_module_template
, field_decl_chain
, NULL_TREE
);
1746 /* Create an instance of "objc_module". */
1748 decl_specs
= tree_cons (NULL_TREE
, objc_module_template
,
1749 build_tree_list (NULL_TREE
,
1750 ridpointers
[(int) RID_STATIC
]));
1752 UOBJC_MODULES_decl
= start_decl (get_identifier ("_OBJC_MODULES"),
1753 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
1755 DECL_ARTIFICIAL (UOBJC_MODULES_decl
) = 1;
1756 DECL_IGNORED_P (UOBJC_MODULES_decl
) = 1;
1757 finish_decl (UOBJC_MODULES_decl
,
1758 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl
)),
1761 /* Mark the decl to avoid "defined but not used" warning. */
1762 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl
) = 1;
1764 /* Generate a constructor call for the module descriptor.
1765 This code was generated by reading the grammar rules
1766 of c-parse.in; Therefore, it may not be the most efficient
1767 way of generating the requisite code. */
1769 if (flag_next_runtime
)
1773 tree parms
, function_decl
, decelerator
, void_list_node_1
;
1775 tree init_function_name
= get_file_function_name ('I');
1777 /* Declare void __objc_execClass (void *); */
1779 void_list_node_1
= build_tree_list (NULL_TREE
, void_type_node
);
1781 = build_function_type (void_type_node
,
1782 tree_cons (NULL_TREE
, ptr_type_node
,
1784 function_decl
= build_decl (FUNCTION_DECL
,
1785 get_identifier (TAG_EXECCLASS
),
1787 DECL_EXTERNAL (function_decl
) = 1;
1788 DECL_ARTIFICIAL (function_decl
) = 1;
1789 TREE_PUBLIC (function_decl
) = 1;
1791 pushdecl (function_decl
);
1792 rest_of_decl_compilation (function_decl
, 0, 0, 0);
1795 = build_tree_list (NULL_TREE
,
1796 build_unary_op (ADDR_EXPR
, UOBJC_MODULES_decl
, 0));
1797 decelerator
= build_function_call (function_decl
, parms
);
1799 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1801 start_function (void_list_node_1
,
1802 build_parse_node (CALL_EXPR
, init_function_name
,
1803 /* This has the format of the output
1804 of get_parm_info. */
1805 tree_cons (NULL_TREE
, NULL_TREE
,
1808 NULL_TREE
, NULL_TREE
, 0);
1809 #if 0 /* This should be turned back on later
1810 for the systems where collect is not needed. */
1811 /* Make these functions nonglobal
1812 so each file can use the same name. */
1813 TREE_PUBLIC (current_function_decl
) = 0;
1815 TREE_USED (current_function_decl
) = 1;
1816 store_parm_decls ();
1818 assemble_external (function_decl
);
1819 c_expand_expr_stmt (decelerator
);
1821 TREE_PUBLIC (current_function_decl
) = 1;
1823 function_decl
= current_function_decl
;
1824 finish_function (0);
1826 /* Return the name of the constructor function. */
1827 return XSTR (XEXP (DECL_RTL (function_decl
), 0), 0);
1831 /* extern const char _OBJC_STRINGS[]; */
1834 generate_forward_declaration_to_string_table ()
1836 tree sc_spec
, decl_specs
, expr_decl
;
1838 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_EXTERN
], NULL_TREE
);
1839 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1842 = build_nt (ARRAY_REF
, get_identifier ("_OBJC_STRINGS"), NULL_TREE
);
1844 UOBJC_STRINGS_decl
= define_decl (expr_decl
, decl_specs
);
1847 /* Return the DECL of the string IDENT in the SECTION. */
1850 get_objc_string_decl (ident
, section
)
1852 enum string_section section
;
1856 if (section
== class_names
)
1857 chain
= class_names_chain
;
1858 else if (section
== meth_var_names
)
1859 chain
= meth_var_names_chain
;
1860 else if (section
== meth_var_types
)
1861 chain
= meth_var_types_chain
;
1865 for (; chain
!= 0; chain
= TREE_VALUE (chain
))
1866 if (TREE_VALUE (chain
) == ident
)
1867 return (TREE_PURPOSE (chain
));
1873 /* Output references to all statically allocated objects. Return the DECL
1874 for the array built. */
1877 generate_static_references ()
1879 tree decls
= NULL_TREE
, ident
, decl_spec
, expr_decl
, expr
= NULL_TREE
;
1880 tree class_name
, class, decl
, initlist
;
1881 tree cl_chain
, in_chain
, type
;
1882 int num_inst
, num_class
;
1885 if (flag_next_runtime
)
1888 for (cl_chain
= objc_static_instances
, num_class
= 0;
1889 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
1891 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
1892 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
1894 sprintf (buf
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
1895 ident
= get_identifier (buf
);
1897 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1898 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1899 build_tree_list (NULL_TREE
,
1900 ridpointers
[(int) RID_STATIC
]));
1901 decl
= start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
, NULL_TREE
);
1902 DECL_CONTEXT (decl
) = 0;
1903 DECL_ARTIFICIAL (decl
) = 1;
1905 /* Output {class_name, ...}. */
1906 class = TREE_VALUE (cl_chain
);
1907 class_name
= get_objc_string_decl (TYPE_NAME (class), class_names
);
1908 initlist
= build_tree_list (NULL_TREE
,
1909 build_unary_op (ADDR_EXPR
, class_name
, 1));
1911 /* Output {..., instance, ...}. */
1912 for (in_chain
= TREE_PURPOSE (cl_chain
);
1913 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
1915 expr
= build_unary_op (ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
1916 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1919 /* Output {..., NULL}. */
1920 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1922 expr
= build_constructor (TREE_TYPE (decl
), nreverse (initlist
));
1923 finish_decl (decl
, expr
, NULL_TREE
);
1924 TREE_USED (decl
) = 1;
1926 type
= build_array_type (build_pointer_type (void_type_node
), 0);
1927 decl
= build_decl (VAR_DECL
, ident
, type
);
1928 make_decl_rtl (decl
, 0, 1);
1929 TREE_USED (decl
) = 1;
1931 = tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, decl
, 1), decls
);
1934 decls
= tree_cons (NULL_TREE
, build_int_2 (0, 0), decls
);
1935 ident
= get_identifier ("_OBJC_STATIC_INSTANCES");
1936 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1937 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1938 build_tree_list (NULL_TREE
,
1939 ridpointers
[(int) RID_STATIC
]));
1940 static_instances_decl
1941 = start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
, NULL_TREE
);
1942 TREE_USED (static_instances_decl
) = 1;
1943 DECL_CONTEXT (static_instances_decl
) = 0;
1944 DECL_ARTIFICIAL (static_instances_decl
) = 1;
1945 end_temporary_allocation ();
1946 expr
= build_constructor (TREE_TYPE (static_instances_decl
),
1948 finish_decl (static_instances_decl
, expr
, NULL_TREE
);
1951 /* Output all strings. */
1956 tree sc_spec
, decl_specs
, expr_decl
;
1957 tree chain
, string_expr
;
1960 for (chain
= class_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1962 string
= TREE_VALUE (chain
);
1963 decl
= TREE_PURPOSE (chain
);
1965 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1966 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1967 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1968 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
1969 end_temporary_allocation ();
1970 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1971 IDENTIFIER_POINTER (string
));
1972 finish_decl (decl
, string_expr
, NULL_TREE
);
1975 for (chain
= meth_var_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1977 string
= TREE_VALUE (chain
);
1978 decl
= TREE_PURPOSE (chain
);
1980 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1981 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1982 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1983 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
1984 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1985 IDENTIFIER_POINTER (string
));
1986 finish_decl (decl
, string_expr
, NULL_TREE
);
1989 for (chain
= meth_var_types_chain
; chain
; chain
= TREE_CHAIN (chain
))
1991 string
= TREE_VALUE (chain
);
1992 decl
= TREE_PURPOSE (chain
);
1994 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1995 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1996 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1997 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
1998 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1999 IDENTIFIER_POINTER (string
));
2000 finish_decl (decl
, string_expr
, NULL_TREE
);
2005 build_selector_reference_decl ()
2011 sprintf (buf
, "_OBJC_SELECTOR_REFERENCES_%d", idx
++);
2013 push_obstacks_nochange ();
2014 end_temporary_allocation ();
2016 ident
= get_identifier (buf
);
2018 decl
= build_decl (VAR_DECL
, ident
, selector_type
);
2019 DECL_EXTERNAL (decl
) = 1;
2020 TREE_PUBLIC (decl
) = 1;
2021 TREE_USED (decl
) = 1;
2022 TREE_READONLY (decl
) = 1;
2023 DECL_ARTIFICIAL (decl
) = 1;
2024 DECL_CONTEXT (decl
) = 0;
2026 make_decl_rtl (decl
, 0, 1);
2027 pushdecl_top_level (decl
);
2034 /* Just a handy wrapper for add_objc_string. */
2037 build_selector (ident
)
2040 tree expr
= add_objc_string (ident
, meth_var_names
);
2041 if (flag_typed_selectors
)
2044 return build_c_cast (selector_type
, expr
); /* cast! */
2047 /* Synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>]
2048 The cast stops the compiler from issuing the following message:
2049 grok.m: warning: initialization of non-const * pointer from const *
2050 grok.m: warning: initialization between incompatible pointer types. */
2054 build_msg_pool_reference (offset
)
2057 tree expr
= build_int_2 (offset
, 0);
2060 expr
= build_array_ref (UOBJC_STRINGS_decl
, expr
);
2061 expr
= build_unary_op (ADDR_EXPR
, expr
, 0);
2063 cast
= build_tree_list (build_tree_list (NULL_TREE
,
2064 ridpointers
[(int) RID_CHAR
]),
2065 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
2066 TREE_TYPE (expr
) = groktypename (cast
);
2071 init_selector (offset
)
2074 tree expr
= build_msg_pool_reference (offset
);
2075 TREE_TYPE (expr
) = selector_type
;
2081 build_selector_translation_table ()
2083 tree sc_spec
, decl_specs
;
2084 tree chain
, initlist
= NULL_TREE
;
2086 tree decl
= NULL_TREE
, var_decl
, name
;
2088 /* The corresponding pop_obstacks is in finish_decl,
2089 called at the end of this function. */
2090 if (! flag_next_runtime
)
2091 push_obstacks_nochange ();
2093 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
2097 expr
= build_selector (TREE_VALUE (chain
));
2099 if (flag_next_runtime
)
2101 name
= DECL_NAME (TREE_PURPOSE (chain
));
2103 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
2105 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2106 decl_specs
= tree_cons (NULL_TREE
, selector_type
, sc_spec
);
2110 /* The `decl' that is returned from start_decl is the one that we
2111 forward declared in `build_selector_reference' */
2112 decl
= start_decl (var_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2115 /* add one for the '\0' character */
2116 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (chain
)) + 1;
2118 if (flag_next_runtime
)
2119 finish_decl (decl
, expr
, NULL_TREE
);
2122 if (flag_typed_selectors
)
2124 tree eltlist
= NULL_TREE
;
2125 tree encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
2126 eltlist
= tree_cons (NULL_TREE
, expr
, NULL_TREE
);
2127 eltlist
= tree_cons (NULL_TREE
, encoding
, eltlist
);
2128 expr
= build_constructor (objc_selector_template
,
2129 nreverse (eltlist
));
2131 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2136 if (! flag_next_runtime
)
2138 /* Cause the variable and its initial value to be actually output. */
2139 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl
) = 0;
2140 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl
) = 1;
2141 /* NULL terminate the list and fix the decl for output. */
2142 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
2143 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl
) = (tree
) 1;
2144 initlist
= build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
2145 nreverse (initlist
));
2146 finish_decl (UOBJC_SELECTOR_TABLE_decl
, initlist
, NULL_TREE
);
2147 current_function_decl
= NULL_TREE
;
2152 get_proto_encoding (proto
)
2160 if (! METHOD_ENCODING (proto
))
2162 tmp_decl
= build_tmp_function_decl ();
2163 hack_method_prototype (proto
, tmp_decl
);
2164 encoding
= encode_method_prototype (proto
, tmp_decl
);
2165 METHOD_ENCODING (proto
) = encoding
;
2168 encoding
= METHOD_ENCODING (proto
);
2170 return add_objc_string (encoding
, meth_var_types
);
2173 return build_int_2 (0, 0);
2176 /* sel_ref_chain is a list whose "value" fields will be instances of
2177 identifier_node that represent the selector. */
2180 build_typed_selector_reference (ident
, proto
)
2183 tree
*chain
= &sel_ref_chain
;
2189 if (TREE_PURPOSE (*chain
) == ident
&& TREE_VALUE (*chain
) == proto
)
2190 goto return_at_index
;
2193 chain
= &TREE_CHAIN (*chain
);
2196 *chain
= perm_tree_cons (proto
, ident
, NULL_TREE
);
2199 expr
= build_unary_op (ADDR_EXPR
,
2200 build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2201 build_int_2 (index
, 0)),
2203 return build_c_cast (selector_type
, expr
);
2207 build_selector_reference (ident
)
2210 tree
*chain
= &sel_ref_chain
;
2216 if (TREE_VALUE (*chain
) == ident
)
2217 return (flag_next_runtime
2218 ? TREE_PURPOSE (*chain
)
2219 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2220 build_int_2 (index
, 0)));
2223 chain
= &TREE_CHAIN (*chain
);
2226 expr
= build_selector_reference_decl ();
2228 *chain
= perm_tree_cons (expr
, ident
, NULL_TREE
);
2230 return (flag_next_runtime
2232 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2233 build_int_2 (index
, 0)));
2237 build_class_reference_decl ()
2243 sprintf (buf
, "_OBJC_CLASS_REFERENCES_%d", idx
++);
2245 push_obstacks_nochange ();
2246 end_temporary_allocation ();
2248 ident
= get_identifier (buf
);
2250 decl
= build_decl (VAR_DECL
, ident
, objc_class_type
);
2251 DECL_EXTERNAL (decl
) = 1;
2252 TREE_PUBLIC (decl
) = 1;
2253 TREE_USED (decl
) = 1;
2254 TREE_READONLY (decl
) = 1;
2255 DECL_CONTEXT (decl
) = 0;
2256 DECL_ARTIFICIAL (decl
) = 1;
2258 make_decl_rtl (decl
, 0, 1);
2259 pushdecl_top_level (decl
);
2266 /* Create a class reference, but don't create a variable to reference
2270 add_class_reference (ident
)
2275 if ((chain
= cls_ref_chain
))
2280 if (ident
== TREE_VALUE (chain
))
2284 chain
= TREE_CHAIN (chain
);
2288 /* Append to the end of the list */
2289 TREE_CHAIN (tail
) = perm_tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2292 cls_ref_chain
= perm_tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2295 /* Get a class reference, creating it if necessary. Also create the
2296 reference variable. */
2299 get_class_reference (ident
)
2302 if (flag_next_runtime
)
2307 for (chain
= &cls_ref_chain
; *chain
; chain
= &TREE_CHAIN (*chain
))
2308 if (TREE_VALUE (*chain
) == ident
)
2310 if (! TREE_PURPOSE (*chain
))
2311 TREE_PURPOSE (*chain
) = build_class_reference_decl ();
2313 return TREE_PURPOSE (*chain
);
2316 decl
= build_class_reference_decl ();
2317 *chain
= perm_tree_cons (decl
, ident
, NULL_TREE
);
2324 add_class_reference (ident
);
2326 params
= build_tree_list (NULL_TREE
,
2327 my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
2328 IDENTIFIER_POINTER (ident
)));
2330 assemble_external (objc_get_class_decl
);
2331 return build_function_call (objc_get_class_decl
, params
);
2335 /* SEL_REFDEF_CHAIN is a list whose "value" fields will be instances
2336 of identifier_node that represent the selector. It returns the
2337 offset of the selector from the beginning of the _OBJC_STRINGS
2338 pool. This offset is typically used by init_selector during code
2341 For each string section we have a chain which maps identifier nodes
2342 to decls for the strings. */
2345 add_objc_string (ident
, section
)
2347 enum string_section section
;
2351 if (section
== class_names
)
2352 chain
= &class_names_chain
;
2353 else if (section
== meth_var_names
)
2354 chain
= &meth_var_names_chain
;
2355 else if (section
== meth_var_types
)
2356 chain
= &meth_var_types_chain
;
2362 if (TREE_VALUE (*chain
) == ident
)
2363 return build_unary_op (ADDR_EXPR
, TREE_PURPOSE (*chain
), 1);
2365 chain
= &TREE_CHAIN (*chain
);
2368 decl
= build_objc_string_decl (section
);
2370 *chain
= perm_tree_cons (decl
, ident
, NULL_TREE
);
2372 return build_unary_op (ADDR_EXPR
, decl
, 1);
2376 build_objc_string_decl (section
)
2377 enum string_section section
;
2381 static int class_names_idx
= 0;
2382 static int meth_var_names_idx
= 0;
2383 static int meth_var_types_idx
= 0;
2385 if (section
== class_names
)
2386 sprintf (buf
, "_OBJC_CLASS_NAME_%d", class_names_idx
++);
2387 else if (section
== meth_var_names
)
2388 sprintf (buf
, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx
++);
2389 else if (section
== meth_var_types
)
2390 sprintf (buf
, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx
++);
2392 push_obstacks_nochange ();
2393 end_temporary_allocation ();
2394 ident
= get_identifier (buf
);
2396 decl
= build_decl (VAR_DECL
, ident
, build_array_type (char_type_node
, 0));
2397 DECL_EXTERNAL (decl
) = 1;
2398 TREE_PUBLIC (decl
) = 1;
2399 TREE_USED (decl
) = 1;
2400 TREE_READONLY (decl
) = 1;
2401 TREE_CONSTANT (decl
) = 1;
2402 DECL_CONTEXT (decl
) = 0;
2403 DECL_ARTIFICIAL (decl
) = 1;
2405 make_decl_rtl (decl
, 0, 1);
2406 pushdecl_top_level (decl
);
2415 objc_declare_alias (alias_ident
, class_ident
)
2419 if (!doing_objc_thang
)
2422 if (is_class_name (class_ident
) != class_ident
)
2423 warning ("Cannot find class `%s'", IDENTIFIER_POINTER (class_ident
));
2424 else if (is_class_name (alias_ident
))
2425 warning ("Class `%s' already exists", IDENTIFIER_POINTER (alias_ident
));
2427 alias_chain
= tree_cons (class_ident
, alias_ident
, alias_chain
);
2431 objc_declare_class (ident_list
)
2436 if (!doing_objc_thang
)
2439 for (list
= ident_list
; list
; list
= TREE_CHAIN (list
))
2441 tree ident
= TREE_VALUE (list
);
2444 if ((decl
= lookup_name (ident
)))
2446 error ("`%s' redeclared as different kind of symbol",
2447 IDENTIFIER_POINTER (ident
));
2448 error_with_decl (decl
, "previous declaration of `%s'");
2451 if (! is_class_name (ident
))
2453 tree record
= xref_tag (RECORD_TYPE
, ident
);
2454 TREE_STATIC_TEMPLATE (record
) = 1;
2455 class_chain
= tree_cons (NULL_TREE
, ident
, class_chain
);
2461 is_class_name (ident
)
2466 if (lookup_interface (ident
))
2469 for (chain
= class_chain
; chain
; chain
= TREE_CHAIN (chain
))
2471 if (ident
== TREE_VALUE (chain
))
2475 for (chain
= alias_chain
; chain
; chain
= TREE_CHAIN (chain
))
2477 if (ident
== TREE_VALUE (chain
))
2478 return TREE_PURPOSE (chain
);
2485 lookup_interface (ident
)
2490 for (chain
= interface_chain
; chain
; chain
= TREE_CHAIN (chain
))
2492 if (ident
== CLASS_NAME (chain
))
2499 objc_copy_list (list
, head
)
2503 tree newlist
= NULL_TREE
, tail
= NULL_TREE
;
2507 tail
= copy_node (list
);
2509 /* The following statement fixes a bug when inheriting instance
2510 variables that are declared to be bitfields. finish_struct
2511 expects to find the width of the bitfield in DECL_INITIAL,
2512 which it nulls out after processing the decl of the super
2513 class...rather than change the way finish_struct works (which
2514 is risky), I create the situation it expects...s.naroff
2517 if (DECL_BIT_FIELD (tail
) && DECL_INITIAL (tail
) == 0)
2518 DECL_INITIAL (tail
) = build_int_2 (DECL_FIELD_SIZE (tail
), 0);
2520 newlist
= chainon (newlist
, tail
);
2521 list
= TREE_CHAIN (list
);
2528 /* Used by: build_private_template, get_class_ivars, and
2529 continue_class. COPY is 1 when called from @defs. In this case
2530 copy all fields. Otherwise don't copy leaf ivars since we rely on
2531 them being side-effected exactly once by finish_struct. */
2534 build_ivar_chain (interface
, copy
)
2538 tree my_name
, super_name
, ivar_chain
;
2540 my_name
= CLASS_NAME (interface
);
2541 super_name
= CLASS_SUPER_NAME (interface
);
2543 /* Possibly copy leaf ivars. */
2545 objc_copy_list (CLASS_IVARS (interface
), &ivar_chain
);
2547 ivar_chain
= CLASS_IVARS (interface
);
2552 tree super_interface
= lookup_interface (super_name
);
2554 if (!super_interface
)
2556 /* fatal did not work with 2 args...should fix */
2557 error ("Cannot find interface declaration for `%s', superclass of `%s'",
2558 IDENTIFIER_POINTER (super_name
),
2559 IDENTIFIER_POINTER (my_name
));
2560 exit (FATAL_EXIT_CODE
);
2563 if (super_interface
== interface
)
2565 fatal ("Circular inheritance in interface declaration for `%s'",
2566 IDENTIFIER_POINTER (super_name
));
2569 interface
= super_interface
;
2570 my_name
= CLASS_NAME (interface
);
2571 super_name
= CLASS_SUPER_NAME (interface
);
2573 op1
= CLASS_IVARS (interface
);
2576 tree head
, tail
= objc_copy_list (op1
, &head
);
2578 /* Prepend super class ivars...make a copy of the list, we
2579 do not want to alter the original. */
2580 TREE_CHAIN (tail
) = ivar_chain
;
2587 /* struct <classname> {
2588 struct objc_class *isa;
2593 build_private_template (class)
2598 if (CLASS_STATIC_TEMPLATE (class))
2600 uprivate_record
= CLASS_STATIC_TEMPLATE (class);
2601 ivar_context
= TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2605 uprivate_record
= start_struct (RECORD_TYPE
, CLASS_NAME (class));
2607 ivar_context
= build_ivar_chain (class, 0);
2609 finish_struct (uprivate_record
, ivar_context
, NULL_TREE
);
2611 CLASS_STATIC_TEMPLATE (class) = uprivate_record
;
2613 /* mark this record as class template - for class type checking */
2614 TREE_STATIC_TEMPLATE (uprivate_record
) = 1;
2618 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
2620 build1 (INDIRECT_REF
, NULL_TREE
,
2623 return ivar_context
;
2626 /* Begin code generation for protocols... */
2628 /* struct objc_protocol {
2629 char *protocol_name;
2630 struct objc_protocol **protocol_list;
2631 struct objc_method_desc *instance_methods;
2632 struct objc_method_desc *class_methods;
2636 build_protocol_template ()
2638 tree decl_specs
, field_decl
, field_decl_chain
;
2641 template = start_struct (RECORD_TYPE
, get_identifier (UTAG_PROTOCOL
));
2643 /* struct objc_class *isa; */
2645 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2646 get_identifier (UTAG_CLASS
)));
2647 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
2649 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2650 field_decl_chain
= field_decl
;
2652 /* char *protocol_name; */
2654 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
2656 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_name"));
2658 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2659 chainon (field_decl_chain
, field_decl
);
2661 /* struct objc_protocol **protocol_list; */
2663 decl_specs
= build_tree_list (NULL_TREE
, template);
2665 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
2666 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
2668 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2669 chainon (field_decl_chain
, field_decl
);
2671 /* struct objc_method_list *instance_methods; */
2674 = build_tree_list (NULL_TREE
,
2675 xref_tag (RECORD_TYPE
,
2676 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2678 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
2680 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2681 chainon (field_decl_chain
, field_decl
);
2683 /* struct objc_method_list *class_methods; */
2686 = build_tree_list (NULL_TREE
,
2687 xref_tag (RECORD_TYPE
,
2688 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2690 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
2692 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2693 chainon (field_decl_chain
, field_decl
);
2695 return finish_struct (template, field_decl_chain
, NULL_TREE
);
2699 build_descriptor_table_initializer (type
, entries
)
2703 tree initlist
= NULL_TREE
;
2707 tree eltlist
= NULL_TREE
;
2710 = tree_cons (NULL_TREE
,
2711 build_selector (METHOD_SEL_NAME (entries
)), NULL_TREE
);
2713 = tree_cons (NULL_TREE
,
2714 add_objc_string (METHOD_ENCODING (entries
),
2719 = tree_cons (NULL_TREE
,
2720 build_constructor (type
, nreverse (eltlist
)), initlist
);
2722 entries
= TREE_CHAIN (entries
);
2726 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
2729 /* struct objc_method_prototype_list {
2731 struct objc_method_prototype {
2738 build_method_prototype_list_template (list_type
, size
)
2742 tree objc_ivar_list_record
;
2743 tree decl_specs
, field_decl
, field_decl_chain
;
2745 /* Generate an unnamed struct definition. */
2747 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
2749 /* int method_count; */
2751 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
2752 field_decl
= get_identifier ("method_count");
2755 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2756 field_decl_chain
= field_decl
;
2758 /* struct objc_method method_list[]; */
2760 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
2761 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
2762 build_int_2 (size
, 0));
2765 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2766 chainon (field_decl_chain
, field_decl
);
2768 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
2770 return objc_ivar_list_record
;
2774 build_method_prototype_template ()
2777 tree decl_specs
, field_decl
, field_decl_chain
;
2780 = start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD_PROTOTYPE
));
2782 #ifdef OBJC_INT_SELECTORS
2783 /* unsigned int _cmd; */
2785 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_UNSIGNED
], NULL_TREE
);
2786 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_INT
], decl_specs
);
2787 field_decl
= get_identifier ("_cmd");
2788 #else /* OBJC_INT_SELECTORS */
2789 /* struct objc_selector *_cmd; */
2790 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
2791 get_identifier (TAG_SELECTOR
)), NULL_TREE
);
2792 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
2793 #endif /* OBJC_INT_SELECTORS */
2796 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2797 field_decl_chain
= field_decl
;
2799 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
2801 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_types"));
2803 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2804 chainon (field_decl_chain
, field_decl
);
2806 finish_struct (proto_record
, field_decl_chain
, NULL_TREE
);
2808 return proto_record
;
2811 /* True if last call to forwarding_offset yielded a register offset. */
2812 static int offset_is_register
;
2815 forwarding_offset (parm
)
2818 int offset_in_bytes
;
2820 if (GET_CODE (DECL_INCOMING_RTL (parm
)) == MEM
)
2822 rtx addr
= XEXP (DECL_INCOMING_RTL (parm
), 0);
2824 /* ??? Here we assume that the parm address is indexed
2825 off the frame pointer or arg pointer.
2826 If that is not true, we produce meaningless results,
2827 but do not crash. */
2828 if (GET_CODE (addr
) == PLUS
2829 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
2830 offset_in_bytes
= INTVAL (XEXP (addr
, 1));
2832 offset_in_bytes
= 0;
2834 offset_in_bytes
+= OBJC_FORWARDING_STACK_OFFSET
;
2835 offset_is_register
= 0;
2837 else if (GET_CODE (DECL_INCOMING_RTL (parm
)) == REG
)
2839 int regno
= REGNO (DECL_INCOMING_RTL (parm
));
2840 offset_in_bytes
= apply_args_register_offset (regno
);
2841 offset_is_register
= 1;
2846 /* This is the case where the parm is passed as an int or double
2847 and it is converted to a char, short or float and stored back
2848 in the parmlist. In this case, describe the parm
2849 with the variable's declared type, and adjust the address
2850 if the least significant bytes (which we are using) are not
2852 if (BYTES_BIG_ENDIAN
&& TREE_TYPE (parm
) != DECL_ARG_TYPE (parm
))
2853 offset_in_bytes
+= (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm
)))
2854 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm
))));
2856 return offset_in_bytes
;
2860 encode_method_prototype (method_decl
, func_decl
)
2867 int max_parm_end
= 0;
2871 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2872 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl
)));
2875 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
2876 obstack_object_size (&util_obstack
),
2877 OBJC_ENCODE_INLINE_DEFS
);
2880 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
2881 parms
= TREE_CHAIN (parms
))
2883 int parm_end
= (forwarding_offset (parms
)
2884 + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms
)))
2887 if (!offset_is_register
&& max_parm_end
< parm_end
)
2888 max_parm_end
= parm_end
;
2891 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
2893 sprintf (buf
, "%d", stack_size
);
2894 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2896 user_args
= METHOD_SEL_ARGS (method_decl
);
2898 /* Argument types. */
2899 for (parms
= DECL_ARGUMENTS (func_decl
), i
= 0; parms
;
2900 parms
= TREE_CHAIN (parms
), i
++)
2902 /* Process argument qualifiers for user supplied arguments. */
2905 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args
)));
2906 user_args
= TREE_CHAIN (user_args
);
2910 encode_type (TREE_TYPE (parms
),
2911 obstack_object_size (&util_obstack
),
2912 OBJC_ENCODE_INLINE_DEFS
);
2914 /* Compute offset. */
2915 sprintf (buf
, "%d", forwarding_offset (parms
));
2917 /* Indicate register. */
2918 if (offset_is_register
)
2919 obstack_1grow (&util_obstack
, '+');
2921 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2924 obstack_1grow (&util_obstack
, '\0');
2925 result
= get_identifier (obstack_finish (&util_obstack
));
2926 obstack_free (&util_obstack
, util_firstobj
);
2931 generate_descriptor_table (type
, name
, size
, list
, proto
)
2938 tree sc_spec
, decl_specs
, decl
, initlist
;
2940 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2941 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
2943 decl
= start_decl (synth_id_with_class_suffix (name
, proto
),
2944 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2946 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
2947 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
2949 finish_decl (decl
, build_constructor (type
, nreverse (initlist
)),
2956 generate_method_descriptors (protocol
) /* generate_dispatch_tables */
2959 static tree objc_method_prototype_template
;
2960 tree initlist
, chain
, method_list_template
;
2961 tree cast
, variable_length_type
;
2964 if (!objc_method_prototype_template
)
2965 objc_method_prototype_template
= build_method_prototype_template ();
2967 cast
= build_tree_list (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2968 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
))),
2970 variable_length_type
= groktypename (cast
);
2972 chain
= PROTOCOL_CLS_METHODS (protocol
);
2975 size
= list_length (chain
);
2977 method_list_template
2978 = build_method_prototype_list_template (objc_method_prototype_template
,
2982 = build_descriptor_table_initializer (objc_method_prototype_template
,
2985 UOBJC_CLASS_METHODS_decl
2986 = generate_descriptor_table (method_list_template
,
2987 "_OBJC_PROTOCOL_CLASS_METHODS",
2988 size
, initlist
, protocol
);
2989 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
2992 UOBJC_CLASS_METHODS_decl
= 0;
2994 chain
= PROTOCOL_NST_METHODS (protocol
);
2997 size
= list_length (chain
);
2999 method_list_template
3000 = build_method_prototype_list_template (objc_method_prototype_template
,
3003 = build_descriptor_table_initializer (objc_method_prototype_template
,
3006 UOBJC_INSTANCE_METHODS_decl
3007 = generate_descriptor_table (method_list_template
,
3008 "_OBJC_PROTOCOL_INSTANCE_METHODS",
3009 size
, initlist
, protocol
);
3010 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
3013 UOBJC_INSTANCE_METHODS_decl
= 0;
3017 build_tmp_function_decl ()
3019 tree decl_specs
, expr_decl
, parms
;
3023 /* struct objc_object *objc_xxx (id, SEL, ...); */
3025 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3026 push_parm_decl (build_tree_list
3027 (build_tree_list (decl_specs
,
3028 build1 (INDIRECT_REF
, NULL_TREE
,
3030 build_tree_list (NULL_TREE
, NULL_TREE
)));
3032 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3033 get_identifier (TAG_SELECTOR
)));
3034 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
);
3036 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, expr_decl
),
3037 build_tree_list (NULL_TREE
, NULL_TREE
)));
3038 parms
= get_parm_info (0);
3041 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3042 sprintf (buffer
, "__objc_tmp_%x", xxx
++);
3043 expr_decl
= build_nt (CALL_EXPR
, get_identifier (buffer
), parms
, NULL_TREE
);
3044 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
3046 return define_decl (expr_decl
, decl_specs
);
3050 hack_method_prototype (nst_methods
, tmp_decl
)
3057 /* Hack to avoid problem with static typing of self arg. */
3058 TREE_SET_CODE (nst_methods
, CLASS_METHOD_DECL
);
3059 start_method_def (nst_methods
);
3060 TREE_SET_CODE (nst_methods
, INSTANCE_METHOD_DECL
);
3062 if (METHOD_ADD_ARGS (nst_methods
) == (tree
) 1)
3063 parms
= get_parm_info (0); /* we have a `, ...' */
3065 parms
= get_parm_info (1); /* place a `void_at_end' */
3067 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
3069 /* Usually called from store_parm_decls -> init_function_start. */
3071 DECL_ARGUMENTS (tmp_decl
) = TREE_PURPOSE (parms
);
3072 current_function_decl
= tmp_decl
;
3075 /* Code taken from start_function. */
3076 tree restype
= TREE_TYPE (TREE_TYPE (tmp_decl
));
3077 /* Promote the value to int before returning it. */
3078 if (TREE_CODE (restype
) == INTEGER_TYPE
3079 && TYPE_PRECISION (restype
) < TYPE_PRECISION (integer_type_node
))
3080 restype
= integer_type_node
;
3081 DECL_RESULT (tmp_decl
) = build_decl (RESULT_DECL
, 0, restype
);
3084 for (parm
= DECL_ARGUMENTS (tmp_decl
); parm
; parm
= TREE_CHAIN (parm
))
3085 DECL_CONTEXT (parm
) = tmp_decl
;
3087 init_function_start (tmp_decl
, "objc-act", 0);
3089 /* Typically called from expand_function_start for function definitions. */
3090 assign_parms (tmp_decl
);
3092 /* install return type */
3093 TREE_TYPE (TREE_TYPE (tmp_decl
)) = groktypename (TREE_TYPE (nst_methods
));
3098 generate_protocol_references (plist
)
3103 /* Forward declare protocols referenced. */
3104 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
3106 tree proto
= TREE_VALUE (lproto
);
3108 if (TREE_CODE (proto
) == PROTOCOL_INTERFACE_TYPE
3109 && PROTOCOL_NAME (proto
))
3111 if (! PROTOCOL_FORWARD_DECL (proto
))
3112 build_protocol_reference (proto
);
3114 if (PROTOCOL_LIST (proto
))
3115 generate_protocol_references (PROTOCOL_LIST (proto
));
3121 generate_protocols ()
3123 tree p
, tmp_decl
, encoding
;
3124 tree sc_spec
, decl_specs
, decl
;
3125 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
3126 tree cast_type2
= 0;
3128 tmp_decl
= build_tmp_function_decl ();
3130 if (! objc_protocol_template
)
3131 objc_protocol_template
= build_protocol_template ();
3133 /* If a protocol was directly referenced, pull in indirect references. */
3134 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3135 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
3136 generate_protocol_references (PROTOCOL_LIST (p
));
3138 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3140 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
3141 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
3143 /* If protocol wasn't referenced, don't generate any code. */
3144 if (! PROTOCOL_FORWARD_DECL (p
))
3147 /* Make sure we link in the Protocol class. */
3148 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
3152 if (! METHOD_ENCODING (nst_methods
))
3154 hack_method_prototype (nst_methods
, tmp_decl
);
3155 encoding
= encode_method_prototype (nst_methods
, tmp_decl
);
3156 METHOD_ENCODING (nst_methods
) = encoding
;
3158 nst_methods
= TREE_CHAIN (nst_methods
);
3163 if (! METHOD_ENCODING (cls_methods
))
3165 hack_method_prototype (cls_methods
, tmp_decl
);
3166 encoding
= encode_method_prototype (cls_methods
, tmp_decl
);
3167 METHOD_ENCODING (cls_methods
) = encoding
;
3170 cls_methods
= TREE_CHAIN (cls_methods
);
3172 generate_method_descriptors (p
);
3174 if (PROTOCOL_LIST (p
))
3175 refs_decl
= generate_protocol_list (p
);
3179 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3181 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
],
3183 decl_specs
= tree_cons (NULL_TREE
, objc_protocol_template
, sc_spec
);
3185 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
),
3186 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
3188 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
3195 (build_tree_list (build_tree_list (NULL_TREE
,
3196 objc_protocol_template
),
3197 build1 (INDIRECT_REF
, NULL_TREE
,
3198 build1 (INDIRECT_REF
, NULL_TREE
,
3201 refs_expr
= build_unary_op (ADDR_EXPR
, refs_decl
, 0);
3202 TREE_TYPE (refs_expr
) = cast_type2
;
3205 refs_expr
= build_int_2 (0, 0);
3207 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3208 by generate_method_descriptors, which is called above. */
3209 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
3210 protocol_name_expr
, refs_expr
,
3211 UOBJC_INSTANCE_METHODS_decl
,
3212 UOBJC_CLASS_METHODS_decl
);
3213 finish_decl (decl
, initlist
, NULL_TREE
);
3215 /* Mark the decl as used to avoid "defined but not used" warning. */
3216 TREE_USED (decl
) = 1;
3221 build_protocol_initializer (type
, protocol_name
, protocol_list
,
3222 instance_methods
, class_methods
)
3226 tree instance_methods
;
3229 tree initlist
= NULL_TREE
, expr
;
3230 static tree cast_type
= 0;
3236 (build_tree_list (NULL_TREE
,
3237 xref_tag (RECORD_TYPE
,
3238 get_identifier (UTAG_CLASS
))),
3239 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
3241 /* Filling the "isa" in with one allows the runtime system to
3242 detect that the version change...should remove before final release. */
3244 expr
= build_int_2 (PROTOCOL_VERSION
, 0);
3245 TREE_TYPE (expr
) = cast_type
;
3246 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3247 initlist
= tree_cons (NULL_TREE
, protocol_name
, initlist
);
3248 initlist
= tree_cons (NULL_TREE
, protocol_list
, initlist
);
3250 if (!instance_methods
)
3251 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3254 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
3255 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3259 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3262 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
3263 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3266 return build_constructor (type
, nreverse (initlist
));
3269 /* struct objc_category {
3270 char *category_name;
3272 struct objc_method_list *instance_methods;
3273 struct objc_method_list *class_methods;
3274 struct objc_protocol_list *protocols;
3278 build_category_template ()
3280 tree decl_specs
, field_decl
, field_decl_chain
;
3282 objc_category_template
= start_struct (RECORD_TYPE
,
3283 get_identifier (UTAG_CATEGORY
));
3284 /* char *category_name; */
3286 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3288 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("category_name"));
3290 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3291 field_decl_chain
= field_decl
;
3293 /* char *class_name; */
3295 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3296 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_name"));
3298 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3299 chainon (field_decl_chain
, field_decl
);
3301 /* struct objc_method_list *instance_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 ("instance_methods"));
3309 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3310 chainon (field_decl_chain
, field_decl
);
3312 /* struct objc_method_list *class_methods; */
3314 decl_specs
= build_tree_list (NULL_TREE
,
3315 xref_tag (RECORD_TYPE
,
3316 get_identifier (UTAG_METHOD_LIST
)));
3318 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
3320 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3321 chainon (field_decl_chain
, field_decl
);
3323 /* struct objc_protocol **protocol_list; */
3325 decl_specs
= build_tree_list (NULL_TREE
,
3326 xref_tag (RECORD_TYPE
,
3327 get_identifier (UTAG_PROTOCOL
)));
3329 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3330 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3332 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3333 chainon (field_decl_chain
, field_decl
);
3335 finish_struct (objc_category_template
, field_decl_chain
, NULL_TREE
);
3338 /* struct objc_selector {
3344 build_selector_template ()
3347 tree decl_specs
, field_decl
, field_decl_chain
;
3349 objc_selector_template
3350 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SELECTOR
));
3354 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3355 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3357 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3358 field_decl_chain
= field_decl
;
3360 /* char *sel_type; */
3362 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3363 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_type"));
3365 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3366 chainon (field_decl_chain
, field_decl
);
3368 finish_struct (objc_selector_template
, field_decl_chain
, NULL_TREE
);
3371 /* struct objc_class {
3372 struct objc_class *isa;
3373 struct objc_class *super_class;
3378 struct objc_ivar_list *ivars;
3379 struct objc_method_list *methods;
3380 if (flag_next_runtime)
3381 struct objc_cache *cache;
3383 struct sarray *dtable;
3384 struct objc_class *subclass_list;
3385 struct objc_class *sibling_class;
3387 struct objc_protocol_list *protocols;
3388 void *gc_object_type;
3392 build_class_template ()
3394 tree decl_specs
, field_decl
, field_decl_chain
;
3397 = start_struct (RECORD_TYPE
, get_identifier (UTAG_CLASS
));
3399 /* struct objc_class *isa; */
3401 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3402 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
3404 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3405 field_decl_chain
= field_decl
;
3407 /* struct objc_class *super_class; */
3409 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3411 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("super_class"));
3413 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3414 chainon (field_decl_chain
, field_decl
);
3418 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3419 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
3421 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3422 chainon (field_decl_chain
, field_decl
);
3426 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3427 field_decl
= get_identifier ("version");
3429 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3430 chainon (field_decl_chain
, field_decl
);
3434 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3435 field_decl
= get_identifier ("info");
3437 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3438 chainon (field_decl_chain
, field_decl
);
3440 /* long instance_size; */
3442 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3443 field_decl
= get_identifier ("instance_size");
3445 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3446 chainon (field_decl_chain
, field_decl
);
3448 /* struct objc_ivar_list *ivars; */
3450 decl_specs
= build_tree_list (NULL_TREE
,
3451 xref_tag (RECORD_TYPE
,
3452 get_identifier (UTAG_IVAR_LIST
)));
3453 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivars"));
3455 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3456 chainon (field_decl_chain
, field_decl
);
3458 /* struct objc_method_list *methods; */
3460 decl_specs
= build_tree_list (NULL_TREE
,
3461 xref_tag (RECORD_TYPE
,
3462 get_identifier (UTAG_METHOD_LIST
)));
3463 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("methods"));
3465 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3466 chainon (field_decl_chain
, field_decl
);
3468 if (flag_next_runtime
)
3470 /* struct objc_cache *cache; */
3472 decl_specs
= build_tree_list (NULL_TREE
,
3473 xref_tag (RECORD_TYPE
,
3474 get_identifier ("objc_cache")));
3475 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("cache"));
3476 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3477 decl_specs
, NULL_TREE
);
3478 chainon (field_decl_chain
, field_decl
);
3482 /* struct sarray *dtable; */
3484 decl_specs
= build_tree_list (NULL_TREE
,
3485 xref_tag (RECORD_TYPE
,
3486 get_identifier ("sarray")));
3487 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("dtable"));
3488 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3489 decl_specs
, NULL_TREE
);
3490 chainon (field_decl_chain
, field_decl
);
3492 /* struct objc_class *subclass_list; */
3494 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3496 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("subclass_list"));
3497 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3498 decl_specs
, NULL_TREE
);
3499 chainon (field_decl_chain
, field_decl
);
3501 /* struct objc_class *sibling_class; */
3503 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3505 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sibling_class"));
3506 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3507 decl_specs
, NULL_TREE
);
3508 chainon (field_decl_chain
, field_decl
);
3511 /* struct objc_protocol **protocol_list; */
3513 decl_specs
= build_tree_list (NULL_TREE
,
3514 xref_tag (RECORD_TYPE
,
3515 get_identifier (UTAG_PROTOCOL
)));
3517 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3519 = build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3520 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3521 decl_specs
, NULL_TREE
);
3522 chainon (field_decl_chain
, field_decl
);
3526 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3527 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3529 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3530 chainon (field_decl_chain
, field_decl
);
3532 /* void *gc_object_type; */
3534 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3535 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("gc_object_type"));
3537 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3538 chainon (field_decl_chain
, field_decl
);
3540 finish_struct (objc_class_template
, field_decl_chain
, NULL_TREE
);
3543 /* Generate appropriate forward declarations for an implementation. */
3546 synth_forward_declarations ()
3548 tree sc_spec
, decl_specs
, an_id
;
3550 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3552 an_id
= synth_id_with_class_suffix ("_OBJC_CLASS", implementation_context
);
3554 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
3555 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
3556 UOBJC_CLASS_decl
= define_decl (an_id
, decl_specs
);
3557 TREE_USED (UOBJC_CLASS_decl
) = 1;
3558 DECL_ARTIFICIAL (UOBJC_CLASS_decl
) = 1;
3560 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3562 an_id
= synth_id_with_class_suffix ("_OBJC_METACLASS",
3563 implementation_context
);
3565 UOBJC_METACLASS_decl
= define_decl (an_id
, decl_specs
);
3566 TREE_USED (UOBJC_METACLASS_decl
) = 1;
3567 DECL_ARTIFICIAL(UOBJC_METACLASS_decl
) = 1;
3569 /* Pre-build the following entities - for speed/convenience. */
3571 an_id
= get_identifier ("super_class");
3572 ucls_super_ref
= build_component_ref (UOBJC_CLASS_decl
, an_id
);
3573 uucls_super_ref
= build_component_ref (UOBJC_METACLASS_decl
, an_id
);
3577 error_with_ivar (message
, decl
, rawdecl
)
3578 const char *message
;
3584 report_error_function (DECL_SOURCE_FILE (decl
));
3586 fprintf (stderr
, "%s:%d: ",
3587 DECL_SOURCE_FILE (decl
), DECL_SOURCE_LINE (decl
));
3588 bzero (errbuf
, BUFSIZE
);
3589 fprintf (stderr
, "%s `%s'\n", message
, gen_declaration (rawdecl
, errbuf
));
3592 #define USERTYPE(t) \
3593 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3594 || TREE_CODE (t) == ENUMERAL_TYPE)
3597 check_ivars (inter
, imp
)
3601 tree intdecls
= CLASS_IVARS (inter
);
3602 tree impdecls
= CLASS_IVARS (imp
);
3603 tree rawintdecls
= CLASS_RAW_IVARS (inter
);
3604 tree rawimpdecls
= CLASS_RAW_IVARS (imp
);
3610 if (intdecls
== 0 && impdecls
== 0)
3612 if (intdecls
== 0 || impdecls
== 0)
3614 error ("inconsistent instance variable specification");
3618 t1
= TREE_TYPE (intdecls
); t2
= TREE_TYPE (impdecls
);
3620 if (!comptypes (t1
, t2
))
3622 if (DECL_NAME (intdecls
) == DECL_NAME (impdecls
))
3624 error_with_ivar ("conflicting instance variable type",
3625 impdecls
, rawimpdecls
);
3626 error_with_ivar ("previous declaration of",
3627 intdecls
, rawintdecls
);
3629 else /* both the type and the name don't match */
3631 error ("inconsistent instance variable specification");
3636 else if (DECL_NAME (intdecls
) != DECL_NAME (impdecls
))
3638 error_with_ivar ("conflicting instance variable name",
3639 impdecls
, rawimpdecls
);
3640 error_with_ivar ("previous declaration of",
3641 intdecls
, rawintdecls
);
3644 intdecls
= TREE_CHAIN (intdecls
);
3645 impdecls
= TREE_CHAIN (impdecls
);
3646 rawintdecls
= TREE_CHAIN (rawintdecls
);
3647 rawimpdecls
= TREE_CHAIN (rawimpdecls
);
3651 /* Set super_type to the data type node for struct objc_super *,
3652 first defining struct objc_super itself.
3653 This needs to be done just once per compilation. */
3656 build_super_template ()
3658 tree record
, decl_specs
, field_decl
, field_decl_chain
;
3660 record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_SUPER
));
3662 /* struct objc_object *self; */
3664 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3665 field_decl
= get_identifier ("self");
3666 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3667 field_decl
= grokfield (input_filename
, lineno
,
3668 field_decl
, decl_specs
, NULL_TREE
);
3669 field_decl_chain
= field_decl
;
3671 /* struct objc_class *class; */
3673 decl_specs
= get_identifier (UTAG_CLASS
);
3674 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
3675 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class"));
3677 field_decl
= grokfield (input_filename
, lineno
,
3678 field_decl
, decl_specs
, NULL_TREE
);
3679 chainon (field_decl_chain
, field_decl
);
3681 finish_struct (record
, field_decl_chain
, NULL_TREE
);
3683 /* `struct objc_super *' */
3684 super_type
= groktypename (build_tree_list (build_tree_list (NULL_TREE
,
3686 build1 (INDIRECT_REF
,
3687 NULL_TREE
, NULL_TREE
)));
3691 /* struct objc_ivar {
3698 build_ivar_template ()
3700 tree objc_ivar_id
, objc_ivar_record
;
3701 tree decl_specs
, field_decl
, field_decl_chain
;
3703 objc_ivar_id
= get_identifier (UTAG_IVAR
);
3704 objc_ivar_record
= start_struct (RECORD_TYPE
, objc_ivar_id
);
3706 /* char *ivar_name; */
3708 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3709 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_name"));
3711 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3712 decl_specs
, NULL_TREE
);
3713 field_decl_chain
= field_decl
;
3715 /* char *ivar_type; */
3717 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3718 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_type"));
3720 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3721 decl_specs
, NULL_TREE
);
3722 chainon (field_decl_chain
, field_decl
);
3724 /* int ivar_offset; */
3726 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3727 field_decl
= get_identifier ("ivar_offset");
3729 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3730 decl_specs
, NULL_TREE
);
3731 chainon (field_decl_chain
, field_decl
);
3733 finish_struct (objc_ivar_record
, field_decl_chain
, NULL_TREE
);
3735 return objc_ivar_record
;
3740 struct objc_ivar ivar_list[ivar_count];
3744 build_ivar_list_template (list_type
, size
)
3748 tree objc_ivar_list_record
;
3749 tree decl_specs
, field_decl
, field_decl_chain
;
3751 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3753 /* int ivar_count; */
3755 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3756 field_decl
= get_identifier ("ivar_count");
3758 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3759 decl_specs
, NULL_TREE
);
3760 field_decl_chain
= field_decl
;
3762 /* struct objc_ivar ivar_list[]; */
3764 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3765 field_decl
= build_nt (ARRAY_REF
, get_identifier ("ivar_list"),
3766 build_int_2 (size
, 0));
3768 field_decl
= grokfield (input_filename
, lineno
,
3769 field_decl
, decl_specs
, NULL_TREE
);
3770 chainon (field_decl_chain
, field_decl
);
3772 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3774 return objc_ivar_list_record
;
3780 struct objc_method method_list[method_count];
3784 build_method_list_template (list_type
, size
)
3788 tree objc_ivar_list_record
;
3789 tree decl_specs
, field_decl
, field_decl_chain
;
3791 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3793 /* int method_next; */
3798 xref_tag (RECORD_TYPE
,
3799 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
3801 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_next"));
3802 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3803 decl_specs
, NULL_TREE
);
3804 field_decl_chain
= field_decl
;
3806 /* int method_count; */
3808 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3809 field_decl
= get_identifier ("method_count");
3811 field_decl
= grokfield (input_filename
, lineno
,
3812 field_decl
, decl_specs
, NULL_TREE
);
3813 chainon (field_decl_chain
, field_decl
);
3815 /* struct objc_method method_list[]; */
3817 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3818 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
3819 build_int_2 (size
, 0));
3821 field_decl
= grokfield (input_filename
, lineno
,
3822 field_decl
, decl_specs
, NULL_TREE
);
3823 chainon (field_decl_chain
, field_decl
);
3825 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3827 return objc_ivar_list_record
;
3831 build_ivar_list_initializer (type
, field_decl
)
3835 tree initlist
= NULL_TREE
;
3839 tree ivar
= NULL_TREE
;
3842 if (DECL_NAME (field_decl
))
3843 ivar
= tree_cons (NULL_TREE
,
3844 add_objc_string (DECL_NAME (field_decl
),
3848 /* Unnamed bit-field ivar (yuck). */
3849 ivar
= tree_cons (NULL_TREE
, build_int_2 (0, 0), ivar
);
3852 encode_field_decl (field_decl
,
3853 obstack_object_size (&util_obstack
),
3854 OBJC_ENCODE_DONT_INLINE_DEFS
);
3856 /* Null terminate string. */
3857 obstack_1grow (&util_obstack
, 0);
3861 add_objc_string (get_identifier (obstack_finish (&util_obstack
)),
3864 obstack_free (&util_obstack
, util_firstobj
);
3870 build_int_2 ((TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl
))
3875 initlist
= tree_cons (NULL_TREE
,
3876 build_constructor (type
, nreverse (ivar
)),
3879 field_decl
= TREE_CHAIN (field_decl
);
3883 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3887 generate_ivars_list (type
, name
, size
, list
)
3893 tree sc_spec
, decl_specs
, decl
, initlist
;
3895 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3896 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
3898 decl
= start_decl (synth_id_with_class_suffix (name
, implementation_context
),
3899 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
3901 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
3902 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3905 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3912 generate_ivar_lists ()
3914 tree initlist
, ivar_list_template
, chain
;
3915 tree cast
, variable_length_type
;
3918 generating_instance_variables
= 1;
3920 if (!objc_ivar_template
)
3921 objc_ivar_template
= build_ivar_template ();
3925 (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3926 get_identifier (UTAG_IVAR_LIST
))),
3928 variable_length_type
= groktypename (cast
);
3930 /* Only generate class variables for the root of the inheritance
3931 hierarchy since these will be the same for every class. */
3933 if (CLASS_SUPER_NAME (implementation_template
) == NULL_TREE
3934 && (chain
= TYPE_FIELDS (objc_class_template
)))
3936 size
= list_length (chain
);
3938 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3939 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3941 UOBJC_CLASS_VARIABLES_decl
3942 = generate_ivars_list (ivar_list_template
, "_OBJC_CLASS_VARIABLES",
3944 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl
) = variable_length_type
;
3947 UOBJC_CLASS_VARIABLES_decl
= 0;
3949 chain
= CLASS_IVARS (implementation_template
);
3952 size
= list_length (chain
);
3953 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3954 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3956 UOBJC_INSTANCE_VARIABLES_decl
3957 = generate_ivars_list (ivar_list_template
, "_OBJC_INSTANCE_VARIABLES",
3959 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl
) = variable_length_type
;
3962 UOBJC_INSTANCE_VARIABLES_decl
= 0;
3964 generating_instance_variables
= 0;
3968 build_dispatch_table_initializer (type
, entries
)
3972 tree initlist
= NULL_TREE
;
3976 tree elemlist
= NULL_TREE
;
3978 elemlist
= tree_cons (NULL_TREE
,
3979 build_selector (METHOD_SEL_NAME (entries
)),
3982 elemlist
= tree_cons (NULL_TREE
,
3983 add_objc_string (METHOD_ENCODING (entries
),
3987 elemlist
= tree_cons (NULL_TREE
,
3988 build_unary_op (ADDR_EXPR
,
3989 METHOD_DEFINITION (entries
), 1),
3992 initlist
= tree_cons (NULL_TREE
,
3993 build_constructor (type
, nreverse (elemlist
)),
3996 entries
= TREE_CHAIN (entries
);
4000 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
4003 /* To accomplish method prototyping without generating all kinds of
4004 inane warnings, the definition of the dispatch table entries were
4007 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
4009 struct objc_method { SEL _cmd; ...; void *_imp; }; */
4012 build_method_template ()
4015 tree decl_specs
, field_decl
, field_decl_chain
;
4017 _SLT_record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD
));
4019 #ifdef OBJC_INT_SELECTORS
4020 /* unsigned int _cmd; */
4021 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_UNSIGNED
],
4023 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_INT
], decl_specs
);
4024 field_decl
= get_identifier ("_cmd");
4025 #else /* not OBJC_INT_SELECTORS */
4026 /* struct objc_selector *_cmd; */
4027 decl_specs
= tree_cons (NULL_TREE
,
4028 xref_tag (RECORD_TYPE
,
4029 get_identifier (TAG_SELECTOR
)),
4031 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
4032 #endif /* not OBJC_INT_SELECTORS */
4034 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
4035 decl_specs
, NULL_TREE
);
4036 field_decl_chain
= field_decl
;
4038 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
4039 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
,
4040 get_identifier ("method_types"));
4041 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
4042 decl_specs
, NULL_TREE
);
4043 chainon (field_decl_chain
, field_decl
);
4047 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_VOID
], NULL_TREE
);
4048 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_imp"));
4049 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
4050 decl_specs
, NULL_TREE
);
4051 chainon (field_decl_chain
, field_decl
);
4053 finish_struct (_SLT_record
, field_decl_chain
, NULL_TREE
);
4060 generate_dispatch_table (type
, name
, size
, list
)
4066 tree sc_spec
, decl_specs
, decl
, initlist
;
4068 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4069 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
4071 decl
= start_decl (synth_id_with_class_suffix (name
, implementation_context
),
4072 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
4074 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
4075 initlist
= tree_cons (NULL_TREE
, build_int_2 (size
, 0), initlist
);
4076 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
4079 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
4086 generate_dispatch_tables ()
4088 tree initlist
, chain
, method_list_template
;
4089 tree cast
, variable_length_type
;
4092 if (!objc_method_template
)
4093 objc_method_template
= build_method_template ();
4097 (build_tree_list (NULL_TREE
,
4098 xref_tag (RECORD_TYPE
,
4099 get_identifier (UTAG_METHOD_LIST
))),
4102 variable_length_type
= groktypename (cast
);
4104 chain
= CLASS_CLS_METHODS (implementation_context
);
4107 size
= list_length (chain
);
4109 method_list_template
4110 = build_method_list_template (objc_method_template
, size
);
4112 = build_dispatch_table_initializer (objc_method_template
, chain
);
4114 UOBJC_CLASS_METHODS_decl
4115 = generate_dispatch_table (method_list_template
,
4116 ((TREE_CODE (implementation_context
)
4117 == CLASS_IMPLEMENTATION_TYPE
)
4118 ? "_OBJC_CLASS_METHODS"
4119 : "_OBJC_CATEGORY_CLASS_METHODS"),
4121 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
4124 UOBJC_CLASS_METHODS_decl
= 0;
4126 chain
= CLASS_NST_METHODS (implementation_context
);
4129 size
= list_length (chain
);
4131 method_list_template
4132 = build_method_list_template (objc_method_template
, size
);
4134 = build_dispatch_table_initializer (objc_method_template
, chain
);
4136 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
4137 UOBJC_INSTANCE_METHODS_decl
4138 = generate_dispatch_table (method_list_template
,
4139 "_OBJC_INSTANCE_METHODS",
4142 /* We have a category. */
4143 UOBJC_INSTANCE_METHODS_decl
4144 = generate_dispatch_table (method_list_template
,
4145 "_OBJC_CATEGORY_INSTANCE_METHODS",
4147 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
4150 UOBJC_INSTANCE_METHODS_decl
= 0;
4154 generate_protocol_list (i_or_p
)
4157 static tree cast_type
= 0;
4158 tree initlist
, decl_specs
, sc_spec
;
4159 tree refs_decl
, expr_decl
, lproto
, e
, plist
;
4162 if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
4163 || TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4164 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
4165 else if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4166 plist
= PROTOCOL_LIST (i_or_p
);
4174 (build_tree_list (NULL_TREE
,
4175 xref_tag (RECORD_TYPE
,
4176 get_identifier (UTAG_PROTOCOL
))),
4177 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
4180 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4181 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
4182 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
4185 /* Build initializer. */
4186 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), NULL_TREE
);
4188 e
= build_int_2 (size
, 0);
4189 TREE_TYPE (e
) = cast_type
;
4190 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4192 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4194 tree pval
= TREE_VALUE (lproto
);
4196 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
4197 && PROTOCOL_FORWARD_DECL (pval
))
4199 e
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (pval
), 0);
4200 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4204 /* static struct objc_protocol *refs[n]; */
4206 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4207 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
4208 get_identifier (UTAG_PROTOCOL
)),
4211 if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4212 expr_decl
= build_nt (ARRAY_REF
,
4213 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4215 build_int_2 (size
+ 2, 0));
4216 else if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
)
4217 expr_decl
= build_nt (ARRAY_REF
,
4218 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4220 build_int_2 (size
+ 2, 0));
4221 else if (TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4223 = build_nt (ARRAY_REF
,
4224 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4226 build_int_2 (size
+ 2, 0));
4230 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
4232 refs_decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
4234 finish_decl (refs_decl
, build_constructor (TREE_TYPE (refs_decl
),
4235 nreverse (initlist
)),
4242 build_category_initializer (type
, cat_name
, class_name
,
4243 instance_methods
, class_methods
, protocol_list
)
4247 tree instance_methods
;
4251 tree initlist
= NULL_TREE
, expr
;
4253 initlist
= tree_cons (NULL_TREE
, cat_name
, initlist
);
4254 initlist
= tree_cons (NULL_TREE
, class_name
, initlist
);
4256 if (!instance_methods
)
4257 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4260 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
4261 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4264 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4267 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
4268 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4271 /* protocol_list = */
4273 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4276 static tree cast_type2
;
4282 (build_tree_list (NULL_TREE
,
4283 xref_tag (RECORD_TYPE
,
4284 get_identifier (UTAG_PROTOCOL
))),
4285 build1 (INDIRECT_REF
, NULL_TREE
,
4286 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4288 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4289 TREE_TYPE (expr
) = cast_type2
;
4290 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4293 return build_constructor (type
, nreverse (initlist
));
4296 /* struct objc_class {
4297 struct objc_class *isa;
4298 struct objc_class *super_class;
4303 struct objc_ivar_list *ivars;
4304 struct objc_method_list *methods;
4305 if (flag_next_runtime)
4306 struct objc_cache *cache;
4308 struct sarray *dtable;
4309 struct objc_class *subclass_list;
4310 struct objc_class *sibling_class;
4312 struct objc_protocol_list *protocols;
4313 void *gc_object_type;
4317 build_shared_structure_initializer (type
, isa
, super
, name
, size
, status
,
4318 dispatch_table
, ivar_list
, protocol_list
)
4325 tree dispatch_table
;
4329 tree initlist
= NULL_TREE
, expr
;
4332 initlist
= tree_cons (NULL_TREE
, isa
, initlist
);
4335 initlist
= tree_cons (NULL_TREE
, super
, initlist
);
4338 initlist
= tree_cons (NULL_TREE
, default_conversion (name
), initlist
);
4341 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4344 initlist
= tree_cons (NULL_TREE
, build_int_2 (status
, 0), initlist
);
4346 /* instance_size = */
4347 initlist
= tree_cons (NULL_TREE
, size
, initlist
);
4349 /* objc_ivar_list = */
4351 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4354 expr
= build_unary_op (ADDR_EXPR
, ivar_list
, 0);
4355 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4358 /* objc_method_list = */
4359 if (!dispatch_table
)
4360 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4363 expr
= build_unary_op (ADDR_EXPR
, dispatch_table
, 0);
4364 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4367 if (flag_next_runtime
)
4368 /* method_cache = */
4369 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4373 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4375 /* subclass_list = */
4376 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4378 /* sibling_class = */
4379 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4382 /* protocol_list = */
4383 if (! protocol_list
)
4384 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4387 static tree cast_type2
;
4393 (build_tree_list (NULL_TREE
,
4394 xref_tag (RECORD_TYPE
,
4395 get_identifier (UTAG_PROTOCOL
))),
4396 build1 (INDIRECT_REF
, NULL_TREE
,
4397 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4399 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4400 TREE_TYPE (expr
) = cast_type2
;
4401 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4404 /* gc_object_type = NULL */
4405 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4407 return build_constructor (type
, nreverse (initlist
));
4410 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4413 generate_category (cat
)
4416 tree sc_spec
, decl_specs
, decl
;
4417 tree initlist
, cat_name_expr
, class_name_expr
;
4418 tree protocol_decl
, category
;
4420 add_class_reference (CLASS_NAME (cat
));
4421 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
4423 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
4425 category
= CLASS_CATEGORY_LIST (implementation_template
);
4427 /* find the category interface from the class it is associated with */
4430 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
4432 category
= CLASS_CATEGORY_LIST (category
);
4435 if (category
&& CLASS_PROTOCOL_LIST (category
))
4437 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
4438 protocol_decl
= generate_protocol_list (category
);
4443 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4444 decl_specs
= tree_cons (NULL_TREE
, objc_category_template
, sc_spec
);
4446 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4447 implementation_context
),
4448 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
4450 initlist
= build_category_initializer (TREE_TYPE (decl
),
4451 cat_name_expr
, class_name_expr
,
4452 UOBJC_INSTANCE_METHODS_decl
,
4453 UOBJC_CLASS_METHODS_decl
,
4456 TREE_USED (decl
) = 1;
4457 finish_decl (decl
, initlist
, NULL_TREE
);
4460 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4461 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4464 generate_shared_structures ()
4466 tree sc_spec
, decl_specs
, decl
;
4467 tree name_expr
, super_expr
, root_expr
;
4468 tree my_root_id
= NULL_TREE
, my_super_id
= NULL_TREE
;
4469 tree cast_type
, initlist
, protocol_decl
;
4471 my_super_id
= CLASS_SUPER_NAME (implementation_template
);
4474 add_class_reference (my_super_id
);
4476 /* Compute "my_root_id" - this is required for code generation.
4477 the "isa" for all meta class structures points to the root of
4478 the inheritance hierarchy (e.g. "__Object")... */
4479 my_root_id
= my_super_id
;
4482 tree my_root_int
= lookup_interface (my_root_id
);
4484 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
4485 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
4492 /* No super class. */
4493 my_root_id
= CLASS_NAME (implementation_template
);
4496 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
4497 objc_class_template
),
4498 build1 (INDIRECT_REF
,
4499 NULL_TREE
, NULL_TREE
)));
4501 name_expr
= add_objc_string (CLASS_NAME (implementation_template
),
4504 /* Install class `isa' and `super' pointers at runtime. */
4507 super_expr
= add_objc_string (my_super_id
, class_names
);
4508 super_expr
= build_c_cast (cast_type
, super_expr
); /* cast! */
4511 super_expr
= build_int_2 (0, 0);
4513 root_expr
= add_objc_string (my_root_id
, class_names
);
4514 root_expr
= build_c_cast (cast_type
, root_expr
); /* cast! */
4516 if (CLASS_PROTOCOL_LIST (implementation_template
))
4518 generate_protocol_references
4519 (CLASS_PROTOCOL_LIST (implementation_template
));
4520 protocol_decl
= generate_protocol_list (implementation_template
);
4525 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4527 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
4528 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
4530 decl
= start_decl (DECL_NAME (UOBJC_METACLASS_decl
), decl_specs
, 1,
4531 NULL_TREE
, NULL_TREE
);
4534 = build_shared_structure_initializer
4536 root_expr
, super_expr
, name_expr
,
4537 build_int_2 ((TREE_INT_CST_LOW (TYPE_SIZE (objc_class_template
))
4541 UOBJC_CLASS_METHODS_decl
,
4542 UOBJC_CLASS_VARIABLES_decl
,
4545 finish_decl (decl
, initlist
, NULL_TREE
);
4547 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4549 decl
= start_decl (DECL_NAME (UOBJC_CLASS_decl
), decl_specs
, 1,
4550 NULL_TREE
, NULL_TREE
);
4553 = build_shared_structure_initializer
4555 build_unary_op (ADDR_EXPR
, UOBJC_METACLASS_decl
, 0),
4556 super_expr
, name_expr
,
4559 (TYPE_SIZE (CLASS_STATIC_TEMPLATE (implementation_template
)))
4563 UOBJC_INSTANCE_METHODS_decl
,
4564 UOBJC_INSTANCE_VARIABLES_decl
,
4567 finish_decl (decl
, initlist
, NULL_TREE
);
4571 synth_id_with_class_suffix (preamble
, ctxt
)
4572 const char *preamble
;
4576 if (TREE_CODE (ctxt
) == CLASS_IMPLEMENTATION_TYPE
4577 || TREE_CODE (ctxt
) == CLASS_INTERFACE_TYPE
)
4579 const char *class_name
4580 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
4581 string
= (char *) alloca (strlen (preamble
) + strlen (class_name
) + 3);
4582 sprintf (string
, "%s_%s", preamble
,
4583 IDENTIFIER_POINTER (CLASS_NAME (ctxt
)));
4585 else if (TREE_CODE (ctxt
) == CATEGORY_IMPLEMENTATION_TYPE
4586 || TREE_CODE (ctxt
) == CATEGORY_INTERFACE_TYPE
)
4588 /* We have a category. */
4589 const char *class_name
4590 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
4591 const char *class_super_name
4592 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
));
4593 string
= (char *) alloca (strlen (preamble
)
4594 + strlen (class_name
)
4595 + strlen (class_super_name
)
4597 sprintf (string
, "%s_%s_%s", preamble
, class_name
, class_super_name
);
4599 else if (TREE_CODE (ctxt
) == PROTOCOL_INTERFACE_TYPE
)
4601 const char *protocol_name
= IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt
));
4603 = (char *) alloca (strlen (preamble
) + strlen (protocol_name
) + 3);
4604 sprintf (string
, "%s_%s", preamble
, protocol_name
);
4609 return get_identifier (string
);
4613 is_objc_type_qualifier (node
)
4616 return (TREE_CODE (node
) == IDENTIFIER_NODE
4617 && (node
== ridpointers
[(int) RID_CONST
]
4618 || node
== ridpointers
[(int) RID_VOLATILE
]
4619 || node
== ridpointers
[(int) RID_IN
]
4620 || node
== ridpointers
[(int) RID_OUT
]
4621 || node
== ridpointers
[(int) RID_INOUT
]
4622 || node
== ridpointers
[(int) RID_BYCOPY
]
4623 || node
== ridpointers
[(int) RID_BYREF
]
4624 || node
== ridpointers
[(int) RID_ONEWAY
]));
4627 /* If type is empty or only type qualifiers are present, add default
4628 type of id (otherwise grokdeclarator will default to int). */
4631 adjust_type_for_id_default (type
)
4634 tree declspecs
, chain
;
4637 return build_tree_list (build_tree_list (NULL_TREE
, objc_object_reference
),
4638 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4640 declspecs
= TREE_PURPOSE (type
);
4642 /* Determine if a typespec is present. */
4643 for (chain
= declspecs
;
4645 chain
= TREE_CHAIN (chain
))
4647 if (!is_objc_type_qualifier (TREE_VALUE (chain
)))
4651 return build_tree_list (tree_cons (NULL_TREE
, objc_object_reference
,
4653 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4658 selector ':' '(' typename ')' identifier
4661 Transform an Objective-C keyword argument into
4662 the C equivalent parameter declarator.
4664 In: key_name, an "identifier_node" (optional).
4665 arg_type, a "tree_list" (optional).
4666 arg_name, an "identifier_node".
4668 Note: It would be really nice to strongly type the preceding
4669 arguments in the function prototype; however, then I
4670 could not use the "accessor" macros defined in "tree.h".
4672 Out: an instance of "keyword_decl". */
4675 build_keyword_decl (key_name
, arg_type
, arg_name
)
4682 /* If no type is specified, default to "id". */
4683 arg_type
= adjust_type_for_id_default (arg_type
);
4685 keyword_decl
= make_node (KEYWORD_DECL
);
4687 TREE_TYPE (keyword_decl
) = arg_type
;
4688 KEYWORD_ARG_NAME (keyword_decl
) = arg_name
;
4689 KEYWORD_KEY_NAME (keyword_decl
) = key_name
;
4691 return keyword_decl
;
4694 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4697 build_keyword_selector (selector
)
4701 tree key_chain
, key_name
;
4704 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4706 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4707 key_name
= KEYWORD_KEY_NAME (key_chain
);
4708 else if (TREE_CODE (selector
) == TREE_LIST
)
4709 key_name
= TREE_PURPOSE (key_chain
);
4714 len
+= IDENTIFIER_LENGTH (key_name
) + 1;
4716 /* Just a ':' arg. */
4720 buf
= (char *)alloca (len
+ 1);
4721 bzero (buf
, len
+ 1);
4723 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4725 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4726 key_name
= KEYWORD_KEY_NAME (key_chain
);
4727 else if (TREE_CODE (selector
) == TREE_LIST
)
4728 key_name
= TREE_PURPOSE (key_chain
);
4733 strcat (buf
, IDENTIFIER_POINTER (key_name
));
4737 return get_identifier (buf
);
4740 /* Used for declarations and definitions. */
4743 build_method_decl (code
, ret_type
, selector
, add_args
)
4744 enum tree_code code
;
4751 /* If no type is specified, default to "id". */
4752 ret_type
= adjust_type_for_id_default (ret_type
);
4754 method_decl
= make_node (code
);
4755 TREE_TYPE (method_decl
) = ret_type
;
4757 /* If we have a keyword selector, create an identifier_node that
4758 represents the full selector name (`:' included)... */
4759 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4761 METHOD_SEL_NAME (method_decl
) = build_keyword_selector (selector
);
4762 METHOD_SEL_ARGS (method_decl
) = selector
;
4763 METHOD_ADD_ARGS (method_decl
) = add_args
;
4767 METHOD_SEL_NAME (method_decl
) = selector
;
4768 METHOD_SEL_ARGS (method_decl
) = NULL_TREE
;
4769 METHOD_ADD_ARGS (method_decl
) = NULL_TREE
;
4775 #define METHOD_DEF 0
4776 #define METHOD_REF 1
4778 /* Used by `build_message_expr' and `comp_method_types'. Return an
4779 argument list for method METH. CONTEXT is either METHOD_DEF or
4780 METHOD_REF, saying whether we are trying to define a method or call
4781 one. SUPERFLAG says this is for a send to super; this makes a
4782 difference for the NeXT calling sequence in which the lookup and
4783 the method call are done together. */
4786 get_arg_type_list (meth
, context
, superflag
)
4793 /* Receiver type. */
4794 if (flag_next_runtime
&& superflag
)
4795 arglist
= build_tree_list (NULL_TREE
, super_type
);
4796 else if (context
== METHOD_DEF
)
4797 arglist
= build_tree_list (NULL_TREE
, TREE_TYPE (self_decl
));
4799 arglist
= build_tree_list (NULL_TREE
, id_type
);
4801 /* Selector type - will eventually change to `int'. */
4802 chainon (arglist
, build_tree_list (NULL_TREE
, selector_type
));
4804 /* Build a list of argument types. */
4805 for (akey
= METHOD_SEL_ARGS (meth
); akey
; akey
= TREE_CHAIN (akey
))
4807 tree arg_decl
= groktypename_in_parm_context (TREE_TYPE (akey
));
4808 chainon (arglist
, build_tree_list (NULL_TREE
, TREE_TYPE (arg_decl
)));
4811 if (METHOD_ADD_ARGS (meth
) == (tree
)1)
4812 /* We have a `, ...' immediately following the selector,
4813 finalize the arglist...simulate get_parm_info (0). */
4815 else if (METHOD_ADD_ARGS (meth
))
4817 /* we have a variable length selector */
4818 tree add_arg_list
= TREE_CHAIN (METHOD_ADD_ARGS (meth
));
4819 chainon (arglist
, add_arg_list
);
4822 /* finalize the arglist...simulate get_parm_info (1) */
4823 chainon (arglist
, build_tree_list (NULL_TREE
, void_type_node
));
4829 check_duplicates (hsh
)
4832 tree meth
= NULL_TREE
;
4840 /* We have two methods with the same name and different types. */
4842 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
) ? '-' : '+';
4844 warning ("multiple declarations for method `%s'",
4845 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
4847 warn_with_method ("using", type
, meth
);
4848 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
4849 warn_with_method ("also found", type
, loop
->value
);
4855 /* If RECEIVER is a class reference, return the identifier node for the
4856 referenced class. RECEIVER is created by get_class_reference, so we
4857 check the exact form created depending on which runtimes are used. */
4860 receiver_is_class_object (receiver
)
4863 tree chain
, exp
, arg
;
4864 if (flag_next_runtime
)
4866 /* The receiver is a variable created by build_class_reference_decl. */
4867 if (TREE_CODE (receiver
) == VAR_DECL
4868 && TREE_TYPE (receiver
) == objc_class_type
)
4869 /* Look up the identifier. */
4870 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
4871 if (TREE_PURPOSE (chain
) == receiver
)
4872 return TREE_VALUE (chain
);
4876 /* The receiver is a function call that returns an id. Check if
4877 it is a call to objc_getClass, if so, pick up the class name. */
4878 if ((exp
= TREE_OPERAND (receiver
, 0))
4879 && TREE_CODE (exp
) == ADDR_EXPR
4880 && (exp
= TREE_OPERAND (exp
, 0))
4881 && TREE_CODE (exp
) == FUNCTION_DECL
4882 && exp
== objc_get_class_decl
4883 /* we have a call to objc_getClass! */
4884 && (arg
= TREE_OPERAND (receiver
, 1))
4885 && TREE_CODE (arg
) == TREE_LIST
4886 && (arg
= TREE_VALUE (arg
)))
4889 if (TREE_CODE (arg
) == ADDR_EXPR
4890 && (arg
= TREE_OPERAND (arg
, 0))
4891 && TREE_CODE (arg
) == STRING_CST
)
4892 /* Finally, we have the class name. */
4893 return get_identifier (TREE_STRING_POINTER (arg
));
4899 /* If we are currently building a message expr, this holds
4900 the identifier of the selector of the message. This is
4901 used when printing warnings about argument mismatches. */
4903 static tree building_objc_message_expr
= 0;
4906 maybe_building_objc_message_expr ()
4908 return building_objc_message_expr
;
4911 /* Construct an expression for sending a message.
4912 MESS has the object to send to in TREE_PURPOSE
4913 and the argument list (including selector) in TREE_VALUE.
4915 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4916 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4919 build_message_expr (mess
)
4922 tree receiver
= TREE_PURPOSE (mess
);
4923 tree selector
, self_object
;
4924 tree rtype
, sel_name
;
4925 tree args
= TREE_VALUE (mess
);
4926 tree method_params
= NULL_TREE
;
4927 tree method_prototype
= NULL_TREE
;
4929 int statically_typed
= 0, statically_allocated
= 0;
4930 tree class_ident
= 0;
4932 /* 1 if this is sending to the superclass. */
4935 if (!doing_objc_thang
)
4938 if (TREE_CODE (receiver
) == ERROR_MARK
)
4939 return error_mark_node
;
4941 /* Determine receiver type. */
4942 rtype
= TREE_TYPE (receiver
);
4943 super
= IS_SUPER (rtype
);
4947 if (TREE_STATIC_TEMPLATE (rtype
))
4948 statically_allocated
= 1;
4949 else if (TREE_CODE (rtype
) == POINTER_TYPE
4950 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype
)))
4951 statically_typed
= 1;
4952 else if ((flag_next_runtime
4953 || (TREE_CODE (receiver
) == CALL_EXPR
&& IS_ID (rtype
)))
4954 && (class_ident
= receiver_is_class_object (receiver
)))
4956 else if (! IS_ID (rtype
)
4957 /* Allow any type that matches objc_class_type. */
4958 && ! comptypes (rtype
, objc_class_type
))
4960 bzero (errbuf
, BUFSIZE
);
4961 warning ("invalid receiver type `%s'",
4962 gen_declaration (rtype
, errbuf
));
4965 if (statically_allocated
)
4966 receiver
= build_unary_op (ADDR_EXPR
, receiver
, 0);
4968 /* Don't evaluate the receiver twice. */
4969 receiver
= save_expr (receiver
);
4970 self_object
= receiver
;
4973 /* If sending to `super', use current self as the object. */
4974 self_object
= self_decl
;
4976 /* Obtain the full selector name. */
4978 if (TREE_CODE (args
) == IDENTIFIER_NODE
)
4979 /* A unary selector. */
4981 else if (TREE_CODE (args
) == TREE_LIST
)
4982 sel_name
= build_keyword_selector (args
);
4986 /* Build the parameter list to give to the method. */
4988 method_params
= NULL_TREE
;
4989 if (TREE_CODE (args
) == TREE_LIST
)
4991 tree chain
= args
, prev
= NULL_TREE
;
4993 /* We have a keyword selector--check for comma expressions. */
4996 tree element
= TREE_VALUE (chain
);
4998 /* We have a comma expression, must collapse... */
4999 if (TREE_CODE (element
) == TREE_LIST
)
5002 TREE_CHAIN (prev
) = element
;
5007 chain
= TREE_CHAIN (chain
);
5009 method_params
= args
;
5012 /* Determine operation return type. */
5014 if (IS_SUPER (rtype
))
5018 if (CLASS_SUPER_NAME (implementation_template
))
5021 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
5023 if (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
)
5024 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5026 method_prototype
= lookup_class_method_static (iface
, sel_name
);
5028 if (iface
&& !method_prototype
)
5029 warning ("`%s' does not respond to `%s'",
5030 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template
)),
5031 IDENTIFIER_POINTER (sel_name
));
5035 error ("no super class declared in interface for `%s'",
5036 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
5037 return error_mark_node
;
5041 else if (statically_allocated
)
5043 tree ctype
= TREE_TYPE (rtype
);
5044 tree iface
= lookup_interface (TYPE_NAME (rtype
));
5047 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5049 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
5051 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
5054 if (!method_prototype
)
5055 warning ("`%s' does not respond to `%s'",
5056 IDENTIFIER_POINTER (TYPE_NAME (rtype
)),
5057 IDENTIFIER_POINTER (sel_name
));
5059 else if (statically_typed
)
5061 tree ctype
= TREE_TYPE (rtype
);
5063 /* `self' is now statically_typed. All methods should be visible
5064 within the context of the implementation. */
5065 if (implementation_context
5066 && CLASS_NAME (implementation_context
) == TYPE_NAME (ctype
))
5069 = lookup_instance_method_static (implementation_template
,
5072 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
5074 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
5077 if (! method_prototype
5078 && implementation_template
!= implementation_context
)
5079 /* The method is not published in the interface. Check
5082 = lookup_method (CLASS_NST_METHODS (implementation_context
),
5089 if ((iface
= lookup_interface (TYPE_NAME (ctype
))))
5090 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5092 if (! method_prototype
)
5094 tree protocol_list
= TYPE_PROTOCOL_LIST (ctype
);
5097 = lookup_method_in_protocol_list (protocol_list
,
5102 if (!method_prototype
)
5103 warning ("`%s' does not respond to `%s'",
5104 IDENTIFIER_POINTER (TYPE_NAME (ctype
)),
5105 IDENTIFIER_POINTER (sel_name
));
5107 else if (class_ident
)
5109 if (implementation_context
5110 && CLASS_NAME (implementation_context
) == class_ident
)
5113 = lookup_class_method_static (implementation_template
, sel_name
);
5115 if (!method_prototype
5116 && implementation_template
!= implementation_context
)
5117 /* The method is not published in the interface. Check
5120 = lookup_method (CLASS_CLS_METHODS (implementation_context
),
5127 if ((iface
= lookup_interface (class_ident
)))
5128 method_prototype
= lookup_class_method_static (iface
, sel_name
);
5131 if (!method_prototype
)
5133 warning ("cannot find class (factory) method.");
5134 warning ("return type for `%s' defaults to id",
5135 IDENTIFIER_POINTER (sel_name
));
5138 else if (IS_PROTOCOL_QUALIFIED_ID (rtype
))
5140 /* An anonymous object that has been qualified with a protocol. */
5142 tree protocol_list
= TYPE_PROTOCOL_LIST (rtype
);
5144 method_prototype
= lookup_method_in_protocol_list (protocol_list
,
5147 if (!method_prototype
)
5151 warning ("method `%s' not implemented by protocol.",
5152 IDENTIFIER_POINTER (sel_name
));
5154 /* Try and find the method signature in the global pools. */
5156 if (!(hsh
= hash_lookup (nst_method_hash_list
, sel_name
)))
5157 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5159 if (!(method_prototype
= check_duplicates (hsh
)))
5160 warning ("return type defaults to id");
5167 /* We think we have an instance...loophole: extern id Object; */
5168 hsh
= hash_lookup (nst_method_hash_list
, sel_name
);
5170 /* For various loopholes, like sending messages to self in a
5172 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5174 method_prototype
= check_duplicates (hsh
);
5175 if (!method_prototype
)
5177 warning ("cannot find method.");
5178 warning ("return type for `%s' defaults to id",
5179 IDENTIFIER_POINTER (sel_name
));
5183 /* Save the selector name for printing error messages. */
5184 building_objc_message_expr
= sel_name
;
5186 /* Build the parameters list for looking up the method.
5187 These are the object itself and the selector. */
5189 if (flag_typed_selectors
)
5190 selector
= build_typed_selector_reference (sel_name
, method_prototype
);
5192 selector
= build_selector_reference (sel_name
);
5194 retval
= build_objc_method_call (super
, method_prototype
,
5195 receiver
, self_object
,
5196 selector
, method_params
);
5198 building_objc_message_expr
= 0;
5203 /* Build a tree expression to send OBJECT the operation SELECTOR,
5204 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5205 assuming the method has prototype METHOD_PROTOTYPE.
5206 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5207 Use METHOD_PARAMS as list of args to pass to the method.
5208 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5211 build_objc_method_call (super_flag
, method_prototype
, lookup_object
, object
,
5212 selector
, method_params
)
5214 tree method_prototype
, lookup_object
, object
, selector
, method_params
;
5216 tree sender
= (super_flag
? umsg_super_decl
: umsg_decl
);
5217 tree rcv_p
= (super_flag
5218 ? build_pointer_type (xref_tag (RECORD_TYPE
,
5219 get_identifier (TAG_SUPER
)))
5222 if (flag_next_runtime
)
5224 if (! method_prototype
)
5226 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5227 tree_cons (NULL_TREE
, selector
,
5229 assemble_external (sender
);
5230 return build_function_call (sender
, method_params
);
5234 /* This is a real kludge, but it is used only for the Next.
5235 Clobber the data type of SENDER temporarily to accept
5236 all the arguments for this operation, and to return
5237 whatever this operation returns. */
5238 tree arglist
= NULL_TREE
;
5241 /* Save the proper contents of SENDER's data type. */
5242 tree savarg
= TYPE_ARG_TYPES (TREE_TYPE (sender
));
5243 tree savret
= TREE_TYPE (TREE_TYPE (sender
));
5245 /* Install this method's argument types. */
5246 arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5248 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = arglist
;
5250 /* Install this method's return type. */
5251 TREE_TYPE (TREE_TYPE (sender
))
5252 = groktypename (TREE_TYPE (method_prototype
));
5254 /* Call SENDER with all the parameters. This will do type
5255 checking using the arg types for this method. */
5256 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5257 tree_cons (NULL_TREE
, selector
,
5259 assemble_external (sender
);
5260 retval
= build_function_call (sender
, method_params
);
5262 /* Restore SENDER's return/argument types. */
5263 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = savarg
;
5264 TREE_TYPE (TREE_TYPE (sender
)) = savret
;
5270 /* This is the portable way.
5271 First call the lookup function to get a pointer to the method,
5272 then cast the pointer, then call it with the method arguments. */
5275 /* Avoid trouble since we may evaluate each of these twice. */
5276 object
= save_expr (object
);
5277 selector
= save_expr (selector
);
5279 lookup_object
= build_c_cast (rcv_p
, lookup_object
);
5281 assemble_external (sender
);
5283 = build_function_call (sender
,
5284 tree_cons (NULL_TREE
, lookup_object
,
5285 tree_cons (NULL_TREE
, selector
,
5288 /* If we have a method prototype, construct the data type this
5289 method needs, and cast what we got from SENDER into a pointer
5291 if (method_prototype
)
5293 tree arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5295 tree valtype
= groktypename (TREE_TYPE (method_prototype
));
5296 tree fake_function_type
= build_function_type (valtype
, arglist
);
5297 TREE_TYPE (method
) = build_pointer_type (fake_function_type
);
5301 = build_pointer_type (build_function_type (ptr_type_node
, NULL_TREE
));
5303 /* Pass the object to the method. */
5304 assemble_external (method
);
5305 return build_function_call (method
,
5306 tree_cons (NULL_TREE
, object
,
5307 tree_cons (NULL_TREE
, selector
,
5313 build_protocol_reference (p
)
5316 tree decl
, ident
, ptype
;
5318 push_obstacks_nochange ();
5319 end_temporary_allocation ();
5321 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5323 ident
= synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
);
5325 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
5326 objc_protocol_template
),
5329 if (IDENTIFIER_GLOBAL_VALUE (ident
))
5330 decl
= IDENTIFIER_GLOBAL_VALUE (ident
); /* Set by pushdecl. */
5333 decl
= build_decl (VAR_DECL
, ident
, ptype
);
5334 DECL_EXTERNAL (decl
) = 1;
5335 TREE_PUBLIC (decl
) = 1;
5336 TREE_USED (decl
) = 1;
5337 DECL_ARTIFICIAL (decl
) = 1;
5339 make_decl_rtl (decl
, 0, 1);
5340 pushdecl_top_level (decl
);
5343 PROTOCOL_FORWARD_DECL (p
) = decl
;
5348 build_protocol_expr (protoname
)
5354 if (!doing_objc_thang
)
5357 p
= lookup_protocol (protoname
);
5361 error ("Cannot find protocol declaration for `%s'",
5362 IDENTIFIER_POINTER (protoname
));
5363 return error_mark_node
;
5366 if (!PROTOCOL_FORWARD_DECL (p
))
5367 build_protocol_reference (p
);
5369 expr
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
5371 TREE_TYPE (expr
) = protocol_type
;
5377 build_selector_expr (selnamelist
)
5382 if (!doing_objc_thang
)
5385 /* Obtain the full selector name. */
5386 if (TREE_CODE (selnamelist
) == IDENTIFIER_NODE
)
5387 /* A unary selector. */
5388 selname
= selnamelist
;
5389 else if (TREE_CODE (selnamelist
) == TREE_LIST
)
5390 selname
= build_keyword_selector (selnamelist
);
5394 if (flag_typed_selectors
)
5395 return build_typed_selector_reference (selname
, 0);
5397 return build_selector_reference (selname
);
5401 build_encode_expr (type
)
5407 if (!doing_objc_thang
)
5410 encode_type (type
, obstack_object_size (&util_obstack
),
5411 OBJC_ENCODE_INLINE_DEFS
);
5412 obstack_1grow (&util_obstack
, 0); /* null terminate string */
5413 string
= obstack_finish (&util_obstack
);
5415 /* Synthesize a string that represents the encoded struct/union. */
5416 result
= my_build_string (strlen (string
) + 1, string
);
5417 obstack_free (&util_obstack
, util_firstobj
);
5422 build_ivar_reference (id
)
5425 if (TREE_CODE (method_context
) == CLASS_METHOD_DECL
)
5427 /* Historically, a class method that produced objects (factory
5428 method) would assign `self' to the instance that it
5429 allocated. This would effectively turn the class method into
5430 an instance method. Following this assignment, the instance
5431 variables could be accessed. That practice, while safe,
5432 violates the simple rule that a class method should not refer
5433 to an instance variable. It's better to catch the cases
5434 where this is done unknowingly than to support the above
5436 warning ("instance variable `%s' accessed in class method",
5437 IDENTIFIER_POINTER (id
));
5438 TREE_TYPE (self_decl
) = instance_type
; /* cast */
5441 return build_component_ref (build_indirect_ref (self_decl
, "->"), id
);
5444 #define HASH_ALLOC_LIST_SIZE 170
5445 #define ATTR_ALLOC_LIST_SIZE 170
5446 #define SIZEHASHTABLE 257
5449 #define HASHFUNCTION(key) ((HOST_WIDE_INT) key & 0x7fffffff)
5454 nst_method_hash_list
= (hash
*)xmalloc (SIZEHASHTABLE
* sizeof (hash
));
5455 cls_method_hash_list
= (hash
*)xmalloc (SIZEHASHTABLE
* sizeof (hash
));
5457 if (!nst_method_hash_list
|| !cls_method_hash_list
)
5458 perror ("unable to allocate space in objc-tree.c");
5463 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
5465 nst_method_hash_list
[i
] = 0;
5466 cls_method_hash_list
[i
] = 0;
5472 hash_enter (hashlist
, method
)
5476 static hash hash_alloc_list
= 0;
5477 static int hash_alloc_index
= 0;
5479 int slot
= HASHFUNCTION (METHOD_SEL_NAME (method
)) % SIZEHASHTABLE
;
5481 if (! hash_alloc_list
|| hash_alloc_index
>= HASH_ALLOC_LIST_SIZE
)
5483 hash_alloc_index
= 0;
5484 hash_alloc_list
= (hash
) xmalloc (sizeof (struct hashed_entry
)
5485 * HASH_ALLOC_LIST_SIZE
);
5486 if (! hash_alloc_list
)
5487 perror ("unable to allocate in objc-tree.c");
5489 obj
= &hash_alloc_list
[hash_alloc_index
++];
5491 obj
->next
= hashlist
[slot
];
5494 hashlist
[slot
] = obj
; /* append to front */
5498 hash_lookup (hashlist
, sel_name
)
5504 target
= hashlist
[HASHFUNCTION (sel_name
) % SIZEHASHTABLE
];
5508 if (sel_name
== METHOD_SEL_NAME (target
->key
))
5511 target
= target
->next
;
5517 hash_add_attr (entry
, value
)
5521 static attr attr_alloc_list
= 0;
5522 static int attr_alloc_index
= 0;
5525 if (! attr_alloc_list
|| attr_alloc_index
>= ATTR_ALLOC_LIST_SIZE
)
5527 attr_alloc_index
= 0;
5528 attr_alloc_list
= (attr
) xmalloc (sizeof (struct hashed_attribute
)
5529 * ATTR_ALLOC_LIST_SIZE
);
5530 if (! attr_alloc_list
)
5531 perror ("unable to allocate in objc-tree.c");
5533 obj
= &attr_alloc_list
[attr_alloc_index
++];
5534 obj
->next
= entry
->list
;
5537 entry
->list
= obj
; /* append to front */
5541 lookup_method (mchain
, method
)
5547 if (TREE_CODE (method
) == IDENTIFIER_NODE
)
5550 key
= METHOD_SEL_NAME (method
);
5554 if (METHOD_SEL_NAME (mchain
) == key
)
5556 mchain
= TREE_CHAIN (mchain
);
5562 lookup_instance_method_static (interface
, ident
)
5566 tree inter
= interface
;
5567 tree chain
= CLASS_NST_METHODS (inter
);
5568 tree meth
= NULL_TREE
;
5572 if ((meth
= lookup_method (chain
, ident
)))
5575 if (CLASS_CATEGORY_LIST (inter
))
5577 tree category
= CLASS_CATEGORY_LIST (inter
);
5578 chain
= CLASS_NST_METHODS (category
);
5582 if ((meth
= lookup_method (chain
, ident
)))
5585 /* Check for instance methods in protocols in categories. */
5586 if (CLASS_PROTOCOL_LIST (category
))
5588 if ((meth
= (lookup_method_in_protocol_list
5589 (CLASS_PROTOCOL_LIST (category
), ident
, 0))))
5593 if ((category
= CLASS_CATEGORY_LIST (category
)))
5594 chain
= CLASS_NST_METHODS (category
);
5599 if (CLASS_PROTOCOL_LIST (inter
))
5601 if ((meth
= (lookup_method_in_protocol_list
5602 (CLASS_PROTOCOL_LIST (inter
), ident
, 0))))
5606 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5607 chain
= CLASS_NST_METHODS (inter
);
5615 lookup_class_method_static (interface
, ident
)
5619 tree inter
= interface
;
5620 tree chain
= CLASS_CLS_METHODS (inter
);
5621 tree meth
= NULL_TREE
;
5622 tree root_inter
= NULL_TREE
;
5626 if ((meth
= lookup_method (chain
, ident
)))
5629 if (CLASS_CATEGORY_LIST (inter
))
5631 tree category
= CLASS_CATEGORY_LIST (inter
);
5632 chain
= CLASS_CLS_METHODS (category
);
5636 if ((meth
= lookup_method (chain
, ident
)))
5639 /* Check for class methods in protocols in categories. */
5640 if (CLASS_PROTOCOL_LIST (category
))
5642 if ((meth
= (lookup_method_in_protocol_list
5643 (CLASS_PROTOCOL_LIST (category
), ident
, 1))))
5647 if ((category
= CLASS_CATEGORY_LIST (category
)))
5648 chain
= CLASS_CLS_METHODS (category
);
5653 /* Check for class methods in protocols. */
5654 if (CLASS_PROTOCOL_LIST (inter
))
5656 if ((meth
= (lookup_method_in_protocol_list
5657 (CLASS_PROTOCOL_LIST (inter
), ident
, 1))))
5662 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5663 chain
= CLASS_CLS_METHODS (inter
);
5667 /* Simulate wrap around. */
5668 return lookup_instance_method_static (root_inter
, ident
);
5672 add_class_method (class, method
)
5679 /* We will have allocated the method parameter declarations on the
5680 maybepermanent_obstack. Need to make sure they stick around! */
5683 if (!(mth
= lookup_method (CLASS_CLS_METHODS (class), method
)))
5685 /* put method on list in reverse order */
5686 TREE_CHAIN (method
) = CLASS_CLS_METHODS (class);
5687 CLASS_CLS_METHODS (class) = method
;
5691 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5692 error ("duplicate definition of class method `%s'.",
5693 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5696 /* Check types; if different, complain. */
5697 if (!comp_proto_with_proto (method
, mth
))
5698 error ("duplicate declaration of class method `%s'.",
5699 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5703 if (!(hsh
= hash_lookup (cls_method_hash_list
, METHOD_SEL_NAME (method
))))
5705 /* Install on a global chain. */
5706 hash_enter (cls_method_hash_list
, method
);
5710 /* Check types; if different, add to a list. */
5711 if (!comp_proto_with_proto (method
, hsh
->key
))
5712 hash_add_attr (hsh
, method
);
5718 add_instance_method (class, method
)
5725 /* We will have allocated the method parameter declarations on the
5726 maybepermanent_obstack. Need to make sure they stick around! */
5729 if (!(mth
= lookup_method (CLASS_NST_METHODS (class), method
)))
5731 /* Put method on list in reverse order. */
5732 TREE_CHAIN (method
) = CLASS_NST_METHODS (class);
5733 CLASS_NST_METHODS (class) = method
;
5737 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5738 error ("duplicate definition of instance method `%s'.",
5739 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5742 /* Check types; if different, complain. */
5743 if (!comp_proto_with_proto (method
, mth
))
5744 error ("duplicate declaration of instance method `%s'.",
5745 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5749 if (!(hsh
= hash_lookup (nst_method_hash_list
, METHOD_SEL_NAME (method
))))
5751 /* Install on a global chain. */
5752 hash_enter (nst_method_hash_list
, method
);
5756 /* Check types; if different, add to a list. */
5757 if (!comp_proto_with_proto (method
, hsh
->key
))
5758 hash_add_attr (hsh
, method
);
5767 /* Put interfaces on list in reverse order. */
5768 TREE_CHAIN (class) = interface_chain
;
5769 interface_chain
= class;
5770 return interface_chain
;
5774 add_category (class, category
)
5778 /* Put categories on list in reverse order. */
5779 tree cat
= CLASS_CATEGORY_LIST (class);
5783 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
5784 warning ("duplicate interface declaration for category `%s(%s)'",
5785 IDENTIFIER_POINTER (CLASS_NAME (class)),
5786 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category
)));
5787 cat
= CLASS_CATEGORY_LIST (cat
);
5790 CLASS_CATEGORY_LIST (category
) = CLASS_CATEGORY_LIST (class);
5791 CLASS_CATEGORY_LIST (class) = category
;
5794 /* Called after parsing each instance variable declaration. Necessary to
5795 preserve typedefs and implement public/private...
5797 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5800 add_instance_variable (class, public, declarator
, declspecs
, width
)
5807 tree field_decl
, raw_decl
;
5809 raw_decl
= build_tree_list (declspecs
, declarator
);
5811 if (CLASS_RAW_IVARS (class))
5812 chainon (CLASS_RAW_IVARS (class), raw_decl
);
5814 CLASS_RAW_IVARS (class) = raw_decl
;
5816 field_decl
= grokfield (input_filename
, lineno
,
5817 declarator
, declspecs
, width
);
5819 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5823 TREE_PUBLIC (field_decl
) = 0;
5824 TREE_PRIVATE (field_decl
) = 0;
5825 TREE_PROTECTED (field_decl
) = 1;
5829 TREE_PUBLIC (field_decl
) = 1;
5830 TREE_PRIVATE (field_decl
) = 0;
5831 TREE_PROTECTED (field_decl
) = 0;
5835 TREE_PUBLIC (field_decl
) = 0;
5836 TREE_PRIVATE (field_decl
) = 1;
5837 TREE_PROTECTED (field_decl
) = 0;
5842 if (CLASS_IVARS (class))
5843 chainon (CLASS_IVARS (class), field_decl
);
5845 CLASS_IVARS (class) = field_decl
;
5851 is_ivar (decl_chain
, ident
)
5855 for ( ; decl_chain
; decl_chain
= TREE_CHAIN (decl_chain
))
5856 if (DECL_NAME (decl_chain
) == ident
)
5861 /* True if the ivar is private and we are not in its implementation. */
5867 if (TREE_PRIVATE (decl
)
5868 && ! is_ivar (CLASS_IVARS (implementation_template
), DECL_NAME (decl
)))
5870 error ("instance variable `%s' is declared private",
5871 IDENTIFIER_POINTER (DECL_NAME (decl
)));
5878 /* We have an instance variable reference;, check to see if it is public. */
5881 is_public (expr
, identifier
)
5885 tree basetype
= TREE_TYPE (expr
);
5886 enum tree_code code
= TREE_CODE (basetype
);
5889 if (code
== RECORD_TYPE
)
5891 if (TREE_STATIC_TEMPLATE (basetype
))
5893 if (!lookup_interface (TYPE_NAME (basetype
)))
5895 error ("Cannot find interface declaration for `%s'",
5896 IDENTIFIER_POINTER (TYPE_NAME (basetype
)));
5900 if ((decl
= is_ivar (TYPE_FIELDS (basetype
), identifier
)))
5902 if (TREE_PUBLIC (decl
))
5905 /* Important difference between the Stepstone translator:
5906 all instance variables should be public within the context
5907 of the implementation. */
5908 if (implementation_context
5909 && (((TREE_CODE (implementation_context
)
5910 == CLASS_IMPLEMENTATION_TYPE
)
5911 || (TREE_CODE (implementation_context
)
5912 == CATEGORY_IMPLEMENTATION_TYPE
))
5913 && (CLASS_NAME (implementation_context
)
5914 == TYPE_NAME (basetype
))))
5915 return ! is_private (decl
);
5917 error ("instance variable `%s' is declared %s",
5918 IDENTIFIER_POINTER (identifier
),
5919 TREE_PRIVATE (decl
) ? "private" : "protected");
5924 else if (implementation_context
&& (basetype
== objc_object_reference
))
5926 TREE_TYPE (expr
) = uprivate_record
;
5927 warning ("static access to object of type `id'");
5934 /* Implement @defs (<classname>) within struct bodies. */
5937 get_class_ivars (interface
)
5940 if (!doing_objc_thang
)
5943 return build_ivar_chain (interface
, 1);
5946 /* Make sure all entries in CHAIN are also in LIST. */
5949 check_methods (chain
, list
, mtype
)
5958 if (!lookup_method (list
, chain
))
5962 if (TREE_CODE (implementation_context
)
5963 == CLASS_IMPLEMENTATION_TYPE
)
5964 warning ("incomplete implementation of class `%s'",
5965 IDENTIFIER_POINTER (CLASS_NAME (implementation_context
)));
5966 else if (TREE_CODE (implementation_context
)
5967 == CATEGORY_IMPLEMENTATION_TYPE
)
5968 warning ("incomplete implementation of category `%s'",
5969 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
5973 warning ("method definition for `%c%s' not found",
5974 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
5977 chain
= TREE_CHAIN (chain
);
5984 conforms_to_protocol (class, protocol
)
5990 tree p
= CLASS_PROTOCOL_LIST (class);
5992 while (p
&& TREE_VALUE (p
) != TREE_VALUE (protocol
))
5997 tree super
= (CLASS_SUPER_NAME (class)
5998 ? lookup_interface (CLASS_SUPER_NAME (class))
6000 int tmp
= super
? conforms_to_protocol (super
, protocol
) : 0;
6005 protocol
= TREE_CHAIN (protocol
);
6011 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
6012 CONTEXT. This is one of two mechanisms to check protocol integrity. */
6015 check_methods_accessible (chain
, context
, mtype
)
6022 tree base_context
= context
;
6026 context
= base_context
;
6030 list
= CLASS_CLS_METHODS (context
);
6032 list
= CLASS_NST_METHODS (context
);
6034 if (lookup_method (list
, chain
))
6037 else if (TREE_CODE (context
) == CLASS_IMPLEMENTATION_TYPE
6038 || TREE_CODE (context
) == CLASS_INTERFACE_TYPE
)
6039 context
= (CLASS_SUPER_NAME (context
)
6040 ? lookup_interface (CLASS_SUPER_NAME (context
))
6043 else if (TREE_CODE (context
) == CATEGORY_IMPLEMENTATION_TYPE
6044 || TREE_CODE (context
) == CATEGORY_INTERFACE_TYPE
)
6045 context
= (CLASS_NAME (context
)
6046 ? lookup_interface (CLASS_NAME (context
))
6052 if (context
== NULL_TREE
)
6056 if (TREE_CODE (implementation_context
)
6057 == CLASS_IMPLEMENTATION_TYPE
)
6058 warning ("incomplete implementation of class `%s'",
6060 (CLASS_NAME (implementation_context
)));
6061 else if (TREE_CODE (implementation_context
)
6062 == CATEGORY_IMPLEMENTATION_TYPE
)
6063 warning ("incomplete implementation of category `%s'",
6065 (CLASS_SUPER_NAME (implementation_context
)));
6068 warning ("method definition for `%c%s' not found",
6069 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
6072 chain
= TREE_CHAIN (chain
); /* next method... */
6078 check_protocols (proto_list
, type
, name
)
6083 for ( ; proto_list
; proto_list
= TREE_CHAIN (proto_list
))
6085 tree p
= TREE_VALUE (proto_list
);
6087 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
6091 /* Ensure that all protocols have bodies. */
6092 if (flag_warn_protocol
) {
6093 f1
= check_methods (PROTOCOL_CLS_METHODS (p
),
6094 CLASS_CLS_METHODS (implementation_context
),
6096 f2
= check_methods (PROTOCOL_NST_METHODS (p
),
6097 CLASS_NST_METHODS (implementation_context
),
6100 f1
= check_methods_accessible (PROTOCOL_CLS_METHODS (p
),
6101 implementation_context
,
6103 f2
= check_methods_accessible (PROTOCOL_NST_METHODS (p
),
6104 implementation_context
,
6109 warning ("%s `%s' does not fully implement the `%s' protocol",
6110 type
, name
, IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
6115 ; /* An identifier if we could not find a protocol. */
6118 /* Check protocols recursively. */
6119 if (PROTOCOL_LIST (p
))
6122 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
6123 if (! conforms_to_protocol (super_class
, PROTOCOL_LIST (p
)))
6124 check_protocols (PROTOCOL_LIST (p
), type
, name
);
6129 /* Make sure that the class CLASS_NAME is defined
6130 CODE says which kind of thing CLASS_NAME ought to be.
6131 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6132 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE.
6134 If CODE is CLASS_INTERFACE_TYPE, we also do a push_obstacks_nochange
6135 whose matching pop is in continue_class. */
6138 start_class (code
, class_name
, super_name
, protocol_list
)
6139 enum tree_code code
;
6146 if (code
== CLASS_INTERFACE_TYPE
)
6148 push_obstacks_nochange ();
6149 end_temporary_allocation ();
6152 if (!doing_objc_thang
)
6155 class = make_node (code
);
6156 TYPE_BINFO (class) = make_tree_vec (5);
6158 CLASS_NAME (class) = class_name
;
6159 CLASS_SUPER_NAME (class) = super_name
;
6160 CLASS_CLS_METHODS (class) = NULL_TREE
;
6162 if (! is_class_name (class_name
) && (decl
= lookup_name (class_name
)))
6164 error ("`%s' redeclared as different kind of symbol",
6165 IDENTIFIER_POINTER (class_name
));
6166 error_with_decl (decl
, "previous declaration of `%s'");
6169 if (code
== CLASS_IMPLEMENTATION_TYPE
)
6172 static tree implemented_classes
= 0;
6173 tree chain
= implemented_classes
;
6174 for (chain
= implemented_classes
; chain
; chain
= TREE_CHAIN (chain
))
6175 if (TREE_VALUE (chain
) == class_name
)
6177 error ("reimplementation of class `%s'",
6178 IDENTIFIER_POINTER (class_name
));
6179 return error_mark_node
;
6181 implemented_classes
= perm_tree_cons (NULL_TREE
, class_name
,
6182 implemented_classes
);
6185 /* Pre-build the following entities - for speed/convenience. */
6187 self_id
= get_identifier ("self");
6189 ucmd_id
= get_identifier ("_cmd");
6192 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6193 if (!objc_super_template
)
6194 objc_super_template
= build_super_template ();
6196 /* Reset for multiple classes per file. */
6199 implementation_context
= class;
6201 /* Lookup the interface for this implementation. */
6203 if (!(implementation_template
= lookup_interface (class_name
)))
6205 warning ("Cannot find interface declaration for `%s'",
6206 IDENTIFIER_POINTER (class_name
));
6207 add_class (implementation_template
= implementation_context
);
6210 /* If a super class has been specified in the implementation,
6211 insure it conforms to the one specified in the interface. */
6214 && (super_name
!= CLASS_SUPER_NAME (implementation_template
)))
6216 tree previous_name
= CLASS_SUPER_NAME (implementation_template
);
6218 previous_name
? IDENTIFIER_POINTER (previous_name
) : "";
6219 error ("conflicting super class name `%s'",
6220 IDENTIFIER_POINTER (super_name
));
6221 error ("previous declaration of `%s'", name
);
6224 else if (! super_name
)
6226 CLASS_SUPER_NAME (implementation_context
)
6227 = CLASS_SUPER_NAME (implementation_template
);
6231 else if (code
== CLASS_INTERFACE_TYPE
)
6233 if (lookup_interface (class_name
))
6234 warning ("duplicate interface declaration for class `%s'",
6235 IDENTIFIER_POINTER (class_name
));
6240 CLASS_PROTOCOL_LIST (class)
6241 = lookup_and_install_protocols (protocol_list
);
6244 else if (code
== CATEGORY_INTERFACE_TYPE
)
6246 tree class_category_is_assoc_with
;
6248 /* For a category, class_name is really the name of the class that
6249 the following set of methods will be associated with. We must
6250 find the interface so that can derive the objects template. */
6252 if (!(class_category_is_assoc_with
= lookup_interface (class_name
)))
6254 error ("Cannot find interface declaration for `%s'",
6255 IDENTIFIER_POINTER (class_name
));
6256 exit (FATAL_EXIT_CODE
);
6259 add_category (class_category_is_assoc_with
, class);
6262 CLASS_PROTOCOL_LIST (class)
6263 = lookup_and_install_protocols (protocol_list
);
6266 else if (code
== CATEGORY_IMPLEMENTATION_TYPE
)
6268 /* Pre-build the following entities for speed/convenience. */
6270 self_id
= get_identifier ("self");
6272 ucmd_id
= get_identifier ("_cmd");
6275 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6276 if (!objc_super_template
)
6277 objc_super_template
= build_super_template ();
6279 /* Reset for multiple classes per file. */
6282 implementation_context
= class;
6284 /* For a category, class_name is really the name of the class that
6285 the following set of methods will be associated with. We must
6286 find the interface so that can derive the objects template. */
6288 if (!(implementation_template
= lookup_interface (class_name
)))
6290 error ("Cannot find interface declaration for `%s'",
6291 IDENTIFIER_POINTER (class_name
));
6292 exit (FATAL_EXIT_CODE
);
6299 continue_class (class)
6302 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6303 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6305 struct imp_entry
*imp_entry
;
6308 /* Check consistency of the instance variables. */
6310 if (CLASS_IVARS (class))
6311 check_ivars (implementation_template
, class);
6313 /* code generation */
6315 ivar_context
= build_private_template (implementation_template
);
6317 if (!objc_class_template
)
6318 build_class_template ();
6321 = (struct imp_entry
*) xmalloc (sizeof (struct imp_entry
))))
6322 perror ("unable to allocate in objc-tree.c");
6324 imp_entry
->next
= imp_list
;
6325 imp_entry
->imp_context
= class;
6326 imp_entry
->imp_template
= implementation_template
;
6328 synth_forward_declarations ();
6329 imp_entry
->class_decl
= UOBJC_CLASS_decl
;
6330 imp_entry
->meta_decl
= UOBJC_METACLASS_decl
;
6332 /* Append to front and increment count. */
6333 imp_list
= imp_entry
;
6334 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6339 return ivar_context
;
6342 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6344 tree record
= xref_tag (RECORD_TYPE
, CLASS_NAME (class));
6346 if (!TYPE_FIELDS (record
))
6348 finish_struct (record
, build_ivar_chain (class, 0), NULL_TREE
);
6349 CLASS_STATIC_TEMPLATE (class) = record
;
6351 /* Mark this record as a class template for static typing. */
6352 TREE_STATIC_TEMPLATE (record
) = 1;
6359 return error_mark_node
;
6362 /* This is called once we see the "@end" in an interface/implementation. */
6365 finish_class (class)
6368 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6370 /* All code generation is done in finish_objc. */
6372 if (implementation_template
!= implementation_context
)
6374 /* Ensure that all method listed in the interface contain bodies. */
6375 check_methods (CLASS_CLS_METHODS (implementation_template
),
6376 CLASS_CLS_METHODS (implementation_context
), '+');
6377 check_methods (CLASS_NST_METHODS (implementation_template
),
6378 CLASS_NST_METHODS (implementation_context
), '-');
6380 if (CLASS_PROTOCOL_LIST (implementation_template
))
6381 check_protocols (CLASS_PROTOCOL_LIST (implementation_template
),
6383 IDENTIFIER_POINTER (CLASS_NAME (implementation_context
)));
6387 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6389 tree category
= CLASS_CATEGORY_LIST (implementation_template
);
6391 /* Find the category interface from the class it is associated with. */
6394 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category
))
6396 category
= CLASS_CATEGORY_LIST (category
);
6401 /* Ensure all method listed in the interface contain bodies. */
6402 check_methods (CLASS_CLS_METHODS (category
),
6403 CLASS_CLS_METHODS (implementation_context
), '+');
6404 check_methods (CLASS_NST_METHODS (category
),
6405 CLASS_NST_METHODS (implementation_context
), '-');
6407 if (CLASS_PROTOCOL_LIST (category
))
6408 check_protocols (CLASS_PROTOCOL_LIST (category
),
6410 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
6414 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6417 const char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (class));
6418 char *string
= (char *) alloca (strlen (class_name
) + 3);
6420 /* extern struct objc_object *_<my_name>; */
6422 sprintf (string
, "_%s", class_name
);
6424 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
6425 decl_specs
= tree_cons (NULL_TREE
, objc_object_reference
, decl_specs
);
6426 define_decl (build1 (INDIRECT_REF
, NULL_TREE
, get_identifier (string
)),
6432 add_protocol (protocol
)
6435 /* Put protocol on list in reverse order. */
6436 TREE_CHAIN (protocol
) = protocol_chain
;
6437 protocol_chain
= protocol
;
6438 return protocol_chain
;
6442 lookup_protocol (ident
)
6447 for (chain
= protocol_chain
; chain
; chain
= TREE_CHAIN (chain
))
6449 if (ident
== PROTOCOL_NAME (chain
))
6457 start_protocol (code
, name
, list
)
6458 enum tree_code code
;
6464 if (!doing_objc_thang
)
6467 /* This is as good a place as any. Need to invoke push_tag_toplevel. */
6468 if (!objc_protocol_template
)
6469 objc_protocol_template
= build_protocol_template ();
6471 protocol
= make_node (code
);
6472 TYPE_BINFO (protocol
) = make_tree_vec (2);
6474 PROTOCOL_NAME (protocol
) = name
;
6475 PROTOCOL_LIST (protocol
) = list
;
6477 lookup_and_install_protocols (list
);
6479 if (lookup_protocol (name
))
6480 warning ("duplicate declaration for protocol `%s'",
6481 IDENTIFIER_POINTER (name
));
6483 add_protocol (protocol
);
6485 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6491 finish_protocol (protocol
)
6492 tree protocol ATTRIBUTE_UNUSED
;
6497 /* "Encode" a data type into a string, which grows in util_obstack.
6498 ??? What is the FORMAT? Someone please document this! */
6501 encode_type_qualifiers (declspecs
)
6506 for (spec
= declspecs
; spec
; spec
= TREE_CHAIN (spec
))
6508 if (ridpointers
[(int) RID_CONST
] == TREE_VALUE (spec
))
6509 obstack_1grow (&util_obstack
, 'r');
6510 else if (ridpointers
[(int) RID_IN
] == TREE_VALUE (spec
))
6511 obstack_1grow (&util_obstack
, 'n');
6512 else if (ridpointers
[(int) RID_INOUT
] == TREE_VALUE (spec
))
6513 obstack_1grow (&util_obstack
, 'N');
6514 else if (ridpointers
[(int) RID_OUT
] == TREE_VALUE (spec
))
6515 obstack_1grow (&util_obstack
, 'o');
6516 else if (ridpointers
[(int) RID_BYCOPY
] == TREE_VALUE (spec
))
6517 obstack_1grow (&util_obstack
, 'O');
6518 else if (ridpointers
[(int) RID_BYREF
] == TREE_VALUE (spec
))
6519 obstack_1grow (&util_obstack
, 'R');
6520 else if (ridpointers
[(int) RID_ONEWAY
] == TREE_VALUE (spec
))
6521 obstack_1grow (&util_obstack
, 'V');
6525 /* Encode a pointer type. */
6528 encode_pointer (type
, curtype
, format
)
6533 tree pointer_to
= TREE_TYPE (type
);
6535 if (TREE_CODE (pointer_to
) == RECORD_TYPE
)
6537 if (TYPE_NAME (pointer_to
)
6538 && TREE_CODE (TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
)
6540 const char *name
= IDENTIFIER_POINTER (TYPE_NAME (pointer_to
));
6542 if (strcmp (name
, TAG_OBJECT
) == 0) /* '@' */
6544 obstack_1grow (&util_obstack
, '@');
6547 else if (TREE_STATIC_TEMPLATE (pointer_to
))
6549 if (generating_instance_variables
)
6551 obstack_1grow (&util_obstack
, '@');
6552 obstack_1grow (&util_obstack
, '"');
6553 obstack_grow (&util_obstack
, name
, strlen (name
));
6554 obstack_1grow (&util_obstack
, '"');
6559 obstack_1grow (&util_obstack
, '@');
6563 else if (strcmp (name
, TAG_CLASS
) == 0) /* '#' */
6565 obstack_1grow (&util_obstack
, '#');
6568 #ifndef OBJC_INT_SELECTORS
6569 else if (strcmp (name
, TAG_SELECTOR
) == 0) /* ':' */
6571 obstack_1grow (&util_obstack
, ':');
6574 #endif /* OBJC_INT_SELECTORS */
6577 else if (TREE_CODE (pointer_to
) == INTEGER_TYPE
6578 && TYPE_MODE (pointer_to
) == QImode
)
6580 obstack_1grow (&util_obstack
, '*');
6584 /* We have a type that does not get special treatment. */
6586 /* NeXT extension */
6587 obstack_1grow (&util_obstack
, '^');
6588 encode_type (pointer_to
, curtype
, format
);
6592 encode_array (type
, curtype
, format
)
6597 tree an_int_cst
= TYPE_SIZE (type
);
6598 tree array_of
= TREE_TYPE (type
);
6601 /* An incomplete array is treated like a pointer. */
6602 if (an_int_cst
== NULL
)
6604 encode_pointer (type
, curtype
, format
);
6608 sprintf (buffer
, "[%ld",
6609 (long) (TREE_INT_CST_LOW (an_int_cst
)
6610 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
6612 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6613 encode_type (array_of
, curtype
, format
);
6614 obstack_1grow (&util_obstack
, ']');
6619 encode_aggregate_within (type
, curtype
, format
, left
, right
)
6626 if (obstack_object_size (&util_obstack
) > 0
6627 && *(obstack_next_free (&util_obstack
) - 1) == '^')
6629 tree name
= TYPE_NAME (type
);
6631 /* we have a reference; this is a NeXT extension. */
6633 if (obstack_object_size (&util_obstack
) - curtype
== 1
6634 && format
== OBJC_ENCODE_INLINE_DEFS
)
6636 /* Output format of struct for first level only. */
6637 tree fields
= TYPE_FIELDS (type
);
6639 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6641 obstack_1grow (&util_obstack
, left
);
6642 obstack_grow (&util_obstack
,
6643 IDENTIFIER_POINTER (name
),
6644 strlen (IDENTIFIER_POINTER (name
)));
6645 obstack_1grow (&util_obstack
, '=');
6649 obstack_1grow (&util_obstack
, left
);
6650 obstack_grow (&util_obstack
, "?=", 2);
6653 for ( ; fields
; fields
= TREE_CHAIN (fields
))
6654 encode_field_decl (fields
, curtype
, format
);
6656 obstack_1grow (&util_obstack
, right
);
6659 else if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6661 obstack_1grow (&util_obstack
, left
);
6662 obstack_grow (&util_obstack
,
6663 IDENTIFIER_POINTER (name
),
6664 strlen (IDENTIFIER_POINTER (name
)));
6665 obstack_1grow (&util_obstack
, right
);
6670 /* We have an untagged structure or a typedef. */
6671 obstack_1grow (&util_obstack
, left
);
6672 obstack_1grow (&util_obstack
, '?');
6673 obstack_1grow (&util_obstack
, right
);
6679 tree name
= TYPE_NAME (type
);
6680 tree fields
= TYPE_FIELDS (type
);
6682 if (format
== OBJC_ENCODE_INLINE_DEFS
6683 || generating_instance_variables
)
6685 obstack_1grow (&util_obstack
, left
);
6686 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6687 obstack_grow (&util_obstack
,
6688 IDENTIFIER_POINTER (name
),
6689 strlen (IDENTIFIER_POINTER (name
)));
6691 obstack_1grow (&util_obstack
, '?');
6693 obstack_1grow (&util_obstack
, '=');
6695 for (; fields
; fields
= TREE_CHAIN (fields
))
6697 if (generating_instance_variables
)
6699 tree fname
= DECL_NAME (fields
);
6701 obstack_1grow (&util_obstack
, '"');
6702 if (fname
&& TREE_CODE (fname
) == IDENTIFIER_NODE
)
6704 obstack_grow (&util_obstack
,
6705 IDENTIFIER_POINTER (fname
),
6706 strlen (IDENTIFIER_POINTER (fname
)));
6709 obstack_1grow (&util_obstack
, '"');
6712 encode_field_decl (fields
, curtype
, format
);
6715 obstack_1grow (&util_obstack
, right
);
6720 obstack_1grow (&util_obstack
, left
);
6721 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6722 obstack_grow (&util_obstack
,
6723 IDENTIFIER_POINTER (name
),
6724 strlen (IDENTIFIER_POINTER (name
)));
6726 /* We have an untagged structure or a typedef. */
6727 obstack_1grow (&util_obstack
, '?');
6729 obstack_1grow (&util_obstack
, right
);
6735 encode_aggregate (type
, curtype
, format
)
6740 enum tree_code code
= TREE_CODE (type
);
6746 encode_aggregate_within(type
, curtype
, format
, '{', '}');
6751 encode_aggregate_within(type
, curtype
, format
, '(', ')');
6756 obstack_1grow (&util_obstack
, 'i');
6764 /* Support bitfields. The current version of Objective-C does not support
6765 them. The string will consist of one or more "b:n"'s where n is an
6766 integer describing the width of the bitfield. Currently, classes in
6767 the kit implement a method "-(char *)describeBitfieldStruct:" that
6768 simulates this. If they do not implement this method, the archiver
6769 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6770 according to the GNU compiler. After looking at the "kit", it appears
6771 that all classes currently rely on this default behavior, rather than
6772 hand generating this string (which is tedious). */
6775 encode_bitfield (width
)
6779 sprintf (buffer
, "b%d", width
);
6780 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6783 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6786 encode_type (type
, curtype
, format
)
6791 enum tree_code code
= TREE_CODE (type
);
6793 if (code
== INTEGER_TYPE
)
6795 if (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type
)) == 0
6796 && TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type
)) == 0)
6798 /* Unsigned integer types. */
6800 if (TYPE_MODE (type
) == QImode
)
6801 obstack_1grow (&util_obstack
, 'C');
6802 else if (TYPE_MODE (type
) == HImode
)
6803 obstack_1grow (&util_obstack
, 'S');
6804 else if (TYPE_MODE (type
) == SImode
)
6806 if (type
== long_unsigned_type_node
)
6807 obstack_1grow (&util_obstack
, 'L');
6809 obstack_1grow (&util_obstack
, 'I');
6811 else if (TYPE_MODE (type
) == DImode
)
6812 obstack_1grow (&util_obstack
, 'Q');
6816 /* Signed integer types. */
6818 if (TYPE_MODE (type
) == QImode
)
6819 obstack_1grow (&util_obstack
, 'c');
6820 else if (TYPE_MODE (type
) == HImode
)
6821 obstack_1grow (&util_obstack
, 's');
6822 else if (TYPE_MODE (type
) == SImode
)
6824 if (type
== long_integer_type_node
)
6825 obstack_1grow (&util_obstack
, 'l');
6827 obstack_1grow (&util_obstack
, 'i');
6830 else if (TYPE_MODE (type
) == DImode
)
6831 obstack_1grow (&util_obstack
, 'q');
6835 else if (code
== REAL_TYPE
)
6837 /* Floating point types. */
6839 if (TYPE_MODE (type
) == SFmode
)
6840 obstack_1grow (&util_obstack
, 'f');
6841 else if (TYPE_MODE (type
) == DFmode
6842 || TYPE_MODE (type
) == TFmode
)
6843 obstack_1grow (&util_obstack
, 'd');
6846 else if (code
== VOID_TYPE
)
6847 obstack_1grow (&util_obstack
, 'v');
6849 else if (code
== ARRAY_TYPE
)
6850 encode_array (type
, curtype
, format
);
6852 else if (code
== POINTER_TYPE
)
6853 encode_pointer (type
, curtype
, format
);
6855 else if (code
== RECORD_TYPE
|| code
== UNION_TYPE
|| code
== ENUMERAL_TYPE
)
6856 encode_aggregate (type
, curtype
, format
);
6858 else if (code
== FUNCTION_TYPE
) /* '?' */
6859 obstack_1grow (&util_obstack
, '?');
6863 encode_complete_bitfield (int position
, tree type
, int size
)
6865 enum tree_code code
= TREE_CODE (type
);
6867 char charType
= '?';
6869 if (code
== INTEGER_TYPE
)
6871 if (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type
)) == 0
6872 && TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type
)) == 0)
6874 /* Unsigned integer types. */
6876 if (TYPE_MODE (type
) == QImode
)
6878 else if (TYPE_MODE (type
) == HImode
)
6880 else if (TYPE_MODE (type
) == SImode
)
6882 if (type
== long_unsigned_type_node
)
6887 else if (TYPE_MODE (type
) == DImode
)
6892 /* Signed integer types. */
6894 if (TYPE_MODE (type
) == QImode
)
6896 else if (TYPE_MODE (type
) == HImode
)
6898 else if (TYPE_MODE (type
) == SImode
)
6900 if (type
== long_integer_type_node
)
6906 else if (TYPE_MODE (type
) == DImode
)
6914 sprintf (buffer
, "b%d%c%d", position
, charType
, size
);
6915 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6919 encode_field_decl (field_decl
, curtype
, format
)
6926 type
= TREE_TYPE (field_decl
);
6928 /* If this field is obviously a bitfield, or is a bitfield that has been
6929 clobbered to look like a ordinary integer mode, go ahead and generate
6930 the bitfield typing information. */
6931 if (flag_next_runtime
)
6933 if (DECL_BIT_FIELD (field_decl
))
6934 encode_bitfield (DECL_FIELD_SIZE (field_decl
));
6935 else if (TREE_CODE (TYPE_SIZE (type
)) == INTEGER_CST
6936 && DECL_FIELD_SIZE (field_decl
)
6937 && TYPE_MODE (type
) > DECL_MODE (field_decl
))
6938 encode_bitfield (DECL_FIELD_SIZE (field_decl
));
6940 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6944 if (DECL_BIT_FIELD (field_decl
)
6945 || (TREE_CODE (TYPE_SIZE (type
)) == INTEGER_CST
6946 && DECL_FIELD_SIZE (field_decl
)
6947 && TYPE_MODE (type
) > DECL_MODE (field_decl
)))
6949 encode_complete_bitfield (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl
)),
6950 DECL_BIT_FIELD_TYPE (field_decl
),
6951 DECL_FIELD_SIZE (field_decl
));
6954 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6959 expr_last (complex_expr
)
6965 while ((next
= TREE_OPERAND (complex_expr
, 0)))
6966 complex_expr
= next
;
6968 return complex_expr
;
6971 /* The selector of the current method,
6972 or NULL if we aren't compiling a method. */
6975 maybe_objc_method_name (decl
)
6976 tree decl ATTRIBUTE_UNUSED
;
6979 return METHOD_SEL_NAME (method_context
);
6984 /* Transform a method definition into a function definition as follows:
6985 - synthesize the first two arguments, "self" and "_cmd". */
6988 start_method_def (method
)
6993 /* Required to implement _msgSuper. */
6994 method_context
= method
;
6995 UOBJC_SUPER_decl
= NULL_TREE
;
6997 /* Must be called BEFORE start_function. */
7000 /* Generate prototype declarations for arguments..."new-style". */
7002 if (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
)
7003 decl_specs
= build_tree_list (NULL_TREE
, uprivate_record
);
7005 /* Really a `struct objc_class *'. However, we allow people to
7006 assign to self, which changes its type midstream. */
7007 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
7009 push_parm_decl (build_tree_list
7010 (build_tree_list (decl_specs
,
7011 build1 (INDIRECT_REF
, NULL_TREE
, self_id
)),
7012 build_tree_list (unused_list
, NULL_TREE
)));
7014 #ifdef OBJC_INT_SELECTORS
7015 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_UNSIGNED
]);
7016 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_INT
], decl_specs
);
7017 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, ucmd_id
),
7018 build_tree_list (unused_list
, NULL_TREE
)));
7019 #else /* not OBJC_INT_SELECTORS */
7020 decl_specs
= build_tree_list (NULL_TREE
,
7021 xref_tag (RECORD_TYPE
,
7022 get_identifier (TAG_SELECTOR
)));
7023 push_parm_decl (build_tree_list
7024 (build_tree_list (decl_specs
,
7025 build1 (INDIRECT_REF
, NULL_TREE
, ucmd_id
)),
7026 build_tree_list (unused_list
, NULL_TREE
)));
7027 #endif /* not OBJC_INT_SELECTORS */
7029 /* Generate argument declarations if a keyword_decl. */
7030 if (METHOD_SEL_ARGS (method
))
7032 tree arglist
= METHOD_SEL_ARGS (method
);
7035 tree arg_spec
= TREE_PURPOSE (TREE_TYPE (arglist
));
7036 tree arg_decl
= TREE_VALUE (TREE_TYPE (arglist
));
7040 tree last_expr
= expr_last (arg_decl
);
7042 /* Unite the abstract decl with its name. */
7043 TREE_OPERAND (last_expr
, 0) = KEYWORD_ARG_NAME (arglist
);
7044 push_parm_decl (build_tree_list
7045 (build_tree_list (arg_spec
, arg_decl
),
7046 build_tree_list (NULL_TREE
, NULL_TREE
)));
7048 /* Unhook: restore the abstract declarator. */
7049 TREE_OPERAND (last_expr
, 0) = NULL_TREE
;
7053 push_parm_decl (build_tree_list
7054 (build_tree_list (arg_spec
,
7055 KEYWORD_ARG_NAME (arglist
)),
7056 build_tree_list (NULL_TREE
, NULL_TREE
)));
7058 arglist
= TREE_CHAIN (arglist
);
7063 if (METHOD_ADD_ARGS (method
) > (tree
)1)
7065 /* We have a variable length selector - in "prototype" format. */
7066 tree akey
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
7069 /* This must be done prior to calling pushdecl. pushdecl is
7070 going to change our chain on us. */
7071 tree nextkey
= TREE_CHAIN (akey
);
7079 warn_with_method (message
, mtype
, method
)
7080 const char *message
;
7084 if (count_error (1) == 0)
7087 report_error_function (DECL_SOURCE_FILE (method
));
7089 fprintf (stderr
, "%s:%d: warning: ",
7090 DECL_SOURCE_FILE (method
), DECL_SOURCE_LINE (method
));
7091 bzero (errbuf
, BUFSIZE
);
7092 fprintf (stderr
, "%s `%c%s'\n",
7093 message
, mtype
, gen_method_decl (method
, errbuf
));
7096 /* Return 1 if METHOD is consistent with PROTO. */
7099 comp_method_with_proto (method
, proto
)
7102 static tree function_type
= 0;
7104 /* Create a function_type node once. */
7107 push_obstacks_nochange ();
7108 end_temporary_allocation ();
7109 function_type
= make_node (FUNCTION_TYPE
);
7113 /* Install argument types - normally set by build_function_type. */
7114 TYPE_ARG_TYPES (function_type
) = get_arg_type_list (proto
, METHOD_DEF
, 0);
7116 /* install return type */
7117 TREE_TYPE (function_type
) = groktypename (TREE_TYPE (proto
));
7119 return comptypes (TREE_TYPE (METHOD_DEFINITION (method
)), function_type
);
7122 /* Return 1 if PROTO1 is consistent with PROTO2. */
7125 comp_proto_with_proto (proto1
, proto2
)
7126 tree proto1
, proto2
;
7128 static tree function_type1
= 0, function_type2
= 0;
7130 /* Create a couple function_type node's once. */
7131 if (!function_type1
)
7133 push_obstacks_nochange ();
7134 end_temporary_allocation ();
7135 function_type1
= make_node (FUNCTION_TYPE
);
7136 function_type2
= make_node (FUNCTION_TYPE
);
7140 /* Install argument types; normally set by build_function_type. */
7141 TYPE_ARG_TYPES (function_type1
) = get_arg_type_list (proto1
, METHOD_REF
, 0);
7142 TYPE_ARG_TYPES (function_type2
) = get_arg_type_list (proto2
, METHOD_REF
, 0);
7144 /* Install return type. */
7145 TREE_TYPE (function_type1
) = groktypename (TREE_TYPE (proto1
));
7146 TREE_TYPE (function_type2
) = groktypename (TREE_TYPE (proto2
));
7148 return comptypes (function_type1
, function_type2
);
7151 /* - Generate an identifier for the function. the format is "_n_cls",
7152 where 1 <= n <= nMethods, and cls is the name the implementation we
7154 - Install the return type from the method declaration.
7155 - If we have a prototype, check for type consistency. */
7158 really_start_method (method
, parmlist
)
7159 tree method
, parmlist
;
7161 tree sc_spec
, ret_spec
, ret_decl
, decl_specs
;
7162 tree method_decl
, method_id
;
7163 const char *sel_name
, *class_name
, *cat_name
;
7166 /* Synth the storage class & assemble the return type. */
7167 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
7168 ret_spec
= TREE_PURPOSE (TREE_TYPE (method
));
7169 decl_specs
= chainon (sc_spec
, ret_spec
);
7171 sel_name
= IDENTIFIER_POINTER (METHOD_SEL_NAME (method
));
7172 class_name
= IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
7173 cat_name
= ((TREE_CODE (implementation_context
)
7174 == CLASS_IMPLEMENTATION_TYPE
)
7176 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
7179 /* Make sure this is big enough for any plausible method label. */
7180 buf
= (char *) alloca (50 + strlen (sel_name
) + strlen (class_name
)
7181 + (cat_name
? strlen (cat_name
) : 0));
7183 OBJC_GEN_METHOD_LABEL (buf
, TREE_CODE (method
) == INSTANCE_METHOD_DECL
,
7184 class_name
, cat_name
, sel_name
, method_slot
);
7186 method_id
= get_identifier (buf
);
7188 method_decl
= build_nt (CALL_EXPR
, method_id
, parmlist
, NULL_TREE
);
7190 /* Check the declarator portion of the return type for the method. */
7191 if ((ret_decl
= TREE_VALUE (TREE_TYPE (method
))))
7193 /* Unite the complex decl (specified in the abstract decl) with the
7194 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7195 tree save_expr
= expr_last (ret_decl
);
7197 TREE_OPERAND (save_expr
, 0) = method_decl
;
7198 method_decl
= ret_decl
;
7200 /* Fool the parser into thinking it is starting a function. */
7201 start_function (decl_specs
, method_decl
, NULL_TREE
, NULL_TREE
, 0);
7203 /* Unhook: this has the effect of restoring the abstract declarator. */
7204 TREE_OPERAND (save_expr
, 0) = NULL_TREE
;
7209 TREE_VALUE (TREE_TYPE (method
)) = method_decl
;
7211 /* Fool the parser into thinking it is starting a function. */
7212 start_function (decl_specs
, method_decl
, NULL_TREE
, NULL_TREE
, 0);
7214 /* Unhook: this has the effect of restoring the abstract declarator. */
7215 TREE_VALUE (TREE_TYPE (method
)) = NULL_TREE
;
7218 METHOD_DEFINITION (method
) = current_function_decl
;
7220 if (implementation_template
!= implementation_context
)
7224 if (TREE_CODE (method
) == INSTANCE_METHOD_DECL
)
7225 proto
= lookup_instance_method_static (implementation_template
,
7226 METHOD_SEL_NAME (method
));
7228 proto
= lookup_class_method_static (implementation_template
,
7229 METHOD_SEL_NAME (method
));
7231 if (proto
&& ! comp_method_with_proto (method
, proto
))
7233 char type
= (TREE_CODE (method
) == INSTANCE_METHOD_DECL
? '-' : '+');
7235 warn_with_method ("conflicting types for", type
, method
);
7236 warn_with_method ("previous declaration of", type
, proto
);
7241 /* The following routine is always called...this "architecture" is to
7242 accommodate "old-style" variable length selectors.
7244 - a:a b:b // prototype ; id c; id d; // old-style. */
7247 continue_method_def ()
7251 if (METHOD_ADD_ARGS (method_context
) == (tree
)1)
7252 /* We have a `, ...' immediately following the selector. */
7253 parmlist
= get_parm_info (0);
7255 parmlist
= get_parm_info (1); /* place a `void_at_end' */
7257 /* Set self_decl from the first argument...this global is used by
7258 build_ivar_reference calling build_indirect_ref. */
7259 self_decl
= TREE_PURPOSE (parmlist
);
7262 really_start_method (method_context
, parmlist
);
7263 store_parm_decls ();
7266 /* Called by the parser, from the `pushlevel' production. */
7271 if (!UOBJC_SUPER_decl
)
7273 UOBJC_SUPER_decl
= start_decl (get_identifier (UTAG_SUPER
),
7274 build_tree_list (NULL_TREE
,
7275 objc_super_template
),
7276 0, NULL_TREE
, NULL_TREE
);
7278 finish_decl (UOBJC_SUPER_decl
, NULL_TREE
, NULL_TREE
);
7280 /* This prevents `unused variable' warnings when compiling with -Wall. */
7281 TREE_USED (UOBJC_SUPER_decl
) = 1;
7282 DECL_ARTIFICIAL (UOBJC_SUPER_decl
) = 1;
7286 /* _n_Method (id self, SEL sel, ...)
7288 struct objc_super _S;
7289 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7293 get_super_receiver ()
7297 tree super_expr
, super_expr_list
;
7299 /* Set receiver to self. */
7300 super_expr
= build_component_ref (UOBJC_SUPER_decl
, self_id
);
7301 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, self_decl
);
7302 super_expr_list
= build_tree_list (NULL_TREE
, super_expr
);
7304 /* Set class to begin searching. */
7305 super_expr
= build_component_ref (UOBJC_SUPER_decl
,
7306 get_identifier ("class"));
7308 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
7310 /* [_cls, __cls]Super are "pre-built" in
7311 synth_forward_declarations. */
7313 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
,
7314 ((TREE_CODE (method_context
)
7315 == INSTANCE_METHOD_DECL
)
7317 : uucls_super_ref
));
7321 /* We have a category. */
7323 tree super_name
= CLASS_SUPER_NAME (implementation_template
);
7328 error ("no super class declared in interface for `%s'",
7329 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
7330 return error_mark_node
;
7333 if (flag_next_runtime
)
7335 super_class
= get_class_reference (super_name
);
7336 if (TREE_CODE (method_context
) == CLASS_METHOD_DECL
)
7338 = build_component_ref (build_indirect_ref (super_class
, "->"),
7339 get_identifier ("isa"));
7343 add_class_reference (super_name
);
7344 super_class
= (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
7345 ? objc_get_class_decl
: objc_get_meta_class_decl
);
7346 assemble_external (super_class
);
7348 = build_function_call
7352 my_build_string (IDENTIFIER_LENGTH (super_name
) + 1,
7353 IDENTIFIER_POINTER (super_name
))));
7356 TREE_TYPE (super_class
) = TREE_TYPE (ucls_super_ref
);
7357 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, super_class
);
7360 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7362 super_expr
= build_unary_op (ADDR_EXPR
, UOBJC_SUPER_decl
, 0);
7363 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7365 return build_compound_expr (super_expr_list
);
7369 error ("[super ...] must appear in a method context");
7370 return error_mark_node
;
7375 encode_method_def (func_decl
)
7380 int max_parm_end
= 0;
7385 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
7386 obstack_object_size (&util_obstack
),
7387 OBJC_ENCODE_INLINE_DEFS
);
7390 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7391 parms
= TREE_CHAIN (parms
))
7393 int parm_end
= (forwarding_offset (parms
)
7394 + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms
)))
7397 if (!offset_is_register
&& parm_end
> max_parm_end
)
7398 max_parm_end
= parm_end
;
7401 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
7403 sprintf (buffer
, "%d", stack_size
);
7404 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7406 /* Argument types. */
7407 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7408 parms
= TREE_CHAIN (parms
))
7411 encode_type (TREE_TYPE (parms
),
7412 obstack_object_size (&util_obstack
),
7413 OBJC_ENCODE_INLINE_DEFS
);
7415 /* Compute offset. */
7416 sprintf (buffer
, "%d", forwarding_offset (parms
));
7418 /* Indicate register. */
7419 if (offset_is_register
)
7420 obstack_1grow (&util_obstack
, '+');
7422 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7425 obstack_1grow (&util_obstack
, 0);
7426 result
= get_identifier (obstack_finish (&util_obstack
));
7427 obstack_free (&util_obstack
, util_firstobj
);
7432 finish_method_def ()
7434 METHOD_ENCODING (method_context
) = encode_method_def (current_function_decl
);
7436 finish_function (0);
7438 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7439 since the optimizer may find "may be used before set" errors. */
7440 method_context
= NULL_TREE
;
7445 lang_report_error_function (decl
)
7450 fprintf (stderr
, "In method `%s'\n",
7451 IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context
)));
7461 is_complex_decl (type
)
7464 return (TREE_CODE (type
) == ARRAY_TYPE
7465 || TREE_CODE (type
) == FUNCTION_TYPE
7466 || (TREE_CODE (type
) == POINTER_TYPE
&& ! IS_ID (type
)));
7470 /* Code to convert a decl node into text for a declaration in C. */
7472 static char tmpbuf
[256];
7475 adorn_decl (decl
, str
)
7479 enum tree_code code
= TREE_CODE (decl
);
7481 if (code
== ARRAY_REF
)
7483 tree an_int_cst
= TREE_OPERAND (decl
, 1);
7485 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_CST
)
7486 sprintf (str
+ strlen (str
), "[%ld]",
7487 (long) TREE_INT_CST_LOW (an_int_cst
));
7492 else if (code
== ARRAY_TYPE
)
7494 tree an_int_cst
= TYPE_SIZE (decl
);
7495 tree array_of
= TREE_TYPE (decl
);
7497 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_TYPE
)
7498 sprintf (str
+ strlen (str
), "[%ld]",
7499 (long) (TREE_INT_CST_LOW (an_int_cst
)
7500 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
7505 else if (code
== CALL_EXPR
)
7507 tree chain
= TREE_PURPOSE (TREE_OPERAND (decl
, 1));
7512 gen_declaration (chain
, str
);
7513 chain
= TREE_CHAIN (chain
);
7520 else if (code
== FUNCTION_TYPE
)
7522 tree chain
= TYPE_ARG_TYPES (decl
);
7525 while (chain
&& TREE_VALUE (chain
) != void_type_node
)
7527 gen_declaration (TREE_VALUE (chain
), str
);
7528 chain
= TREE_CHAIN (chain
);
7529 if (chain
&& TREE_VALUE (chain
) != void_type_node
)
7535 else if (code
== INDIRECT_REF
)
7537 strcpy (tmpbuf
, "*");
7538 if (TREE_TYPE (decl
) && TREE_CODE (TREE_TYPE (decl
)) == TREE_LIST
)
7542 for (chain
= nreverse (copy_list (TREE_TYPE (decl
)));
7544 chain
= TREE_CHAIN (chain
))
7546 if (TREE_CODE (TREE_VALUE (chain
)) == IDENTIFIER_NODE
)
7548 strcat (tmpbuf
, " ");
7549 strcat (tmpbuf
, IDENTIFIER_POINTER (TREE_VALUE (chain
)));
7553 strcat (tmpbuf
, " ");
7555 strcat (tmpbuf
, str
);
7556 strcpy (str
, tmpbuf
);
7559 else if (code
== POINTER_TYPE
)
7561 strcpy (tmpbuf
, "*");
7562 if (TREE_READONLY (decl
) || TYPE_VOLATILE (decl
))
7564 if (TREE_READONLY (decl
))
7565 strcat (tmpbuf
, " const");
7566 if (TYPE_VOLATILE (decl
))
7567 strcat (tmpbuf
, " volatile");
7569 strcat (tmpbuf
, " ");
7571 strcat (tmpbuf
, str
);
7572 strcpy (str
, tmpbuf
);
7577 gen_declarator (decl
, buf
, name
)
7584 enum tree_code code
= TREE_CODE (decl
);
7594 op
= TREE_OPERAND (decl
, 0);
7596 /* We have a pointer to a function or array...(*)(), (*)[] */
7597 if ((code
== ARRAY_REF
|| code
== CALL_EXPR
)
7598 && op
&& TREE_CODE (op
) == INDIRECT_REF
)
7601 str
= gen_declarator (op
, buf
, name
);
7605 strcpy (tmpbuf
, "(");
7606 strcat (tmpbuf
, str
);
7607 strcat (tmpbuf
, ")");
7608 strcpy (str
, tmpbuf
);
7611 adorn_decl (decl
, str
);
7620 /* This clause is done iteratively rather than recursively. */
7623 op
= (is_complex_decl (TREE_TYPE (decl
))
7624 ? TREE_TYPE (decl
) : NULL_TREE
);
7626 adorn_decl (decl
, str
);
7628 /* We have a pointer to a function or array...(*)(), (*)[] */
7629 if (code
== POINTER_TYPE
7630 && op
&& (TREE_CODE (op
) == FUNCTION_TYPE
7631 || TREE_CODE (op
) == ARRAY_TYPE
))
7633 strcpy (tmpbuf
, "(");
7634 strcat (tmpbuf
, str
);
7635 strcat (tmpbuf
, ")");
7636 strcpy (str
, tmpbuf
);
7639 decl
= (is_complex_decl (TREE_TYPE (decl
))
7640 ? TREE_TYPE (decl
) : NULL_TREE
);
7643 while (decl
&& (code
= TREE_CODE (decl
)))
7648 case IDENTIFIER_NODE
:
7649 /* Will only happen if we are processing a "raw" expr-decl. */
7650 strcpy (buf
, IDENTIFIER_POINTER (decl
));
7661 /* We have an abstract declarator or a _DECL node. */
7669 gen_declspecs (declspecs
, buf
, raw
)
7678 for (chain
= nreverse (copy_list (declspecs
));
7679 chain
; chain
= TREE_CHAIN (chain
))
7681 tree aspec
= TREE_VALUE (chain
);
7683 if (TREE_CODE (aspec
) == IDENTIFIER_NODE
)
7684 strcat (buf
, IDENTIFIER_POINTER (aspec
));
7685 else if (TREE_CODE (aspec
) == RECORD_TYPE
)
7687 if (TYPE_NAME (aspec
))
7689 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7691 if (! TREE_STATIC_TEMPLATE (aspec
))
7692 strcat (buf
, "struct ");
7693 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7698 tree chain
= protocol_list
;
7705 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7706 chain
= TREE_CHAIN (chain
);
7715 strcat (buf
, "untagged struct");
7718 else if (TREE_CODE (aspec
) == UNION_TYPE
)
7720 if (TYPE_NAME (aspec
))
7722 if (! TREE_STATIC_TEMPLATE (aspec
))
7723 strcat (buf
, "union ");
7724 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7727 strcat (buf
, "untagged union");
7730 else if (TREE_CODE (aspec
) == ENUMERAL_TYPE
)
7732 if (TYPE_NAME (aspec
))
7734 if (! TREE_STATIC_TEMPLATE (aspec
))
7735 strcat (buf
, "enum ");
7736 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7739 strcat (buf
, "untagged enum");
7742 else if (TREE_CODE (aspec
) == TYPE_DECL
&& DECL_NAME (aspec
))
7743 strcat (buf
, IDENTIFIER_POINTER (DECL_NAME (aspec
)));
7745 else if (IS_ID (aspec
))
7747 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7752 tree chain
= protocol_list
;
7759 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7760 chain
= TREE_CHAIN (chain
);
7767 if (TREE_CHAIN (chain
))
7773 /* Type qualifiers. */
7774 if (TREE_READONLY (declspecs
))
7775 strcat (buf
, "const ");
7776 if (TYPE_VOLATILE (declspecs
))
7777 strcat (buf
, "volatile ");
7779 switch (TREE_CODE (declspecs
))
7781 /* Type specifiers. */
7784 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7786 /* Signed integer types. */
7788 if (declspecs
== short_integer_type_node
)
7789 strcat (buf
, "short int ");
7790 else if (declspecs
== integer_type_node
)
7791 strcat (buf
, "int ");
7792 else if (declspecs
== long_integer_type_node
)
7793 strcat (buf
, "long int ");
7794 else if (declspecs
== long_long_integer_type_node
)
7795 strcat (buf
, "long long int ");
7796 else if (declspecs
== signed_char_type_node
7797 || declspecs
== char_type_node
)
7798 strcat (buf
, "char ");
7800 /* Unsigned integer types. */
7802 else if (declspecs
== short_unsigned_type_node
)
7803 strcat (buf
, "unsigned short ");
7804 else if (declspecs
== unsigned_type_node
)
7805 strcat (buf
, "unsigned int ");
7806 else if (declspecs
== long_unsigned_type_node
)
7807 strcat (buf
, "unsigned long ");
7808 else if (declspecs
== long_long_unsigned_type_node
)
7809 strcat (buf
, "unsigned long long ");
7810 else if (declspecs
== unsigned_char_type_node
)
7811 strcat (buf
, "unsigned char ");
7815 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7817 if (declspecs
== float_type_node
)
7818 strcat (buf
, "float ");
7819 else if (declspecs
== double_type_node
)
7820 strcat (buf
, "double ");
7821 else if (declspecs
== long_double_type_node
)
7822 strcat (buf
, "long double ");
7826 if (TYPE_NAME (declspecs
)
7827 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7829 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7831 if (! TREE_STATIC_TEMPLATE (declspecs
))
7832 strcat (buf
, "struct ");
7833 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7837 tree chain
= protocol_list
;
7844 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7845 chain
= TREE_CHAIN (chain
);
7854 strcat (buf
, "untagged struct");
7860 if (TYPE_NAME (declspecs
)
7861 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7863 strcat (buf
, "union ");
7864 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7869 strcat (buf
, "untagged union ");
7873 if (TYPE_NAME (declspecs
)
7874 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7876 strcat (buf
, "enum ");
7877 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7882 strcat (buf
, "untagged enum ");
7886 strcat (buf
, "void ");
7891 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7896 tree chain
= protocol_list
;
7903 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7904 chain
= TREE_CHAIN (chain
);
7921 gen_declaration (atype_or_adecl
, buf
)
7922 tree atype_or_adecl
;
7927 if (TREE_CODE (atype_or_adecl
) == TREE_LIST
)
7929 tree declspecs
; /* "identifier_node", "record_type" */
7930 tree declarator
; /* "array_ref", "indirect_ref", "call_expr"... */
7932 /* We have a "raw", abstract declarator (typename). */
7933 declarator
= TREE_VALUE (atype_or_adecl
);
7934 declspecs
= TREE_PURPOSE (atype_or_adecl
);
7936 gen_declspecs (declspecs
, buf
, 1);
7940 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7947 tree declspecs
; /* "integer_type", "real_type", "record_type"... */
7948 tree declarator
; /* "array_type", "function_type", "pointer_type". */
7950 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7951 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7952 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7953 atype
= TREE_TYPE (atype_or_adecl
);
7955 /* Assume we have a *_type node. */
7956 atype
= atype_or_adecl
;
7958 if (is_complex_decl (atype
))
7962 /* Get the declaration specifier; it is at the end of the list. */
7963 declarator
= chain
= atype
;
7965 chain
= TREE_TYPE (chain
); /* not TREE_CHAIN (chain); */
7966 while (is_complex_decl (chain
));
7973 declarator
= NULL_TREE
;
7976 gen_declspecs (declspecs
, buf
, 0);
7978 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7979 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7980 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7982 const char *decl_name
=
7983 (DECL_NAME (atype_or_adecl
)
7984 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl
)) : "");
7989 strcat (buf
, gen_declarator (declarator
, declbuf
, decl_name
));
7992 else if (decl_name
[0])
7995 strcat (buf
, decl_name
);
7998 else if (declarator
)
8001 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
8008 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
8011 gen_method_decl (method
, buf
)
8017 if (RAW_TYPESPEC (method
) != objc_object_reference
)
8020 gen_declaration (TREE_TYPE (method
), buf
);
8024 chain
= METHOD_SEL_ARGS (method
);
8027 /* We have a chain of keyword_decls. */
8030 if (KEYWORD_KEY_NAME (chain
))
8031 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain
)));
8034 if (RAW_TYPESPEC (chain
) != objc_object_reference
)
8037 gen_declaration (TREE_TYPE (chain
), buf
);
8041 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain
)));
8042 if ((chain
= TREE_CHAIN (chain
)))
8047 if (METHOD_ADD_ARGS (method
) == (tree
)1)
8048 strcat (buf
, ", ...");
8049 else if (METHOD_ADD_ARGS (method
))
8051 /* We have a tree list node as generate by get_parm_info. */
8052 chain
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
8054 /* Know we have a chain of parm_decls. */
8058 gen_declaration (chain
, buf
);
8059 chain
= TREE_CHAIN (chain
);
8065 /* We have a unary selector. */
8066 strcat (buf
, IDENTIFIER_POINTER (METHOD_SEL_NAME (method
)));
8074 dump_interface (fp
, chain
)
8078 char *buf
= (char *)xmalloc (256);
8079 const char *my_name
= IDENTIFIER_POINTER (CLASS_NAME (chain
));
8080 tree ivar_decls
= CLASS_RAW_IVARS (chain
);
8081 tree nst_methods
= CLASS_NST_METHODS (chain
);
8082 tree cls_methods
= CLASS_CLS_METHODS (chain
);
8084 fprintf (fp
, "\n@interface %s", my_name
);
8086 if (CLASS_SUPER_NAME (chain
))
8088 const char *super_name
= IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain
));
8089 fprintf (fp
, " : %s\n", super_name
);
8096 fprintf (fp
, "{\n");
8100 fprintf (fp
, "\t%s;\n", gen_declaration (ivar_decls
, buf
));
8101 ivar_decls
= TREE_CHAIN (ivar_decls
);
8104 fprintf (fp
, "}\n");
8110 fprintf (fp
, "- %s;\n", gen_method_decl (nst_methods
, buf
));
8111 nst_methods
= TREE_CHAIN (nst_methods
);
8117 fprintf (fp
, "+ %s;\n", gen_method_decl (cls_methods
, buf
));
8118 cls_methods
= TREE_CHAIN (cls_methods
);
8120 fprintf (fp
, "\n@end");
8123 /* Demangle function for Objective-C */
8125 objc_demangle (mangled
)
8126 const char *mangled
;
8128 char *demangled
, *cp
;
8130 if (mangled
[0] == '_' &&
8131 (mangled
[1] == 'i' || mangled
[1] == 'c') &&
8134 cp
= demangled
= xmalloc(strlen(mangled
) + 2);
8135 if (mangled
[1] == 'i')
8136 *cp
++ = '-'; /* for instance method */
8138 *cp
++ = '+'; /* for class method */
8139 *cp
++ = '['; /* opening left brace */
8140 strcpy(cp
, mangled
+3); /* tack on the rest of the mangled name */
8141 while (*cp
&& *cp
== '_')
8142 cp
++; /* skip any initial underbars in class name */
8143 cp
= strchr(cp
, '_'); /* find first non-initial underbar */
8146 free(demangled
); /* not mangled name */
8149 if (cp
[1] == '_') /* easy case: no category name */
8151 *cp
++ = ' '; /* replace two '_' with one ' ' */
8152 strcpy(cp
, mangled
+ (cp
- demangled
) + 2);
8156 *cp
++ = '('; /* less easy case: category name */
8157 cp
= strchr(cp
, '_');
8160 free(demangled
); /* not mangled name */
8164 *cp
++ = ' '; /* overwriting 1st char of method name... */
8165 strcpy(cp
, mangled
+ (cp
- demangled
)); /* get it back */
8167 while (*cp
&& *cp
== '_')
8168 cp
++; /* skip any initial underbars in method name */
8171 *cp
= ':'; /* replace remaining '_' with ':' */
8172 *cp
++ = ']'; /* closing right brace */
8173 *cp
++ = 0; /* string terminator */
8177 return mangled
; /* not an objc mangled name */
8181 objc_printable_name (decl
, kind
)
8183 int kind ATTRIBUTE_UNUSED
;
8185 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl
)));
8191 /* Add the special tree codes of Objective C to the tables. */
8193 #define LAST_CODE LAST_AND_UNUSED_TREE_CODE
8195 gcc_obstack_init (&util_obstack
);
8196 util_firstobj
= (char *) obstack_finish (&util_obstack
);
8198 memcpy (tree_code_type
+ (int) LAST_CODE
,
8199 objc_tree_code_type
,
8200 (int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
);
8201 memcpy (tree_code_length
+ (int) LAST_CODE
,
8202 objc_tree_code_length
,
8203 (((int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
) * sizeof (int)));
8204 memcpy (tree_code_name
+ (int) LAST_CODE
,
8205 objc_tree_code_name
,
8206 (((int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
) * sizeof (char *)));
8208 errbuf
= (char *)xmalloc (BUFSIZE
);
8210 synth_module_prologue ();
8212 /* Change the default error function */
8213 decl_printable_name
= objc_printable_name
;
8219 struct imp_entry
*impent
;
8221 /* The internally generated initializers appear to have missing braces.
8222 Don't warn about this. */
8223 int save_warn_missing_braces
= warn_missing_braces
;
8224 warn_missing_braces
= 0;
8226 generate_forward_declaration_to_string_table ();
8228 #ifdef OBJC_PROLOGUE
8232 /* Process the static instances here because initialization of objc_symtab
8234 if (objc_static_instances
)
8235 generate_static_references ();
8237 if (implementation_context
|| class_names_chain
8238 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8239 generate_objc_symtab_decl ();
8241 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8243 implementation_context
= impent
->imp_context
;
8244 implementation_template
= impent
->imp_template
;
8246 UOBJC_CLASS_decl
= impent
->class_decl
;
8247 UOBJC_METACLASS_decl
= impent
->meta_decl
;
8249 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
8251 /* all of the following reference the string pool... */
8252 generate_ivar_lists ();
8253 generate_dispatch_tables ();
8254 generate_shared_structures ();
8258 generate_dispatch_tables ();
8259 generate_category (implementation_context
);
8263 /* If we are using an array of selectors, we must always
8264 finish up the array decl even if no selectors were used. */
8265 if (! flag_next_runtime
|| sel_ref_chain
)
8266 build_selector_translation_table ();
8269 generate_protocols ();
8271 if (implementation_context
|| class_names_chain
|| objc_static_instances
8272 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8274 /* Arrange for Objc data structures to be initialized at run time. */
8275 char *init_name
= build_module_descriptor ();
8277 assemble_constructor (init_name
);
8280 /* Dump the class references. This forces the appropriate classes
8281 to be linked into the executable image, preserving unix archive
8282 semantics. This can be removed when we move to a more dynamically
8283 linked environment. */
8285 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
8287 handle_class_ref (chain
);
8288 if (TREE_PURPOSE (chain
))
8289 generate_classref_translation_entry (chain
);
8292 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8293 handle_impent (impent
);
8295 /* Dump the string table last. */
8297 generate_strings ();
8299 if (flag_gen_declaration
)
8301 add_class (implementation_context
);
8302 dump_interface (gen_declaration_file
, implementation_context
);
8310 /* Run through the selector hash tables and print a warning for any
8311 selector which has multiple methods. */
8313 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8314 for (hsh
= cls_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8317 tree meth
= hsh
->key
;
8318 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8322 warning ("potential selector conflict for method `%s'",
8323 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8324 warn_with_method ("found", type
, meth
);
8325 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8326 warn_with_method ("found", type
, loop
->value
);
8329 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8330 for (hsh
= nst_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8333 tree meth
= hsh
->key
;
8334 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8338 warning ("potential selector conflict for method `%s'",
8339 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8340 warn_with_method ("found", type
, meth
);
8341 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8342 warn_with_method ("found", type
, loop
->value
);
8346 warn_missing_braces
= save_warn_missing_braces
;
8349 /* Subroutines of finish_objc. */
8352 generate_classref_translation_entry (chain
)
8355 tree expr
, name
, decl_specs
, decl
, sc_spec
;
8358 type
= TREE_TYPE (TREE_PURPOSE (chain
));
8360 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
8361 expr
= build_c_cast (type
, expr
); /* cast! */
8363 name
= DECL_NAME (TREE_PURPOSE (chain
));
8365 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
8367 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8368 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
8370 /* The decl that is returned from start_decl is the one that we
8371 forward declared in build_class_reference. */
8372 decl
= start_decl (name
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
8373 finish_decl (decl
, expr
, NULL_TREE
);
8378 handle_class_ref (chain
)
8381 const char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
8382 if (! flag_next_runtime
)
8385 char *string
= (char *) alloca (strlen (name
) + 30);
8388 sprintf (string
, "%sobjc_class_name_%s",
8389 (flag_next_runtime
? "." : "__"), name
);
8391 /* Make a decl for this name, so we can use its address in a tree. */
8392 decl
= build_decl (VAR_DECL
, get_identifier (string
), char_type_node
);
8393 DECL_EXTERNAL (decl
) = 1;
8394 TREE_PUBLIC (decl
) = 1;
8397 rest_of_decl_compilation (decl
, 0, 0, 0);
8399 /* Make following constant read-only (why not)? */
8400 readonly_data_section ();
8402 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
8404 /* Align the section properly. */
8405 assemble_constant_align (exp
);
8407 /* Inform the assembler about this new external thing. */
8408 assemble_external (decl
);
8410 /* Output a constant to reference this address. */
8411 output_constant (exp
, int_size_in_bytes (string_type_node
));
8415 /* This overreliance on our assembler (i.e. lack of portability)
8416 should be dealt with at some point. The GNU strategy (above)
8417 won't work either, but it is a start. */
8418 char *string
= (char *) alloca (strlen (name
) + 30);
8419 sprintf (string
, ".reference .objc_class_name_%s", name
);
8420 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8425 handle_impent (impent
)
8426 struct imp_entry
*impent
;
8428 implementation_context
= impent
->imp_context
;
8429 implementation_template
= impent
->imp_template
;
8431 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
8433 const char *class_name
=
8434 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8435 char *string
= (char *) alloca (strlen (class_name
) + 30);
8437 if (flag_next_runtime
)
8439 /* Grossly unportable.
8440 People should know better than to assume
8441 such things about assembler syntax! */
8442 sprintf (string
, ".objc_class_name_%s=0", class_name
);
8443 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8445 sprintf (string
, ".globl .objc_class_name_%s", class_name
);
8446 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8451 sprintf (string
, "%sobjc_class_name_%s",
8452 (flag_next_runtime
? "." : "__"), class_name
);
8453 assemble_global (string
);
8454 assemble_label (string
);
8458 else if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
8460 const char *class_name
=
8461 IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8462 const char *class_super_name
=
8463 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
8464 char *string
= (char *) alloca (strlen (class_name
)
8465 + strlen (class_super_name
) + 30);
8467 /* Do the same for categories. Even though no references to these
8468 symbols are generated automatically by the compiler, it gives
8469 you a handle to pull them into an archive by hand. */
8470 if (flag_next_runtime
)
8472 /* Grossly unportable. */
8473 sprintf (string
, ".objc_category_name_%s_%s=0",
8474 class_name
, class_super_name
);
8475 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8477 sprintf (string
, ".globl .objc_category_name_%s_%s",
8478 class_name
, class_super_name
);
8479 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8484 sprintf (string
, "%sobjc_category_name_%s_%s",
8485 (flag_next_runtime
? "." : "__"),
8486 class_name
, class_super_name
);
8487 assemble_global (string
);
8488 assemble_label (string
);
8499 char *buf
= (char *)xmalloc (256);
8501 { /* dump function prototypes */
8502 tree loop
= UOBJC_MODULES_decl
;
8504 fprintf (fp
, "\n\nfunction prototypes:\n");
8507 if (TREE_CODE (loop
) == FUNCTION_DECL
&& DECL_INITIAL (loop
))
8509 /* We have a function definition: generate prototype. */
8510 bzero (errbuf
, BUFSIZE
);
8511 gen_declaration (loop
, errbuf
);
8512 fprintf (fp
, "%s;\n", errbuf
);
8514 loop
= TREE_CHAIN (loop
);
8518 /* Dump global chains. */
8520 int i
, index
= 0, offset
= 0;
8523 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
8525 if (hashlist
= nst_method_hash_list
[i
])
8527 fprintf (fp
, "\n\nnst_method_hash_list[%d]:\n", i
);
8531 fprintf (fp
, "-%s;\n", gen_method_decl (hashlist
->key
, buf
));
8532 hashlist
= hashlist
->next
;
8538 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
8540 if (hashlist
= cls_method_hash_list
[i
])
8542 fprintf (fp
, "\n\ncls_method_hash_list[%d]:\n", i
);
8546 fprintf (fp
, "-%s;\n", gen_method_decl (hashlist
->key
, buf
));
8547 hashlist
= hashlist
->next
;
8553 fprintf (fp
, "\nsel_refdef_chain:\n");
8554 for (loop
= sel_refdef_chain
; loop
; loop
= TREE_CHAIN (loop
))
8556 fprintf (fp
, "(index: %4d offset: %4d) %s\n", index
, offset
,
8557 IDENTIFIER_POINTER (TREE_VALUE (loop
)));
8559 /* add one for the '\0' character */
8560 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (loop
)) + 1;
8563 fprintf (fp
, "\n (max_selector_index: %4d.\n", max_selector_index
);
8569 print_lang_statistics ()