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 */
57 /* This is the default way of generating a method name. */
58 /* I am not sure it is really correct.
59 Perhaps there's a danger that it will make name conflicts
60 if method names contain underscores. -- rms. */
61 #ifndef OBJC_GEN_METHOD_LABEL
62 #define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \
65 sprintf ((BUF), "_%s_%s_%s_%s", \
66 ((IS_INST) ? "i" : "c"), \
68 ((CAT_NAME)? (CAT_NAME) : ""), \
70 for (temp = (BUF); *temp; temp++) \
71 if (*temp == ':') *temp = '_'; \
75 /* These need specifying. */
76 #ifndef OBJC_FORWARDING_STACK_OFFSET
77 #define OBJC_FORWARDING_STACK_OFFSET 0
80 #ifndef OBJC_FORWARDING_MIN_OFFSET
81 #define OBJC_FORWARDING_MIN_OFFSET 0
84 /* Define the special tree codes that we use. */
86 /* Table indexed by tree code giving a string containing a character
87 classifying the tree code. Possibilities are
88 t, d, s, c, r, <, 1 and 2. See objc-tree.def for details. */
90 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
92 char objc_tree_code_type
[] = {
94 #include "objc-tree.def"
98 /* Table indexed by tree code giving number of expression
99 operands beyond the fixed part of the node structure.
100 Not used for types or decls. */
102 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
104 int objc_tree_code_length
[] = {
106 #include "objc-tree.def"
110 /* Names of tree components.
111 Used for printing out the tree and error messages. */
112 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
114 char *objc_tree_code_name
[] = {
116 #include "objc-tree.def"
120 /* Set up for use of obstacks. */
124 #define obstack_chunk_alloc xmalloc
125 #define obstack_chunk_free free
127 /* This obstack is used to accumulate the encoding of a data type. */
128 static struct obstack util_obstack
;
129 /* This points to the beginning of obstack contents,
130 so we can free the whole contents. */
133 /* List of classes with list of their static instances. */
134 static tree objc_static_instances
= NULL_TREE
;
136 /* The declaration of the array administrating the static instances. */
137 static tree static_instances_decl
= NULL_TREE
;
139 /* for encode_method_def */
143 #define OBJC_VERSION (flag_next_runtime ? 5 : 8)
144 #define PROTOCOL_VERSION 2
146 #define OBJC_ENCODE_INLINE_DEFS 0
147 #define OBJC_ENCODE_DONT_INLINE_DEFS 1
149 /*** Private Interface (procedures) ***/
151 /* Used by compile_file. */
153 static void init_objc
PROTO((void));
154 static void finish_objc
PROTO((void));
156 /* Code generation. */
158 static void synth_module_prologue
PROTO((void));
159 static tree build_constructor
PROTO((tree
, tree
));
160 static char *build_module_descriptor
PROTO((void));
161 static tree init_module_descriptor
PROTO((tree
));
162 static tree build_objc_method_call
PROTO((int, tree
, tree
,
164 static void generate_strings
PROTO((void));
165 static tree get_proto_encoding
PROTO((tree
));
166 static void build_selector_translation_table
PROTO((void));
167 static tree build_ivar_chain
PROTO((tree
, int));
169 static tree objc_add_static_instance
PROTO((tree
, tree
));
171 static tree build_ivar_template
PROTO((void));
172 static tree build_method_template
PROTO((void));
173 static tree build_private_template
PROTO((tree
));
174 static void build_class_template
PROTO((void));
175 static void build_selector_template
PROTO((void));
176 static void build_category_template
PROTO((void));
177 static tree build_super_template
PROTO((void));
178 static tree build_category_initializer
PROTO((tree
, tree
, tree
,
180 static tree build_protocol_initializer
PROTO((tree
, tree
, tree
,
183 static void synth_forward_declarations
PROTO((void));
184 static void generate_ivar_lists
PROTO((void));
185 static void generate_dispatch_tables
PROTO((void));
186 static void generate_shared_structures
PROTO((void));
187 static tree generate_protocol_list
PROTO((tree
));
188 static void generate_forward_declaration_to_string_table
PROTO((void));
189 static void build_protocol_reference
PROTO((tree
));
191 static tree init_selector
PROTO((int));
192 static tree build_keyword_selector
PROTO((tree
));
193 static tree synth_id_with_class_suffix
PROTO((char *, tree
));
195 static void generate_static_references
PROTO((void));
196 static int check_methods_accessible
PROTO((tree
, tree
,
198 static void encode_aggregate_within
PROTO((tree
, int, int,
201 /* We handle printing method names ourselves for ObjC */
202 extern char *(*decl_printable_name
) ();
204 /* Misc. bookkeeping */
206 typedef struct hashed_entry
*hash
;
207 typedef struct hashed_attribute
*attr
;
209 struct hashed_attribute
221 static void hash_init
PROTO((void));
222 static void hash_enter
PROTO((hash
*, tree
));
223 static hash hash_lookup
PROTO((hash
*, tree
));
224 static void hash_add_attr
PROTO((hash
, tree
));
225 static tree lookup_method
PROTO((tree
, tree
));
226 static tree lookup_instance_method_static
PROTO((tree
, tree
));
227 static tree lookup_class_method_static
PROTO((tree
, tree
));
228 static tree add_class
PROTO((tree
));
229 static void add_category
PROTO((tree
, tree
));
233 class_names
, /* class, category, protocol, module names */
234 meth_var_names
, /* method and variable names */
235 meth_var_types
/* method and variable type descriptors */
238 static tree add_objc_string
PROTO((tree
,
239 enum string_section
));
240 static tree get_objc_string_decl
PROTO((tree
,
241 enum string_section
));
242 static tree build_objc_string_decl
PROTO((tree
,
243 enum string_section
));
244 static tree build_selector_reference_decl
PROTO((tree
));
246 /* Protocol additions. */
248 static tree add_protocol
PROTO((tree
));
249 static tree lookup_protocol
PROTO((tree
));
250 static tree lookup_and_install_protocols
PROTO((tree
));
254 static void encode_type_qualifiers
PROTO((tree
));
255 static void encode_pointer
PROTO((tree
, int, int));
256 static void encode_array
PROTO((tree
, int, int));
257 static void encode_aggregate
PROTO((tree
, int, int));
258 static void encode_bitfield
PROTO((int, int));
259 static void encode_type
PROTO((tree
, int, int));
260 static void encode_field_decl
PROTO((tree
, int, int));
262 static void really_start_method
PROTO((tree
, tree
));
263 static int comp_method_with_proto
PROTO((tree
, tree
));
264 static int comp_proto_with_proto
PROTO((tree
, tree
));
265 static tree get_arg_type_list
PROTO((tree
, int, int));
266 static tree expr_last
PROTO((tree
));
268 /* Utilities for debugging and error diagnostics. */
270 static void warn_with_method
PROTO((char *, int, tree
));
271 static void error_with_ivar
PROTO((char *, tree
, tree
));
272 static char *gen_method_decl
PROTO((tree
, char *));
273 static char *gen_declaration
PROTO((tree
, char *));
274 static char *gen_declarator
PROTO((tree
, char *, char *));
275 static int is_complex_decl
PROTO((tree
));
276 static void adorn_decl
PROTO((tree
, char *));
277 static void dump_interface
PROTO((FILE *, tree
));
279 /* Everything else. */
281 static void objc_fatal
PROTO((void));
282 static tree define_decl
PROTO((tree
, tree
));
283 static tree lookup_method_in_protocol_list
PROTO((tree
, tree
, int));
284 static tree lookup_protocol_in_reflist
PROTO((tree
, tree
));
285 static tree create_builtin_decl
PROTO((enum tree_code
,
287 static tree my_build_string
PROTO((int, char *));
288 static void build_objc_symtab_template
PROTO((void));
289 static tree init_def_list
PROTO((tree
));
290 static tree init_objc_symtab
PROTO((tree
));
291 static void forward_declare_categories
PROTO((void));
292 static void generate_objc_symtab_decl
PROTO((void));
293 static tree build_selector
PROTO((tree
));
294 static tree build_msg_pool_reference
PROTO((int));
295 static tree build_typed_selector_reference
PROTO((tree
, tree
));
296 static tree build_selector_reference
PROTO((tree
));
297 static tree build_class_reference_decl
PROTO((tree
));
298 static void add_class_reference
PROTO((tree
));
299 static tree objc_copy_list
PROTO((tree
, tree
*));
300 static tree build_protocol_template
PROTO((void));
301 static tree build_descriptor_table_initializer
PROTO((tree
, tree
));
302 static tree build_method_prototype_list_template
PROTO((tree
, int));
303 static tree build_method_prototype_template
PROTO((void));
304 static int forwarding_offset
PROTO((tree
));
305 static tree encode_method_prototype
PROTO((tree
, tree
));
306 static tree generate_descriptor_table
PROTO((tree
, char *, int, tree
, tree
));
307 static void generate_method_descriptors
PROTO((tree
));
308 static tree build_tmp_function_decl
PROTO((void));
309 static void hack_method_prototype
PROTO((tree
, tree
));
310 static void generate_protocol_references
PROTO((tree
));
311 static void generate_protocols
PROTO((void));
312 static void check_ivars
PROTO((tree
, tree
));
313 static tree build_ivar_list_template
PROTO((tree
, int));
314 static tree build_method_list_template
PROTO((tree
, int));
315 static tree build_ivar_list_initializer
PROTO((tree
, tree
));
316 static tree generate_ivars_list
PROTO((tree
, char *,
318 static tree build_dispatch_table_initializer
PROTO((tree
, tree
));
319 static tree generate_dispatch_table
PROTO((tree
, char *,
321 static tree build_shared_structure_initializer
PROTO((tree
, tree
, tree
, tree
,
322 tree
, int, tree
, tree
,
324 static void generate_category
PROTO((tree
));
325 static int is_objc_type_qualifier
PROTO((tree
));
326 static tree adjust_type_for_id_default
PROTO((tree
));
327 static tree check_duplicates
PROTO((hash
));
328 static tree receiver_is_class_object
PROTO((tree
));
329 static int check_methods
PROTO((tree
, tree
, int));
330 static int conforms_to_protocol
PROTO((tree
, tree
));
331 static void check_protocols
PROTO((tree
, char *, char *));
332 static tree encode_method_def
PROTO((tree
));
333 static void gen_declspecs
PROTO((tree
, char *, int));
334 static void generate_classref_translation_entry
PROTO((tree
));
335 static void handle_class_ref
PROTO((tree
));
337 /*** Private Interface (data) ***/
339 /* Reserved tag definitions. */
342 #define TAG_OBJECT "objc_object"
343 #define TAG_CLASS "objc_class"
344 #define TAG_SUPER "objc_super"
345 #define TAG_SELECTOR "objc_selector"
347 #define UTAG_CLASS "_objc_class"
348 #define UTAG_IVAR "_objc_ivar"
349 #define UTAG_IVAR_LIST "_objc_ivar_list"
350 #define UTAG_METHOD "_objc_method"
351 #define UTAG_METHOD_LIST "_objc_method_list"
352 #define UTAG_CATEGORY "_objc_category"
353 #define UTAG_MODULE "_objc_module"
354 #define UTAG_STATICS "_objc_statics"
355 #define UTAG_SYMTAB "_objc_symtab"
356 #define UTAG_SUPER "_objc_super"
357 #define UTAG_SELECTOR "_objc_selector"
359 #define UTAG_PROTOCOL "_objc_protocol"
360 #define UTAG_PROTOCOL_LIST "_objc_protocol_list"
361 #define UTAG_METHOD_PROTOTYPE "_objc_method_prototype"
362 #define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list"
364 #define STRING_OBJECT_CLASS_NAME "NXConstantString"
365 #define PROTOCOL_OBJECT_CLASS_NAME "Protocol"
367 static char *TAG_GETCLASS
;
368 static char *TAG_GETMETACLASS
;
369 static char *TAG_MSGSEND
;
370 static char *TAG_MSGSENDSUPER
;
371 static char *TAG_EXECCLASS
;
373 /* Set by `continue_class' and checked by `is_public'. */
375 #define TREE_STATIC_TEMPLATE(record_type) (TREE_PUBLIC (record_type))
376 #define TYPED_OBJECT(type) \
377 (TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type))
379 /* Some commonly used instances of "identifier_node". */
381 static tree self_id
, ucmd_id
;
382 static tree unused_list
;
384 static tree self_decl
, umsg_decl
, umsg_super_decl
;
385 static tree objc_get_class_decl
, objc_get_meta_class_decl
;
387 static tree super_type
, selector_type
, id_type
, objc_class_type
;
388 static tree instance_type
, protocol_type
;
390 /* Type checking macros. */
392 #define IS_ID(TYPE) \
393 (TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (id_type))
394 #define IS_PROTOCOL_QUALIFIED_ID(TYPE) \
395 (IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE))
396 #define IS_SUPER(TYPE) \
397 (super_type && TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (super_type))
399 static tree class_chain
= NULL_TREE
;
400 static tree alias_chain
= NULL_TREE
;
401 static tree interface_chain
= NULL_TREE
;
402 static tree protocol_chain
= NULL_TREE
;
404 /* Chains to manage selectors that are referenced and defined in the
407 static tree cls_ref_chain
= NULL_TREE
; /* Classes referenced. */
408 static tree sel_ref_chain
= NULL_TREE
; /* Selectors referenced. */
410 /* Chains to manage uniquing of strings. */
412 static tree class_names_chain
= NULL_TREE
;
413 static tree meth_var_names_chain
= NULL_TREE
;
414 static tree meth_var_types_chain
= NULL_TREE
;
416 /* Hash tables to manage the global pool of method prototypes. */
418 static hash
*nst_method_hash_list
= 0;
419 static hash
*cls_method_hash_list
= 0;
421 /* Backend data declarations. */
423 static tree UOBJC_SYMBOLS_decl
;
424 static tree UOBJC_INSTANCE_VARIABLES_decl
, UOBJC_CLASS_VARIABLES_decl
;
425 static tree UOBJC_INSTANCE_METHODS_decl
, UOBJC_CLASS_METHODS_decl
;
426 static tree UOBJC_CLASS_decl
, UOBJC_METACLASS_decl
;
427 static tree UOBJC_SELECTOR_TABLE_decl
;
428 static tree UOBJC_MODULES_decl
;
429 static tree UOBJC_STRINGS_decl
;
431 /* The following are used when compiling a class implementation.
432 implementation_template will normally be an interface, however if
433 none exists this will be equal to implementation_context...it is
434 set in start_class. */
436 static tree implementation_context
= NULL_TREE
;
437 static tree implementation_template
= NULL_TREE
;
441 struct imp_entry
*next
;
444 tree class_decl
; /* _OBJC_CLASS_<my_name>; */
445 tree meta_decl
; /* _OBJC_METACLASS_<my_name>; */
448 static void handle_impent
PROTO((struct imp_entry
*));
450 static struct imp_entry
*imp_list
= 0;
451 static int imp_count
= 0; /* `@implementation' */
452 static int cat_count
= 0; /* `@category' */
454 static tree objc_class_template
, objc_category_template
, uprivate_record
;
455 static tree objc_protocol_template
, objc_selector_template
;
456 static tree ucls_super_ref
, uucls_super_ref
;
458 static tree objc_method_template
, objc_ivar_template
;
459 static tree objc_symtab_template
, objc_module_template
;
460 static tree objc_super_template
, objc_object_reference
;
462 static tree objc_object_id
, objc_class_id
, objc_id_id
;
463 static tree constant_string_id
;
464 static tree constant_string_type
;
465 static tree UOBJC_SUPER_decl
;
467 static tree method_context
= NULL_TREE
;
468 static int method_slot
= 0; /* Used by start_method_def, */
472 static char *errbuf
; /* Buffer for error diagnostics */
474 /* Data imported from tree.c. */
476 extern enum debug_info_type write_symbols
;
478 /* Data imported from toplev.c. */
480 extern char *dump_base_name
;
482 /* Generate code for GNU or NeXT runtime environment. */
484 #ifdef NEXT_OBJC_RUNTIME
485 int flag_next_runtime
= 1;
487 int flag_next_runtime
= 0;
490 int flag_typed_selectors
;
492 /* Open and close the file for outputting class declarations, if requested. */
494 int flag_gen_declaration
= 0;
496 FILE *gen_declaration_file
;
498 /* Warn if multiple methods are seen for the same selector, but with
499 different argument types. */
501 int warn_selector
= 0;
503 /* Warn if methods required by a protocol are not implemented in the
504 class adopting it. When turned off, methods inherited to that
505 class are also considered implemented */
507 int flag_warn_protocol
= 1;
509 /* Tells "encode_pointer/encode_aggregate" whether we are generating
510 type descriptors for instance variables (as opposed to methods).
511 Type descriptors for instance variables contain more information
512 than methods (for static typing and embedded structures). This
513 was added to support features being planned for dbkit2. */
515 static int generating_instance_variables
= 0;
517 /* Tells the compiler that this is a special run. Do not perform
518 any compiling, instead we are to test some platform dependent
519 features and output a C header file with appropriate definitions. */
521 static int print_struct_values
= 0;
523 /* Some platforms pass small structures through registers versus through
524 an invisible pointer. Determine at what size structure is the
525 transition point between the two possibilities. */
528 generate_struct_by_value_array ()
531 tree field_decl
, field_decl_chain
;
533 int aggregate_in_mem
[32];
536 /* Presumbaly no platform passes 32 byte structures in a register. */
537 for (i
= 1; i
< 32; i
++)
541 /* Create an unnamed struct that has `i' character components */
542 type
= start_struct (RECORD_TYPE
, NULL_TREE
);
544 strcpy (buffer
, "c1");
545 field_decl
= create_builtin_decl (FIELD_DECL
,
548 field_decl_chain
= field_decl
;
550 for (j
= 1; j
< i
; j
++)
552 sprintf (buffer
, "c%d", j
+ 1);
553 field_decl
= create_builtin_decl (FIELD_DECL
,
556 chainon (field_decl_chain
, field_decl
);
558 finish_struct (type
, field_decl_chain
, NULL_TREE
);
560 aggregate_in_mem
[i
] = aggregate_value_p (type
);
561 if (!aggregate_in_mem
[i
])
565 /* We found some structures that are returned in registers instead of memory
566 so output the necessary data. */
569 for (i
= 31; i
>= 0; i
--)
570 if (!aggregate_in_mem
[i
])
572 printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i
);
574 /* The first member of the structure is always 0 because we don't handle
575 structures with 0 members */
576 printf ("static int struct_forward_array[] = {\n 0");
578 for (j
= 1; j
<= i
; j
++)
579 printf (", %d", aggregate_in_mem
[j
]);
590 /* The beginning of the file is a new line; check for #.
591 With luck, we discover the real source file's name from that
592 and put it in input_filename. */
593 ungetc (check_newline (), finput
);
596 /* The line number can be -1 if we had -g3 and the input file
597 had a directive specifying line 0. But we want predefined
598 functions to have a line number of 0, not -1. */
602 /* If gen_declaration desired, open the output file. */
603 if (flag_gen_declaration
)
605 int dump_base_name_length
= strlen (dump_base_name
);
606 register char *dumpname
= (char *) xmalloc (dump_base_name_length
+ 7);
607 strcpy (dumpname
, dump_base_name
);
608 strcat (dumpname
, ".decl");
609 gen_declaration_file
= fopen (dumpname
, "w");
610 if (gen_declaration_file
== 0)
611 pfatal_with_name (dumpname
);
614 if (flag_next_runtime
)
616 TAG_GETCLASS
= "objc_getClass";
617 TAG_GETMETACLASS
= "objc_getMetaClass";
618 TAG_MSGSEND
= "objc_msgSend";
619 TAG_MSGSENDSUPER
= "objc_msgSendSuper";
620 TAG_EXECCLASS
= "__objc_execClass";
624 TAG_GETCLASS
= "objc_get_class";
625 TAG_GETMETACLASS
= "objc_get_meta_class";
626 TAG_MSGSEND
= "objc_msg_lookup";
627 TAG_MSGSENDSUPER
= "objc_msg_lookup_super";
628 TAG_EXECCLASS
= "__objc_exec_class";
629 flag_typed_selectors
= 1;
632 if (doing_objc_thang
)
635 if (print_struct_values
)
636 generate_struct_by_value_array ();
642 fatal ("Objective-C text in C source file");
648 if (doing_objc_thang
)
649 finish_objc (); /* Objective-C finalization */
651 if (gen_declaration_file
)
652 fclose (gen_declaration_file
);
667 lang_decode_option (p
)
670 if (!strcmp (p
, "-lang-objc"))
671 doing_objc_thang
= 1;
672 else if (!strcmp (p
, "-gen-decls"))
673 flag_gen_declaration
= 1;
674 else if (!strcmp (p
, "-Wselector"))
676 else if (!strcmp (p
, "-Wno-selector"))
678 else if (!strcmp (p
, "-Wprotocol"))
679 flag_warn_protocol
= 1;
680 else if (!strcmp (p
, "-Wno-protocol"))
681 flag_warn_protocol
= 0;
682 else if (!strcmp (p
, "-fgnu-runtime"))
683 flag_next_runtime
= 0;
684 else if (!strcmp (p
, "-fno-next-runtime"))
685 flag_next_runtime
= 0;
686 else if (!strcmp (p
, "-fno-gnu-runtime"))
687 flag_next_runtime
= 1;
688 else if (!strcmp (p
, "-fnext-runtime"))
689 flag_next_runtime
= 1;
690 else if (!strcmp (p
, "-print-objc-runtime-info"))
691 print_struct_values
= 1;
693 return c_decode_option (p
);
698 /* used by print-tree.c */
701 lang_print_xnode (file
, node
, indent
)
710 define_decl (declarator
, declspecs
)
714 tree decl
= start_decl (declarator
, declspecs
, 0, NULL_TREE
, NULL_TREE
);
715 finish_decl (decl
, NULL_TREE
, NULL_TREE
);
719 /* Return 1 if LHS and RHS are compatible types for assignment or
720 various other operations. Return 0 if they are incompatible, and
721 return -1 if we choose to not decide. When the operation is
722 REFLEXIVE, check for compatibility in either direction.
724 For statically typed objects, an assignment of the form `a' = `b'
728 `a' and `b' are the same class type, or
729 `a' and `b' are of class types A and B such that B is a descendant of A. */
732 maybe_objc_comptypes (lhs
, rhs
, reflexive
)
736 if (doing_objc_thang
)
737 return objc_comptypes (lhs
, rhs
, reflexive
);
742 lookup_method_in_protocol_list (rproto_list
, sel_name
, class_meth
)
750 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
752 p
= TREE_VALUE (rproto
);
754 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
756 if ((fnd
= lookup_method (class_meth
757 ? PROTOCOL_CLS_METHODS (p
)
758 : PROTOCOL_NST_METHODS (p
), sel_name
)))
760 else if (PROTOCOL_LIST (p
))
761 fnd
= lookup_method_in_protocol_list (PROTOCOL_LIST (p
),
762 sel_name
, class_meth
);
766 ; /* An identifier...if we could not find a protocol. */
777 lookup_protocol_in_reflist (rproto_list
, lproto
)
783 /* Make sure the protocol is support by the object on the rhs. */
784 if (TREE_CODE (lproto
) == PROTOCOL_INTERFACE_TYPE
)
787 for (rproto
= rproto_list
; rproto
; rproto
= TREE_CHAIN (rproto
))
789 p
= TREE_VALUE (rproto
);
791 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
796 else if (PROTOCOL_LIST (p
))
797 fnd
= lookup_protocol_in_reflist (PROTOCOL_LIST (p
), lproto
);
806 ; /* An identifier...if we could not find a protocol. */
812 /* Return 1 if LHS and RHS are compatible types for assignment
813 or various other operations. Return 0 if they are incompatible,
814 and return -1 if we choose to not decide. When the operation
815 is REFLEXIVE, check for compatibility in either direction. */
818 objc_comptypes (lhs
, rhs
, reflexive
)
823 /* New clause for protocols. */
825 if (TREE_CODE (lhs
) == POINTER_TYPE
826 && TREE_CODE (TREE_TYPE (lhs
)) == RECORD_TYPE
827 && TREE_CODE (rhs
) == POINTER_TYPE
828 && TREE_CODE (TREE_TYPE (rhs
)) == RECORD_TYPE
)
830 int lhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (lhs
);
831 int rhs_is_proto
= IS_PROTOCOL_QUALIFIED_ID (rhs
);
835 tree lproto
, lproto_list
= TYPE_PROTOCOL_LIST (lhs
);
836 tree rproto
, rproto_list
;
841 rproto_list
= TYPE_PROTOCOL_LIST (rhs
);
843 /* Make sure the protocol is supported by the object
845 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
847 p
= TREE_VALUE (lproto
);
848 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
851 warning ("object does not conform to the `%s' protocol",
852 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
855 else if (TYPED_OBJECT (TREE_TYPE (rhs
)))
857 tree rname
= TYPE_NAME (TREE_TYPE (rhs
));
860 /* Make sure the protocol is supported by the object
862 for (lproto
= lproto_list
; lproto
; lproto
= TREE_CHAIN (lproto
))
864 p
= TREE_VALUE (lproto
);
866 rinter
= lookup_interface (rname
);
868 while (rinter
&& !rproto
)
872 rproto_list
= CLASS_PROTOCOL_LIST (rinter
);
873 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
875 /* Check for protocols adopted by categories. */
876 cat
= CLASS_CATEGORY_LIST (rinter
);
877 while (cat
&& !rproto
)
879 rproto_list
= CLASS_PROTOCOL_LIST (cat
);
880 rproto
= lookup_protocol_in_reflist (rproto_list
, p
);
882 cat
= CLASS_CATEGORY_LIST (cat
);
885 rinter
= lookup_interface (CLASS_SUPER_NAME (rinter
));
889 warning ("class `%s' does not implement the `%s' protocol",
890 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs
))),
891 IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
895 /* May change...based on whether there was any mismatch */
898 else if (rhs_is_proto
)
899 /* Lhs is not a protocol...warn if it is statically typed */
900 return (TYPED_OBJECT (TREE_TYPE (lhs
)) != 0);
903 /* Defer to comptypes .*/
907 else if (TREE_CODE (lhs
) == RECORD_TYPE
&& TREE_CODE (rhs
) == RECORD_TYPE
)
908 ; /* Fall thru. This is the case we have been handling all along */
910 /* Defer to comptypes. */
913 /* `id' = `<class> *', `<class> *' = `id' */
915 if ((TYPE_NAME (lhs
) == objc_object_id
&& TYPED_OBJECT (rhs
))
916 || (TYPE_NAME (rhs
) == objc_object_id
&& TYPED_OBJECT (lhs
)))
919 /* `id' = `Class', `Class' = `id' */
921 else if ((TYPE_NAME (lhs
) == objc_object_id
922 && TYPE_NAME (rhs
) == objc_class_id
)
923 || (TYPE_NAME (lhs
) == objc_class_id
924 && TYPE_NAME (rhs
) == objc_object_id
))
927 /* `<class> *' = `<class> *' */
929 else if (TYPED_OBJECT (lhs
) && TYPED_OBJECT (rhs
))
931 tree lname
= TYPE_NAME (lhs
);
932 tree rname
= TYPE_NAME (rhs
);
938 /* If the left hand side is a super class of the right hand side,
940 for (inter
= lookup_interface (rname
); inter
;
941 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
942 if (lname
== CLASS_SUPER_NAME (inter
))
945 /* Allow the reverse when reflexive. */
947 for (inter
= lookup_interface (lname
); inter
;
948 inter
= lookup_interface (CLASS_SUPER_NAME (inter
)))
949 if (rname
== CLASS_SUPER_NAME (inter
))
955 /* Defer to comptypes. */
959 /* Called from c-decl.c before all calls to rest_of_decl_compilation. */
962 objc_check_decl (decl
)
965 tree type
= TREE_TYPE (decl
);
967 if (TREE_CODE (type
) == RECORD_TYPE
968 && TREE_STATIC_TEMPLATE (type
)
969 && type
!= constant_string_type
)
971 error_with_decl (decl
, "`%s' cannot be statically allocated");
972 fatal ("statically allocated objects not supported");
977 maybe_objc_check_decl (decl
)
980 if (doing_objc_thang
)
981 objc_check_decl (decl
);
984 /* Implement static typing. At this point, we know we have an interface. */
987 get_static_reference (interface
, protocols
)
991 tree type
= xref_tag (RECORD_TYPE
, interface
);
995 tree t
, m
= TYPE_MAIN_VARIANT (type
);
997 push_obstacks_nochange ();
998 end_temporary_allocation ();
999 t
= copy_node (type
);
1000 TYPE_BINFO (t
) = make_tree_vec (2);
1003 /* Add this type to the chain of variants of TYPE. */
1004 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
1005 TYPE_NEXT_VARIANT (m
) = t
;
1007 /* Look up protocols and install in lang specific list. */
1008 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
1010 /* This forces a new pointer type to be created later
1011 (in build_pointer_type)...so that the new template
1012 we just created will actually be used...what a hack! */
1013 if (TYPE_POINTER_TO (t
))
1014 TYPE_POINTER_TO (t
) = 0;
1023 get_object_reference (protocols
)
1026 tree type_decl
= lookup_name (objc_id_id
);
1029 if (type_decl
&& TREE_CODE (type_decl
) == TYPE_DECL
)
1031 type
= TREE_TYPE (type_decl
);
1032 if (TYPE_MAIN_VARIANT (type
) != id_type
)
1033 warning ("Unexpected type for `id' (%s)",
1034 gen_declaration (type
, errbuf
));
1037 fatal ("Undefined type `id', please import <objc/objc.h>");
1039 /* This clause creates a new pointer type that is qualified with
1040 the protocol specification...this info is used later to do more
1041 elaborate type checking. */
1045 tree t
, m
= TYPE_MAIN_VARIANT (type
);
1047 push_obstacks_nochange ();
1048 end_temporary_allocation ();
1049 t
= copy_node (type
);
1050 TYPE_BINFO (t
) = make_tree_vec (2);
1053 /* Add this type to the chain of variants of TYPE. */
1054 TYPE_NEXT_VARIANT (t
) = TYPE_NEXT_VARIANT (m
);
1055 TYPE_NEXT_VARIANT (m
) = t
;
1057 /* Look up protocols...and install in lang specific list */
1058 TYPE_PROTOCOL_LIST (t
) = lookup_and_install_protocols (protocols
);
1060 /* This forces a new pointer type to be created later
1061 (in build_pointer_type)...so that the new template
1062 we just created will actually be used...what a hack! */
1063 if (TYPE_POINTER_TO (t
))
1064 TYPE_POINTER_TO (t
) = NULL
;
1072 lookup_and_install_protocols (protocols
)
1077 tree return_value
= protocols
;
1079 for (proto
= protocols
; proto
; proto
= TREE_CHAIN (proto
))
1081 tree ident
= TREE_VALUE (proto
);
1082 tree p
= lookup_protocol (ident
);
1086 error ("Cannot find protocol declaration for `%s'",
1087 IDENTIFIER_POINTER (ident
));
1089 TREE_CHAIN (prev
) = TREE_CHAIN (proto
);
1091 return_value
= TREE_CHAIN (proto
);
1095 /* Replace identifier with actual protocol node. */
1096 TREE_VALUE (proto
) = p
;
1101 return return_value
;
1104 /* Create and push a decl for a built-in external variable or field NAME.
1106 TYPE is its data type. */
1109 create_builtin_decl (code
, type
, name
)
1110 enum tree_code code
;
1114 tree decl
= build_decl (code
, get_identifier (name
), type
);
1116 if (code
== VAR_DECL
)
1118 TREE_STATIC (decl
) = 1;
1119 make_decl_rtl (decl
, 0, 1);
1123 DECL_ARTIFICIAL (decl
) = 1;
1127 /* Purpose: "play" parser, creating/installing representations
1128 of the declarations that are required by Objective-C.
1132 type_spec--------->sc_spec
1133 (tree_list) (tree_list)
1136 identifier_node identifier_node */
1139 synth_module_prologue ()
1144 /* Defined in `objc.h' */
1145 objc_object_id
= get_identifier (TAG_OBJECT
);
1147 objc_object_reference
= xref_tag (RECORD_TYPE
, objc_object_id
);
1149 id_type
= build_pointer_type (objc_object_reference
);
1151 objc_id_id
= get_identifier (TYPE_ID
);
1152 objc_class_id
= get_identifier (TAG_CLASS
);
1154 objc_class_type
= build_pointer_type (xref_tag (RECORD_TYPE
, objc_class_id
));
1155 protocol_type
= build_pointer_type (xref_tag (RECORD_TYPE
,
1156 get_identifier (PROTOCOL_OBJECT_CLASS_NAME
)));
1158 /* Declare type of selector-objects that represent an operation name. */
1160 #ifdef OBJC_INT_SELECTORS
1161 /* `unsigned int' */
1162 selector_type
= unsigned_type_node
;
1164 /* `struct objc_selector *' */
1166 = build_pointer_type (xref_tag (RECORD_TYPE
,
1167 get_identifier (TAG_SELECTOR
)));
1168 #endif /* not OBJC_INT_SELECTORS */
1170 /* Forward declare type, or else the prototype for msgSendSuper will
1173 super_p
= build_pointer_type (xref_tag (RECORD_TYPE
,
1174 get_identifier (TAG_SUPER
)));
1177 /* id objc_msgSend (id, SEL, ...); */
1180 = build_function_type (id_type
,
1181 tree_cons (NULL_TREE
, id_type
,
1182 tree_cons (NULL_TREE
, selector_type
,
1185 if (! flag_next_runtime
)
1187 umsg_decl
= build_decl (FUNCTION_DECL
,
1188 get_identifier (TAG_MSGSEND
), temp_type
);
1189 DECL_EXTERNAL (umsg_decl
) = 1;
1190 TREE_PUBLIC (umsg_decl
) = 1;
1191 DECL_INLINE (umsg_decl
) = 1;
1192 DECL_ARTIFICIAL (umsg_decl
) = 1;
1194 if (flag_traditional
&& TAG_MSGSEND
[0] != '_')
1195 DECL_BUILT_IN_NONANSI (umsg_decl
) = 1;
1197 make_decl_rtl (umsg_decl
, NULL_PTR
, 1);
1198 pushdecl (umsg_decl
);
1201 umsg_decl
= builtin_function (TAG_MSGSEND
, temp_type
, NOT_BUILT_IN
, 0);
1203 /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */
1206 = build_function_type (id_type
,
1207 tree_cons (NULL_TREE
, super_p
,
1208 tree_cons (NULL_TREE
, selector_type
,
1211 umsg_super_decl
= builtin_function (TAG_MSGSENDSUPER
,
1212 temp_type
, NOT_BUILT_IN
, 0);
1214 /* id objc_getClass (const char *); */
1216 temp_type
= build_function_type (id_type
,
1217 tree_cons (NULL_TREE
,
1218 const_string_type_node
,
1219 tree_cons (NULL_TREE
, void_type_node
,
1223 = builtin_function (TAG_GETCLASS
, temp_type
, NOT_BUILT_IN
, 0);
1225 /* id objc_getMetaClass (const char *); */
1227 objc_get_meta_class_decl
1228 = builtin_function (TAG_GETMETACLASS
, temp_type
, NOT_BUILT_IN
, 0);
1230 /* static SEL _OBJC_SELECTOR_TABLE[]; */
1232 if (! flag_next_runtime
)
1234 if (flag_typed_selectors
)
1236 /* Suppress outputting debug symbols, because
1237 dbxout_init hasn'r been called yet. */
1238 enum debug_info_type save_write_symbols
= write_symbols
;
1239 write_symbols
= NO_DEBUG
;
1241 build_selector_template ();
1242 temp_type
= build_array_type (objc_selector_template
, NULL_TREE
);
1244 write_symbols
= save_write_symbols
;
1247 temp_type
= build_array_type (selector_type
, NULL_TREE
);
1249 layout_type (temp_type
);
1250 UOBJC_SELECTOR_TABLE_decl
1251 = create_builtin_decl (VAR_DECL
, temp_type
,
1252 "_OBJC_SELECTOR_TABLE");
1254 /* Avoid warning when not sending messages. */
1255 TREE_USED (UOBJC_SELECTOR_TABLE_decl
) = 1;
1258 generate_forward_declaration_to_string_table ();
1260 /* Forward declare constant_string_id and constant_string_type. */
1261 constant_string_id
= get_identifier (STRING_OBJECT_CLASS_NAME
);
1262 constant_string_type
= xref_tag (RECORD_TYPE
, constant_string_id
);
1265 /* Custom build_string which sets TREE_TYPE! */
1268 my_build_string (len
, str
)
1273 tree a_string
= build_string (len
, str
);
1275 /* Some code from combine_strings, which is local to c-parse.y. */
1276 if (TREE_TYPE (a_string
) == int_array_type_node
)
1279 TREE_TYPE (a_string
)
1280 = build_array_type (wide_flag
? integer_type_node
: char_type_node
,
1281 build_index_type (build_int_2 (len
- 1, 0)));
1283 TREE_CONSTANT (a_string
) = 1; /* Puts string in the readonly segment */
1284 TREE_STATIC (a_string
) = 1;
1289 /* Return a newly constructed OBJC_STRING_CST node whose value is
1290 the LEN characters at STR.
1291 The TREE_TYPE is not initialized. */
1294 build_objc_string (len
, str
)
1298 tree s
= build_string (len
, str
);
1300 TREE_SET_CODE (s
, OBJC_STRING_CST
);
1304 /* Given a chain of OBJC_STRING_CST's, build a static instance of
1305 NXConstanString which points at the concatenation of those strings.
1306 We place the string object in the __string_objects section of the
1307 __OBJC segment. The Objective-C runtime will initialize the isa
1308 pointers of the string objects to point at the NXConstandString class
1312 build_objc_string_object (strings
)
1315 tree string
, initlist
, constructor
;
1318 if (!doing_objc_thang
)
1321 if (lookup_interface (constant_string_id
) == NULL_TREE
)
1323 error ("Cannot find interface declaration for `%s'",
1324 IDENTIFIER_POINTER (constant_string_id
));
1325 return error_mark_node
;
1328 add_class_reference (constant_string_id
);
1330 /* Combine_strings will work for OBJC_STRING_CST's too. */
1331 string
= combine_strings (strings
);
1332 TREE_SET_CODE (string
, STRING_CST
);
1333 length
= TREE_STRING_LENGTH (string
) - 1;
1335 if (! flag_next_runtime
)
1337 push_obstacks_nochange ();
1338 end_temporary_allocation ();
1339 if (! TREE_PERMANENT (strings
))
1340 string
= my_build_string (length
+ 1,
1341 TREE_STRING_POINTER (string
));
1344 /* & ((NXConstantString) {0, string, length}) */
1346 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1348 = tree_cons (NULL_TREE
, copy_node (build_unary_op (ADDR_EXPR
, string
, 1)),
1350 initlist
= tree_cons (NULL_TREE
, build_int_2 (length
, 0), initlist
);
1351 constructor
= build_constructor (constant_string_type
, nreverse (initlist
));
1353 if (!flag_next_runtime
)
1356 = objc_add_static_instance (constructor
, constant_string_type
);
1360 return (build_unary_op (ADDR_EXPR
, constructor
, 1));
1363 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
1366 objc_add_static_instance (constructor
, class_decl
)
1367 tree constructor
, class_decl
;
1369 static int num_static_inst
;
1373 push_obstacks_nochange ();
1374 end_temporary_allocation ();
1376 /* Find the list of static instances for the CLASS_DECL. Create one if
1378 for (chain
= &objc_static_instances
;
1379 *chain
&& TREE_VALUE (*chain
) != class_decl
;
1380 chain
= &TREE_CHAIN (*chain
));
1383 *chain
= tree_cons (NULL_TREE
, class_decl
, NULL_TREE
);
1384 add_objc_string (TYPE_NAME (class_decl
), class_names
);
1387 sprintf (buf
, "_OBJC_INSTANCE_%d", num_static_inst
++);
1388 decl
= build_decl (VAR_DECL
, get_identifier (buf
), class_decl
);
1389 DECL_COMMON (decl
) = 1;
1390 TREE_STATIC (decl
) = 1;
1391 DECL_ARTIFICIAL (decl
) = 1;
1392 pushdecl_top_level (decl
);
1393 rest_of_decl_compilation (decl
, 0, 1, 0);
1395 /* Do this here so it gets output later instead of possibly
1396 inside something else we are writing. */
1397 DECL_INITIAL (decl
) = constructor
;
1399 /* Add the DECL to the head of this CLASS' list. */
1400 TREE_PURPOSE (*chain
) = tree_cons (NULL_TREE
, decl
, TREE_PURPOSE (*chain
));
1406 /* Build a static constant CONSTRUCTOR
1407 with type TYPE and elements ELTS. */
1410 build_constructor (type
, elts
)
1413 tree constructor
= build (CONSTRUCTOR
, type
, NULL_TREE
, elts
);
1415 TREE_CONSTANT (constructor
) = 1;
1416 TREE_STATIC (constructor
) = 1;
1417 TREE_READONLY (constructor
) = 1;
1422 /* Take care of defining and initializing _OBJC_SYMBOLS. */
1424 /* Predefine the following data type:
1432 void *defs[cls_def_cnt + cat_def_cnt];
1436 build_objc_symtab_template ()
1438 tree field_decl
, field_decl_chain
, index
;
1440 objc_symtab_template
1441 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SYMTAB
));
1443 /* long sel_ref_cnt; */
1445 field_decl
= create_builtin_decl (FIELD_DECL
,
1446 long_integer_type_node
,
1448 field_decl_chain
= field_decl
;
1452 field_decl
= create_builtin_decl (FIELD_DECL
,
1453 build_pointer_type (selector_type
),
1455 chainon (field_decl_chain
, field_decl
);
1457 /* short cls_def_cnt; */
1459 field_decl
= create_builtin_decl (FIELD_DECL
,
1460 short_integer_type_node
,
1462 chainon (field_decl_chain
, field_decl
);
1464 /* short cat_def_cnt; */
1466 field_decl
= create_builtin_decl (FIELD_DECL
,
1467 short_integer_type_node
,
1469 chainon (field_decl_chain
, field_decl
);
1471 /* void *defs[cls_def_cnt + cat_def_cnt]; */
1473 if (!flag_next_runtime
)
1474 index
= build_index_type (build_int_2 (imp_count
+ cat_count
, 0));
1476 index
= build_index_type (build_int_2 (imp_count
+ cat_count
- 1,
1477 imp_count
== 0 && cat_count
== 0
1479 field_decl
= create_builtin_decl (FIELD_DECL
,
1480 build_array_type (ptr_type_node
, index
),
1482 chainon (field_decl_chain
, field_decl
);
1484 finish_struct (objc_symtab_template
, field_decl_chain
, NULL_TREE
);
1487 /* Create the initial value for the `defs' field of _objc_symtab.
1488 This is a CONSTRUCTOR. */
1491 init_def_list (type
)
1494 tree expr
, initlist
= NULL_TREE
;
1495 struct imp_entry
*impent
;
1498 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1500 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
1502 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1503 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1508 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1510 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1512 expr
= build_unary_op (ADDR_EXPR
, impent
->class_decl
, 0);
1513 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1517 if (!flag_next_runtime
)
1519 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1522 if (static_instances_decl
)
1523 expr
= build_unary_op (ADDR_EXPR
, static_instances_decl
, 0);
1525 expr
= build_int_2 (0, 0);
1527 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1530 return build_constructor (type
, nreverse (initlist
));
1533 /* Construct the initial value for all of _objc_symtab. */
1536 init_objc_symtab (type
)
1541 /* sel_ref_cnt = { ..., 5, ... } */
1543 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
1545 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
1547 if (flag_next_runtime
|| ! sel_ref_chain
)
1548 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1550 initlist
= tree_cons (NULL_TREE
,
1551 build_unary_op (ADDR_EXPR
,
1552 UOBJC_SELECTOR_TABLE_decl
, 1),
1555 /* cls_def_cnt = { ..., 5, ... } */
1557 initlist
= tree_cons (NULL_TREE
, build_int_2 (imp_count
, 0), initlist
);
1559 /* cat_def_cnt = { ..., 5, ... } */
1561 initlist
= tree_cons (NULL_TREE
, build_int_2 (cat_count
, 0), initlist
);
1563 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
1565 if (imp_count
|| cat_count
|| static_instances_decl
)
1568 tree field
= TYPE_FIELDS (type
);
1569 field
= TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field
))));
1571 initlist
= tree_cons (NULL_TREE
, init_def_list (TREE_TYPE (field
)),
1575 return build_constructor (type
, nreverse (initlist
));
1578 /* Push forward-declarations of all the categories
1579 so that init_def_list can use them in a CONSTRUCTOR. */
1582 forward_declare_categories ()
1584 struct imp_entry
*impent
;
1585 tree sav
= implementation_context
;
1587 for (impent
= imp_list
; impent
; impent
= impent
->next
)
1589 if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
1591 /* Set an invisible arg to synth_id_with_class_suffix. */
1592 implementation_context
= impent
->imp_context
;
1594 = create_builtin_decl (VAR_DECL
, objc_category_template
,
1595 IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", implementation_context
)));
1598 implementation_context
= sav
;
1601 /* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab'
1602 and initialized appropriately. */
1605 generate_objc_symtab_decl ()
1609 if (!objc_category_template
)
1610 build_category_template ();
1612 /* forward declare categories */
1614 forward_declare_categories ();
1616 if (!objc_symtab_template
)
1617 build_objc_symtab_template ();
1619 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
1621 UOBJC_SYMBOLS_decl
= start_decl (get_identifier ("_OBJC_SYMBOLS"),
1622 tree_cons (NULL_TREE
,
1623 objc_symtab_template
, sc_spec
),
1625 NULL_TREE
, NULL_TREE
);
1627 TREE_USED (UOBJC_SYMBOLS_decl
) = 1;
1628 DECL_IGNORED_P (UOBJC_SYMBOLS_decl
) = 1;
1629 DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl
) = 1;
1630 finish_decl (UOBJC_SYMBOLS_decl
,
1631 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl
)),
1636 init_module_descriptor (type
)
1639 tree initlist
, expr
;
1641 /* version = { 1, ... } */
1643 expr
= build_int_2 (OBJC_VERSION
, 0);
1644 initlist
= build_tree_list (NULL_TREE
, expr
);
1646 /* size = { ..., sizeof (struct objc_module), ... } */
1648 expr
= size_in_bytes (objc_module_template
);
1649 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1651 /* name = { ..., "foo.m", ... } */
1653 expr
= add_objc_string (get_identifier (input_filename
), class_names
);
1654 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1656 /* symtab = { ..., _OBJC_SYMBOLS, ... } */
1658 if (UOBJC_SYMBOLS_decl
)
1659 expr
= build_unary_op (ADDR_EXPR
, UOBJC_SYMBOLS_decl
, 0);
1661 expr
= build_int_2 (0, 0);
1662 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1664 return build_constructor (type
, nreverse (initlist
));
1667 /* Write out the data structures to describe Objective C classes defined.
1668 If appropriate, compile and output a setup function to initialize them.
1669 Return a string which is the name of a function to call to initialize
1670 the Objective C data structures for this file (and perhaps for other files
1673 struct objc_module { ... } _OBJC_MODULE = { ... }; */
1676 build_module_descriptor ()
1678 tree decl_specs
, field_decl
, field_decl_chain
;
1680 objc_module_template
1681 = start_struct (RECORD_TYPE
, get_identifier (UTAG_MODULE
));
1685 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1686 field_decl
= get_identifier ("version");
1688 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1689 field_decl_chain
= field_decl
;
1693 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
1694 field_decl
= get_identifier ("size");
1696 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1697 chainon (field_decl_chain
, field_decl
);
1701 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
1702 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
1704 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1705 chainon (field_decl_chain
, field_decl
);
1707 /* struct objc_symtab *symtab; */
1709 decl_specs
= get_identifier (UTAG_SYMTAB
);
1710 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
1711 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("symtab"));
1713 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
1714 chainon (field_decl_chain
, field_decl
);
1716 finish_struct (objc_module_template
, field_decl_chain
, NULL_TREE
);
1718 /* Create an instance of "objc_module". */
1720 decl_specs
= tree_cons (NULL_TREE
, objc_module_template
,
1721 build_tree_list (NULL_TREE
,
1722 ridpointers
[(int) RID_STATIC
]));
1724 UOBJC_MODULES_decl
= start_decl (get_identifier ("_OBJC_MODULES"),
1725 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
1727 DECL_ARTIFICIAL (UOBJC_MODULES_decl
) = 1;
1728 DECL_IGNORED_P (UOBJC_MODULES_decl
) = 1;
1729 finish_decl (UOBJC_MODULES_decl
,
1730 init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl
)),
1733 /* Mark the decl to avoid "defined but not used" warning. */
1734 DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl
) = 1;
1736 /* Generate a constructor call for the module descriptor.
1737 This code was generated by reading the grammar rules
1738 of c-parse.in; Therefore, it may not be the most efficient
1739 way of generating the requisite code. */
1741 if (flag_next_runtime
)
1745 tree parms
, function_decl
, decelerator
, void_list_node
;
1747 tree init_function_name
= get_file_function_name ('I');
1749 /* Declare void __objc_execClass (void *); */
1751 void_list_node
= build_tree_list (NULL_TREE
, void_type_node
);
1753 = build_function_type (void_type_node
,
1754 tree_cons (NULL_TREE
, ptr_type_node
,
1756 function_decl
= build_decl (FUNCTION_DECL
,
1757 get_identifier (TAG_EXECCLASS
),
1759 DECL_EXTERNAL (function_decl
) = 1;
1760 DECL_ARTIFICIAL (function_decl
) = 1;
1761 TREE_PUBLIC (function_decl
) = 1;
1763 pushdecl (function_decl
);
1764 rest_of_decl_compilation (function_decl
, 0, 0, 0);
1767 = build_tree_list (NULL_TREE
,
1768 build_unary_op (ADDR_EXPR
, UOBJC_MODULES_decl
, 0));
1769 decelerator
= build_function_call (function_decl
, parms
);
1771 /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */
1773 start_function (void_list_node
,
1774 build_parse_node (CALL_EXPR
, init_function_name
,
1775 /* This has the format of the output
1776 of get_parm_info. */
1777 tree_cons (NULL_TREE
, NULL_TREE
,
1780 NULL_TREE
, NULL_TREE
, 0);
1781 #if 0 /* This should be turned back on later
1782 for the systems where collect is not needed. */
1783 /* Make these functions nonglobal
1784 so each file can use the same name. */
1785 TREE_PUBLIC (current_function_decl
) = 0;
1787 TREE_USED (current_function_decl
) = 1;
1788 store_parm_decls ();
1790 assemble_external (function_decl
);
1791 c_expand_expr_stmt (decelerator
);
1793 TREE_PUBLIC (current_function_decl
) = 1;
1795 function_decl
= current_function_decl
;
1796 finish_function (0);
1798 /* Return the name of the constructor function. */
1799 return XSTR (XEXP (DECL_RTL (function_decl
), 0), 0);
1803 /* extern const char _OBJC_STRINGS[]; */
1806 generate_forward_declaration_to_string_table ()
1808 tree sc_spec
, decl_specs
, expr_decl
;
1810 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_EXTERN
], NULL_TREE
);
1811 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1814 = build_nt (ARRAY_REF
, get_identifier ("_OBJC_STRINGS"), NULL_TREE
);
1816 UOBJC_STRINGS_decl
= define_decl (expr_decl
, decl_specs
);
1819 /* Return the DECL of the string IDENT in the SECTION. */
1822 get_objc_string_decl (ident
, section
)
1824 enum string_section section
;
1828 if (section
== class_names
)
1829 chain
= class_names_chain
;
1830 else if (section
== meth_var_names
)
1831 chain
= meth_var_names_chain
;
1832 else if (section
== meth_var_types
)
1833 chain
= meth_var_types_chain
;
1835 for (; chain
!= 0; chain
= TREE_VALUE (chain
))
1836 if (TREE_VALUE (chain
) == ident
)
1837 return (TREE_PURPOSE (chain
));
1843 /* Output references to all statically allocated objects. Return the DECL
1844 for the array built. */
1847 generate_static_references ()
1849 tree decls
= NULL_TREE
, ident
, decl_spec
, expr_decl
, expr
= NULL_TREE
;
1850 tree class_name
, class, decl
, initlist
;
1851 tree cl_chain
, in_chain
, type
;
1852 int num_inst
, num_class
;
1855 if (flag_next_runtime
)
1858 for (cl_chain
= objc_static_instances
, num_class
= 0;
1859 cl_chain
; cl_chain
= TREE_CHAIN (cl_chain
), num_class
++)
1861 for (num_inst
= 0, in_chain
= TREE_PURPOSE (cl_chain
);
1862 in_chain
; num_inst
++, in_chain
= TREE_CHAIN (in_chain
));
1864 sprintf (buf
, "_OBJC_STATIC_INSTANCES_%d", num_class
);
1865 ident
= get_identifier (buf
);
1867 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1868 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1869 build_tree_list (NULL_TREE
,
1870 ridpointers
[(int) RID_STATIC
]));
1871 decl
= start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
, NULL_TREE
);
1872 DECL_CONTEXT (decl
) = 0;
1873 DECL_ARTIFICIAL (decl
) = 1;
1875 /* Output {class_name, ...}. */
1876 class = TREE_VALUE (cl_chain
);
1877 class_name
= get_objc_string_decl (TYPE_NAME (class), class_names
);
1878 initlist
= build_tree_list (NULL_TREE
,
1879 build_unary_op (ADDR_EXPR
, class_name
, 1));
1881 /* Output {..., instance, ...}. */
1882 for (in_chain
= TREE_PURPOSE (cl_chain
);
1883 in_chain
; in_chain
= TREE_CHAIN (in_chain
))
1885 expr
= build_unary_op (ADDR_EXPR
, TREE_VALUE (in_chain
), 1);
1886 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
1889 /* Output {..., NULL}. */
1890 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
1892 expr
= build_constructor (TREE_TYPE (decl
), nreverse (initlist
));
1893 finish_decl (decl
, expr
, NULL_TREE
);
1894 TREE_USED (decl
) = 1;
1896 type
= build_array_type (build_pointer_type (void_type_node
), 0);
1897 decl
= build_decl (VAR_DECL
, ident
, type
);
1898 make_decl_rtl (decl
, 0, 1);
1899 TREE_USED (decl
) = 1;
1901 = tree_cons (NULL_TREE
, build_unary_op (ADDR_EXPR
, decl
, 1), decls
);
1904 decls
= tree_cons (NULL_TREE
, build_int_2 (0, 0), decls
);
1905 ident
= get_identifier ("_OBJC_STATIC_INSTANCES");
1906 expr_decl
= build_nt (ARRAY_REF
, ident
, NULL_TREE
);
1907 decl_spec
= tree_cons (NULL_TREE
, build_pointer_type (void_type_node
),
1908 build_tree_list (NULL_TREE
,
1909 ridpointers
[(int) RID_STATIC
]));
1910 static_instances_decl
1911 = start_decl (expr_decl
, decl_spec
, 1, NULL_TREE
, NULL_TREE
);
1912 TREE_USED (static_instances_decl
) = 1;
1913 DECL_CONTEXT (static_instances_decl
) = 0;
1914 DECL_ARTIFICIAL (static_instances_decl
) = 1;
1915 end_temporary_allocation ();
1916 expr
= build_constructor (TREE_TYPE (static_instances_decl
),
1918 finish_decl (static_instances_decl
, expr
, NULL_TREE
);
1921 /* Output all strings. */
1926 tree sc_spec
, decl_specs
, expr_decl
;
1927 tree chain
, string_expr
;
1930 for (chain
= class_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1932 string
= TREE_VALUE (chain
);
1933 decl
= TREE_PURPOSE (chain
);
1935 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1936 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1937 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1938 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
1939 end_temporary_allocation ();
1940 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1941 IDENTIFIER_POINTER (string
));
1942 finish_decl (decl
, string_expr
, NULL_TREE
);
1945 for (chain
= meth_var_names_chain
; chain
; chain
= TREE_CHAIN (chain
))
1947 string
= TREE_VALUE (chain
);
1948 decl
= TREE_PURPOSE (chain
);
1950 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1951 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1952 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1953 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
1954 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1955 IDENTIFIER_POINTER (string
));
1956 finish_decl (decl
, string_expr
, NULL_TREE
);
1959 for (chain
= meth_var_types_chain
; chain
; chain
= TREE_CHAIN (chain
))
1961 string
= TREE_VALUE (chain
);
1962 decl
= TREE_PURPOSE (chain
);
1964 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
1965 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], sc_spec
);
1966 expr_decl
= build_nt (ARRAY_REF
, DECL_NAME (decl
), NULL_TREE
);
1967 decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
1968 string_expr
= my_build_string (IDENTIFIER_LENGTH (string
) + 1,
1969 IDENTIFIER_POINTER (string
));
1970 finish_decl (decl
, string_expr
, NULL_TREE
);
1975 build_selector_reference_decl (name
)
1982 sprintf (buf
, "_OBJC_SELECTOR_REFERENCES_%d", idx
++);
1984 push_obstacks_nochange ();
1985 end_temporary_allocation ();
1987 ident
= get_identifier (buf
);
1989 decl
= build_decl (VAR_DECL
, ident
, selector_type
);
1990 DECL_EXTERNAL (decl
) = 1;
1991 TREE_PUBLIC (decl
) = 1;
1992 TREE_USED (decl
) = 1;
1993 TREE_READONLY (decl
) = 1;
1994 DECL_ARTIFICIAL (decl
) = 1;
1995 DECL_CONTEXT (decl
) = 0;
1997 make_decl_rtl (decl
, 0, 1);
1998 pushdecl_top_level (decl
);
2005 /* Just a handy wrapper for add_objc_string. */
2008 build_selector (ident
)
2011 tree expr
= add_objc_string (ident
, meth_var_names
);
2012 if (flag_typed_selectors
)
2015 return build_c_cast (selector_type
, expr
); /* cast! */
2018 /* Synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>]
2019 The cast stops the compiler from issuing the following message:
2020 grok.m: warning: initialization of non-const * pointer from const *
2021 grok.m: warning: initialization between incompatible pointer types. */
2024 build_msg_pool_reference (offset
)
2027 tree expr
= build_int_2 (offset
, 0);
2030 expr
= build_array_ref (UOBJC_STRINGS_decl
, expr
);
2031 expr
= build_unary_op (ADDR_EXPR
, expr
, 0);
2033 cast
= build_tree_list (build_tree_list (NULL_TREE
,
2034 ridpointers
[(int) RID_CHAR
]),
2035 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
2036 TREE_TYPE (expr
) = groktypename (cast
);
2041 init_selector (offset
)
2044 tree expr
= build_msg_pool_reference (offset
);
2045 TREE_TYPE (expr
) = selector_type
;
2050 build_selector_translation_table ()
2052 tree sc_spec
, decl_specs
;
2053 tree chain
, initlist
= NULL_TREE
;
2055 tree decl
, var_decl
, name
;
2057 /* The corresponding pop_obstacks is in finish_decl,
2058 called at the end of this function. */
2059 if (! flag_next_runtime
)
2060 push_obstacks_nochange ();
2062 for (chain
= sel_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
2066 expr
= build_selector (TREE_VALUE (chain
));
2068 if (flag_next_runtime
)
2070 name
= DECL_NAME (TREE_PURPOSE (chain
));
2072 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
2074 /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */
2075 decl_specs
= tree_cons (NULL_TREE
, selector_type
, sc_spec
);
2079 /* The `decl' that is returned from start_decl is the one that we
2080 forward declared in `build_selector_reference' */
2081 decl
= start_decl (var_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2084 /* add one for the '\0' character */
2085 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (chain
)) + 1;
2087 if (flag_next_runtime
)
2088 finish_decl (decl
, expr
, NULL_TREE
);
2091 if (flag_typed_selectors
)
2093 tree eltlist
= NULL_TREE
;
2094 tree encoding
= get_proto_encoding (TREE_PURPOSE (chain
));
2095 eltlist
= tree_cons (NULL_TREE
, expr
, NULL_TREE
);
2096 eltlist
= tree_cons (NULL_TREE
, encoding
, eltlist
);
2097 expr
= build_constructor (objc_selector_template
,
2098 nreverse (eltlist
));
2100 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
2105 if (! flag_next_runtime
)
2107 /* Cause the variable and its initial value to be actually output. */
2108 DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl
) = 0;
2109 TREE_STATIC (UOBJC_SELECTOR_TABLE_decl
) = 1;
2110 /* NULL terminate the list and fix the decl for output. */
2111 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
2112 DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl
) = (tree
) 1;
2113 initlist
= build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl
),
2114 nreverse (initlist
));
2115 finish_decl (UOBJC_SELECTOR_TABLE_decl
, initlist
, NULL_TREE
);
2116 current_function_decl
= NULL_TREE
;
2121 get_proto_encoding (proto
)
2129 if (! METHOD_ENCODING (proto
))
2131 tmp_decl
= build_tmp_function_decl ();
2132 hack_method_prototype (proto
, tmp_decl
);
2133 encoding
= encode_method_prototype (proto
, tmp_decl
);
2134 METHOD_ENCODING (proto
) = encoding
;
2137 encoding
= METHOD_ENCODING (proto
);
2139 return add_objc_string (encoding
, meth_var_types
);
2142 return build_int_2 (0, 0);
2145 /* sel_ref_chain is a list whose "value" fields will be instances of
2146 identifier_node that represent the selector. */
2149 build_typed_selector_reference (ident
, proto
)
2152 tree
*chain
= &sel_ref_chain
;
2158 if (TREE_PURPOSE (*chain
) == ident
&& TREE_VALUE (*chain
) == proto
)
2159 goto return_at_index
;
2162 chain
= &TREE_CHAIN (*chain
);
2165 *chain
= perm_tree_cons (proto
, ident
, NULL_TREE
);
2168 expr
= build_unary_op (ADDR_EXPR
,
2169 build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2170 build_int_2 (index
, 0)),
2172 return build_c_cast (selector_type
, expr
);
2176 build_selector_reference (ident
)
2179 tree
*chain
= &sel_ref_chain
;
2185 if (TREE_VALUE (*chain
) == ident
)
2186 return (flag_next_runtime
2187 ? TREE_PURPOSE (*chain
)
2188 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2189 build_int_2 (index
, 0)));
2192 chain
= &TREE_CHAIN (*chain
);
2195 expr
= build_selector_reference_decl (ident
);
2197 *chain
= perm_tree_cons (expr
, ident
, NULL_TREE
);
2199 return (flag_next_runtime
2201 : build_array_ref (UOBJC_SELECTOR_TABLE_decl
,
2202 build_int_2 (index
, 0)));
2206 build_class_reference_decl (name
)
2213 sprintf (buf
, "_OBJC_CLASS_REFERENCES_%d", idx
++);
2215 push_obstacks_nochange ();
2216 end_temporary_allocation ();
2218 ident
= get_identifier (buf
);
2220 decl
= build_decl (VAR_DECL
, ident
, objc_class_type
);
2221 DECL_EXTERNAL (decl
) = 1;
2222 TREE_PUBLIC (decl
) = 1;
2223 TREE_USED (decl
) = 1;
2224 TREE_READONLY (decl
) = 1;
2225 DECL_CONTEXT (decl
) = 0;
2226 DECL_ARTIFICIAL (decl
) = 1;
2228 make_decl_rtl (decl
, 0, 1);
2229 pushdecl_top_level (decl
);
2236 /* Create a class reference, but don't create a variable to reference
2240 add_class_reference (ident
)
2245 if ((chain
= cls_ref_chain
))
2250 if (ident
== TREE_VALUE (chain
))
2254 chain
= TREE_CHAIN (chain
);
2258 /* Append to the end of the list */
2259 TREE_CHAIN (tail
) = perm_tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2262 cls_ref_chain
= perm_tree_cons (NULL_TREE
, ident
, NULL_TREE
);
2265 /* Get a class reference, creating it if necessary. Also create the
2266 reference variable. */
2269 get_class_reference (ident
)
2272 if (flag_next_runtime
)
2277 for (chain
= &cls_ref_chain
; *chain
; chain
= &TREE_CHAIN (*chain
))
2278 if (TREE_VALUE (*chain
) == ident
)
2280 if (! TREE_PURPOSE (*chain
))
2281 TREE_PURPOSE (*chain
) = build_class_reference_decl (ident
);
2283 return TREE_PURPOSE (*chain
);
2286 decl
= build_class_reference_decl (ident
);
2287 *chain
= perm_tree_cons (decl
, ident
, NULL_TREE
);
2294 add_class_reference (ident
);
2296 params
= build_tree_list (NULL_TREE
,
2297 my_build_string (IDENTIFIER_LENGTH (ident
) + 1,
2298 IDENTIFIER_POINTER (ident
)));
2300 assemble_external (objc_get_class_decl
);
2301 return build_function_call (objc_get_class_decl
, params
);
2305 /* SEL_REFDEF_CHAIN is a list whose "value" fields will be instances
2306 of identifier_node that represent the selector. It returns the
2307 offset of the selector from the beginning of the _OBJC_STRINGS
2308 pool. This offset is typically used by init_selector during code
2311 For each string section we have a chain which maps identifier nodes
2312 to decls for the strings. */
2315 add_objc_string (ident
, section
)
2317 enum string_section section
;
2321 if (section
== class_names
)
2322 chain
= &class_names_chain
;
2323 else if (section
== meth_var_names
)
2324 chain
= &meth_var_names_chain
;
2325 else if (section
== meth_var_types
)
2326 chain
= &meth_var_types_chain
;
2330 if (TREE_VALUE (*chain
) == ident
)
2331 return build_unary_op (ADDR_EXPR
, TREE_PURPOSE (*chain
), 1);
2333 chain
= &TREE_CHAIN (*chain
);
2336 decl
= build_objc_string_decl (ident
, section
);
2338 *chain
= perm_tree_cons (decl
, ident
, NULL_TREE
);
2340 return build_unary_op (ADDR_EXPR
, decl
, 1);
2344 build_objc_string_decl (name
, section
)
2346 enum string_section section
;
2350 static int class_names_idx
= 0;
2351 static int meth_var_names_idx
= 0;
2352 static int meth_var_types_idx
= 0;
2354 if (section
== class_names
)
2355 sprintf (buf
, "_OBJC_CLASS_NAME_%d", class_names_idx
++);
2356 else if (section
== meth_var_names
)
2357 sprintf (buf
, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx
++);
2358 else if (section
== meth_var_types
)
2359 sprintf (buf
, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx
++);
2361 push_obstacks_nochange ();
2362 end_temporary_allocation ();
2363 ident
= get_identifier (buf
);
2365 decl
= build_decl (VAR_DECL
, ident
, build_array_type (char_type_node
, 0));
2366 DECL_EXTERNAL (decl
) = 1;
2367 TREE_PUBLIC (decl
) = 1;
2368 TREE_USED (decl
) = 1;
2369 TREE_READONLY (decl
) = 1;
2370 TREE_CONSTANT (decl
) = 1;
2371 DECL_CONTEXT (decl
) = 0;
2372 DECL_ARTIFICIAL (decl
) = 1;
2374 make_decl_rtl (decl
, 0, 1);
2375 pushdecl_top_level (decl
);
2384 objc_declare_alias (alias_ident
, class_ident
)
2388 if (!doing_objc_thang
)
2391 if (is_class_name (class_ident
) != class_ident
)
2392 warning ("Cannot find class `%s'", IDENTIFIER_POINTER (class_ident
));
2393 else if (is_class_name (alias_ident
))
2394 warning ("Class `%s' already exists", IDENTIFIER_POINTER (alias_ident
));
2396 alias_chain
= tree_cons (class_ident
, alias_ident
, alias_chain
);
2400 objc_declare_class (ident_list
)
2405 if (!doing_objc_thang
)
2408 for (list
= ident_list
; list
; list
= TREE_CHAIN (list
))
2410 tree ident
= TREE_VALUE (list
);
2413 if ((decl
= lookup_name (ident
)))
2415 error ("`%s' redeclared as different kind of symbol",
2416 IDENTIFIER_POINTER (ident
));
2417 error_with_decl (decl
, "previous declaration of `%s'");
2420 if (! is_class_name (ident
))
2422 tree record
= xref_tag (RECORD_TYPE
, ident
);
2423 TREE_STATIC_TEMPLATE (record
) = 1;
2424 class_chain
= tree_cons (NULL_TREE
, ident
, class_chain
);
2430 is_class_name (ident
)
2435 if (lookup_interface (ident
))
2438 for (chain
= class_chain
; chain
; chain
= TREE_CHAIN (chain
))
2440 if (ident
== TREE_VALUE (chain
))
2444 for (chain
= alias_chain
; chain
; chain
= TREE_CHAIN (chain
))
2446 if (ident
== TREE_VALUE (chain
))
2447 return TREE_PURPOSE (chain
);
2454 lookup_interface (ident
)
2459 for (chain
= interface_chain
; chain
; chain
= TREE_CHAIN (chain
))
2461 if (ident
== CLASS_NAME (chain
))
2468 objc_copy_list (list
, head
)
2472 tree newlist
= NULL_TREE
, tail
= NULL_TREE
;
2476 tail
= copy_node (list
);
2478 /* The following statement fixes a bug when inheriting instance
2479 variables that are declared to be bitfields. finish_struct
2480 expects to find the width of the bitfield in DECL_INITIAL,
2481 which it nulls out after processing the decl of the super
2482 class...rather than change the way finish_struct works (which
2483 is risky), I create the situation it expects...s.naroff
2486 if (DECL_BIT_FIELD (tail
) && DECL_INITIAL (tail
) == 0)
2487 DECL_INITIAL (tail
) = build_int_2 (DECL_FIELD_SIZE (tail
), 0);
2489 newlist
= chainon (newlist
, tail
);
2490 list
= TREE_CHAIN (list
);
2497 /* Used by: build_private_template, get_class_ivars, and
2498 continue_class. COPY is 1 when called from @defs. In this case
2499 copy all fields. Otherwise don't copy leaf ivars since we rely on
2500 them being side-effected exactly once by finish_struct. */
2503 build_ivar_chain (interface
, copy
)
2507 tree my_name
, super_name
, ivar_chain
;
2509 my_name
= CLASS_NAME (interface
);
2510 super_name
= CLASS_SUPER_NAME (interface
);
2512 /* Possibly copy leaf ivars. */
2514 objc_copy_list (CLASS_IVARS (interface
), &ivar_chain
);
2516 ivar_chain
= CLASS_IVARS (interface
);
2521 tree super_interface
= lookup_interface (super_name
);
2523 if (!super_interface
)
2525 /* fatal did not work with 2 args...should fix */
2526 error ("Cannot find interface declaration for `%s', superclass of `%s'",
2527 IDENTIFIER_POINTER (super_name
),
2528 IDENTIFIER_POINTER (my_name
));
2529 exit (FATAL_EXIT_CODE
);
2532 if (super_interface
== interface
)
2534 fatal ("Circular inheritance in interface declaration for `%s'",
2535 IDENTIFIER_POINTER (super_name
));
2538 interface
= super_interface
;
2539 my_name
= CLASS_NAME (interface
);
2540 super_name
= CLASS_SUPER_NAME (interface
);
2542 op1
= CLASS_IVARS (interface
);
2545 tree head
, tail
= objc_copy_list (op1
, &head
);
2547 /* Prepend super class ivars...make a copy of the list, we
2548 do not want to alter the original. */
2549 TREE_CHAIN (tail
) = ivar_chain
;
2556 /* struct <classname> {
2557 struct objc_class *isa;
2562 build_private_template (class)
2567 if (CLASS_STATIC_TEMPLATE (class))
2569 uprivate_record
= CLASS_STATIC_TEMPLATE (class);
2570 ivar_context
= TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class));
2574 uprivate_record
= start_struct (RECORD_TYPE
, CLASS_NAME (class));
2576 ivar_context
= build_ivar_chain (class, 0);
2578 finish_struct (uprivate_record
, ivar_context
, NULL_TREE
);
2580 CLASS_STATIC_TEMPLATE (class) = uprivate_record
;
2582 /* mark this record as class template - for class type checking */
2583 TREE_STATIC_TEMPLATE (uprivate_record
) = 1;
2587 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
2589 build1 (INDIRECT_REF
, NULL_TREE
,
2592 return ivar_context
;
2595 /* Begin code generation for protocols... */
2597 /* struct objc_protocol {
2598 char *protocol_name;
2599 struct objc_protocol **protocol_list;
2600 struct objc_method_desc *instance_methods;
2601 struct objc_method_desc *class_methods;
2605 build_protocol_template ()
2607 tree decl_specs
, field_decl
, field_decl_chain
;
2610 template = start_struct (RECORD_TYPE
, get_identifier (UTAG_PROTOCOL
));
2612 /* struct objc_class *isa; */
2614 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2615 get_identifier (UTAG_CLASS
)));
2616 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
2618 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2619 field_decl_chain
= field_decl
;
2621 /* char *protocol_name; */
2623 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
2625 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_name"));
2627 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2628 chainon (field_decl_chain
, field_decl
);
2630 /* struct objc_protocol **protocol_list; */
2632 decl_specs
= build_tree_list (NULL_TREE
, template);
2634 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
2635 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
2637 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2638 chainon (field_decl_chain
, field_decl
);
2640 /* struct objc_method_list *instance_methods; */
2643 = build_tree_list (NULL_TREE
,
2644 xref_tag (RECORD_TYPE
,
2645 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2647 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
2649 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2650 chainon (field_decl_chain
, field_decl
);
2652 /* struct objc_method_list *class_methods; */
2655 = build_tree_list (NULL_TREE
,
2656 xref_tag (RECORD_TYPE
,
2657 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
2659 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
2661 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2662 chainon (field_decl_chain
, field_decl
);
2664 return finish_struct (template, field_decl_chain
, NULL_TREE
);
2668 build_descriptor_table_initializer (type
, entries
)
2672 tree initlist
= NULL_TREE
;
2676 tree eltlist
= NULL_TREE
;
2679 = tree_cons (NULL_TREE
,
2680 build_selector (METHOD_SEL_NAME (entries
)), NULL_TREE
);
2682 = tree_cons (NULL_TREE
,
2683 add_objc_string (METHOD_ENCODING (entries
),
2688 = tree_cons (NULL_TREE
,
2689 build_constructor (type
, nreverse (eltlist
)), initlist
);
2691 entries
= TREE_CHAIN (entries
);
2695 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
2698 /* struct objc_method_prototype_list {
2700 struct objc_method_prototype {
2707 build_method_prototype_list_template (list_type
, size
)
2711 tree objc_ivar_list_record
;
2712 tree decl_specs
, field_decl
, field_decl_chain
;
2714 /* Generate an unnamed struct definition. */
2716 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
2718 /* int method_count; */
2720 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
2721 field_decl
= get_identifier ("method_count");
2724 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2725 field_decl_chain
= field_decl
;
2727 /* struct objc_method method_list[]; */
2729 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
2730 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
2731 build_int_2 (size
, 0));
2734 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2735 chainon (field_decl_chain
, field_decl
);
2737 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
2739 return objc_ivar_list_record
;
2743 build_method_prototype_template ()
2746 tree decl_specs
, field_decl
, field_decl_chain
;
2749 = start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD_PROTOTYPE
));
2751 #ifdef OBJC_INT_SELECTORS
2752 /* unsigned int _cmd; */
2754 = tree_cons (NULL_TREE
, ridpointers
[(int) RID_UNSIGNED
], NULL_TREE
);
2755 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_INT
], decl_specs
);
2756 field_decl
= get_identifier ("_cmd");
2757 #else /* OBJC_INT_SELECTORS */
2758 /* struct objc_selector *_cmd; */
2759 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
2760 get_identifier (TAG_SELECTOR
)), NULL_TREE
);
2761 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
2762 #endif /* OBJC_INT_SELECTORS */
2765 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2766 field_decl_chain
= field_decl
;
2768 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
2770 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_types"));
2772 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
2773 chainon (field_decl_chain
, field_decl
);
2775 finish_struct (proto_record
, field_decl_chain
, NULL_TREE
);
2777 return proto_record
;
2780 /* True if last call to forwarding_offset yielded a register offset. */
2781 static int offset_is_register
;
2784 forwarding_offset (parm
)
2787 int offset_in_bytes
;
2789 if (GET_CODE (DECL_INCOMING_RTL (parm
)) == MEM
)
2791 rtx addr
= XEXP (DECL_INCOMING_RTL (parm
), 0);
2793 /* ??? Here we assume that the parm address is indexed
2794 off the frame pointer or arg pointer.
2795 If that is not true, we produce meaningless results,
2796 but do not crash. */
2797 if (GET_CODE (addr
) == PLUS
2798 && GET_CODE (XEXP (addr
, 1)) == CONST_INT
)
2799 offset_in_bytes
= INTVAL (XEXP (addr
, 1));
2801 offset_in_bytes
= 0;
2803 offset_in_bytes
+= OBJC_FORWARDING_STACK_OFFSET
;
2804 offset_is_register
= 0;
2806 else if (GET_CODE (DECL_INCOMING_RTL (parm
)) == REG
)
2808 int regno
= REGNO (DECL_INCOMING_RTL (parm
));
2809 offset_in_bytes
= apply_args_register_offset (regno
);
2810 offset_is_register
= 1;
2815 /* This is the case where the parm is passed as an int or double
2816 and it is converted to a char, short or float and stored back
2817 in the parmlist. In this case, describe the parm
2818 with the variable's declared type, and adjust the address
2819 if the least significant bytes (which we are using) are not
2821 if (BYTES_BIG_ENDIAN
&& TREE_TYPE (parm
) != DECL_ARG_TYPE (parm
))
2822 offset_in_bytes
+= (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm
)))
2823 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm
))));
2825 return offset_in_bytes
;
2829 encode_method_prototype (method_decl
, func_decl
)
2836 int max_parm_end
= 0;
2840 /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */
2841 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl
)));
2844 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
2845 obstack_object_size (&util_obstack
),
2846 OBJC_ENCODE_INLINE_DEFS
);
2849 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
2850 parms
= TREE_CHAIN (parms
))
2852 int parm_end
= (forwarding_offset (parms
)
2853 + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms
)))
2856 if (!offset_is_register
&& max_parm_end
< parm_end
)
2857 max_parm_end
= parm_end
;
2860 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
2862 sprintf (buf
, "%d", stack_size
);
2863 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2865 user_args
= METHOD_SEL_ARGS (method_decl
);
2867 /* Argument types. */
2868 for (parms
= DECL_ARGUMENTS (func_decl
), i
= 0; parms
;
2869 parms
= TREE_CHAIN (parms
), i
++)
2871 /* Process argument qualifiers for user supplied arguments. */
2874 encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args
)));
2875 user_args
= TREE_CHAIN (user_args
);
2879 encode_type (TREE_TYPE (parms
),
2880 obstack_object_size (&util_obstack
),
2881 OBJC_ENCODE_INLINE_DEFS
);
2883 /* Compute offset. */
2884 sprintf (buf
, "%d", forwarding_offset (parms
));
2886 /* Indicate register. */
2887 if (offset_is_register
)
2888 obstack_1grow (&util_obstack
, '+');
2890 obstack_grow (&util_obstack
, buf
, strlen (buf
));
2893 obstack_1grow (&util_obstack
, '\0');
2894 result
= get_identifier (obstack_finish (&util_obstack
));
2895 obstack_free (&util_obstack
, util_firstobj
);
2900 generate_descriptor_table (type
, name
, size
, list
, proto
)
2907 tree sc_spec
, decl_specs
, decl
, initlist
;
2909 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
2910 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
2912 decl
= start_decl (synth_id_with_class_suffix (name
, proto
),
2913 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
2915 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
2916 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
2918 finish_decl (decl
, build_constructor (type
, nreverse (initlist
)),
2925 generate_method_descriptors (protocol
) /* generate_dispatch_tables */
2928 static tree objc_method_prototype_template
;
2929 tree initlist
, chain
, method_list_template
;
2930 tree cast
, variable_length_type
;
2933 if (!objc_method_prototype_template
)
2934 objc_method_prototype_template
= build_method_prototype_template ();
2936 cast
= build_tree_list (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
2937 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
))),
2939 variable_length_type
= groktypename (cast
);
2941 chain
= PROTOCOL_CLS_METHODS (protocol
);
2944 size
= list_length (chain
);
2946 method_list_template
2947 = build_method_prototype_list_template (objc_method_prototype_template
,
2951 = build_descriptor_table_initializer (objc_method_prototype_template
,
2954 UOBJC_CLASS_METHODS_decl
2955 = generate_descriptor_table (method_list_template
,
2956 "_OBJC_PROTOCOL_CLASS_METHODS",
2957 size
, initlist
, protocol
);
2958 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
2961 UOBJC_CLASS_METHODS_decl
= 0;
2963 chain
= PROTOCOL_NST_METHODS (protocol
);
2966 size
= list_length (chain
);
2968 method_list_template
2969 = build_method_prototype_list_template (objc_method_prototype_template
,
2972 = build_descriptor_table_initializer (objc_method_prototype_template
,
2975 UOBJC_INSTANCE_METHODS_decl
2976 = generate_descriptor_table (method_list_template
,
2977 "_OBJC_PROTOCOL_INSTANCE_METHODS",
2978 size
, initlist
, protocol
);
2979 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
2982 UOBJC_INSTANCE_METHODS_decl
= 0;
2986 build_tmp_function_decl ()
2988 tree decl_specs
, expr_decl
, parms
;
2992 /* struct objc_object *objc_xxx (id, SEL, ...); */
2994 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
2995 push_parm_decl (build_tree_list
2996 (build_tree_list (decl_specs
,
2997 build1 (INDIRECT_REF
, NULL_TREE
,
2999 build_tree_list (NULL_TREE
, NULL_TREE
)));
3001 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3002 get_identifier (TAG_SELECTOR
)));
3003 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
);
3005 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, expr_decl
),
3006 build_tree_list (NULL_TREE
, NULL_TREE
)));
3007 parms
= get_parm_info (0);
3010 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3011 sprintf (buffer
, "__objc_tmp_%x", xxx
++);
3012 expr_decl
= build_nt (CALL_EXPR
, get_identifier (buffer
), parms
, NULL_TREE
);
3013 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
3015 return define_decl (expr_decl
, decl_specs
);
3019 hack_method_prototype (nst_methods
, tmp_decl
)
3026 /* Hack to avoid problem with static typing of self arg. */
3027 TREE_SET_CODE (nst_methods
, CLASS_METHOD_DECL
);
3028 start_method_def (nst_methods
);
3029 TREE_SET_CODE (nst_methods
, INSTANCE_METHOD_DECL
);
3031 if (METHOD_ADD_ARGS (nst_methods
) == (tree
) 1)
3032 parms
= get_parm_info (0); /* we have a `, ...' */
3034 parms
= get_parm_info (1); /* place a `void_at_end' */
3036 poplevel (0, 0, 0); /* Must be called BEFORE start_function. */
3038 /* Usually called from store_parm_decls -> init_function_start. */
3040 DECL_ARGUMENTS (tmp_decl
) = TREE_PURPOSE (parms
);
3041 current_function_decl
= tmp_decl
;
3044 /* Code taken from start_function. */
3045 tree restype
= TREE_TYPE (TREE_TYPE (tmp_decl
));
3046 /* Promote the value to int before returning it. */
3047 if (TREE_CODE (restype
) == INTEGER_TYPE
3048 && TYPE_PRECISION (restype
) < TYPE_PRECISION (integer_type_node
))
3049 restype
= integer_type_node
;
3050 DECL_RESULT (tmp_decl
) = build_decl (RESULT_DECL
, 0, restype
);
3053 for (parm
= DECL_ARGUMENTS (tmp_decl
); parm
; parm
= TREE_CHAIN (parm
))
3054 DECL_CONTEXT (parm
) = tmp_decl
;
3056 init_function_start (tmp_decl
, "objc-act", 0);
3058 /* Typically called from expand_function_start for function definitions. */
3059 assign_parms (tmp_decl
, 0);
3061 /* install return type */
3062 TREE_TYPE (TREE_TYPE (tmp_decl
)) = groktypename (TREE_TYPE (nst_methods
));
3067 generate_protocol_references (plist
)
3072 /* Forward declare protocols referenced. */
3073 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
3075 tree proto
= TREE_VALUE (lproto
);
3077 if (TREE_CODE (proto
) == PROTOCOL_INTERFACE_TYPE
3078 && PROTOCOL_NAME (proto
))
3080 if (! PROTOCOL_FORWARD_DECL (proto
))
3081 build_protocol_reference (proto
);
3083 if (PROTOCOL_LIST (proto
))
3084 generate_protocol_references (PROTOCOL_LIST (proto
));
3090 generate_protocols ()
3092 tree p
, tmp_decl
, encoding
;
3093 tree sc_spec
, decl_specs
, decl
;
3094 tree initlist
, protocol_name_expr
, refs_decl
, refs_expr
;
3095 tree cast_type2
= 0;
3097 tmp_decl
= build_tmp_function_decl ();
3099 if (! objc_protocol_template
)
3100 objc_protocol_template
= build_protocol_template ();
3102 /* If a protocol was directly referenced, pull in indirect references. */
3103 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3104 if (PROTOCOL_FORWARD_DECL (p
) && PROTOCOL_LIST (p
))
3105 generate_protocol_references (PROTOCOL_LIST (p
));
3107 for (p
= protocol_chain
; p
; p
= TREE_CHAIN (p
))
3109 tree nst_methods
= PROTOCOL_NST_METHODS (p
);
3110 tree cls_methods
= PROTOCOL_CLS_METHODS (p
);
3112 /* If protocol wasn't referenced, don't generate any code. */
3113 if (! PROTOCOL_FORWARD_DECL (p
))
3116 /* Make sure we link in the Protocol class. */
3117 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME
));
3121 if (! METHOD_ENCODING (nst_methods
))
3123 hack_method_prototype (nst_methods
, tmp_decl
);
3124 encoding
= encode_method_prototype (nst_methods
, tmp_decl
);
3125 METHOD_ENCODING (nst_methods
) = encoding
;
3127 nst_methods
= TREE_CHAIN (nst_methods
);
3132 if (! METHOD_ENCODING (cls_methods
))
3134 hack_method_prototype (cls_methods
, tmp_decl
);
3135 encoding
= encode_method_prototype (cls_methods
, tmp_decl
);
3136 METHOD_ENCODING (cls_methods
) = encoding
;
3139 cls_methods
= TREE_CHAIN (cls_methods
);
3141 generate_method_descriptors (p
);
3143 if (PROTOCOL_LIST (p
))
3144 refs_decl
= generate_protocol_list (p
);
3148 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
3150 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
],
3152 decl_specs
= tree_cons (NULL_TREE
, objc_protocol_template
, sc_spec
);
3154 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
),
3155 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
3157 protocol_name_expr
= add_objc_string (PROTOCOL_NAME (p
), class_names
);
3164 (build_tree_list (build_tree_list (NULL_TREE
,
3165 objc_protocol_template
),
3166 build1 (INDIRECT_REF
, NULL_TREE
,
3167 build1 (INDIRECT_REF
, NULL_TREE
,
3170 refs_expr
= build_unary_op (ADDR_EXPR
, refs_decl
, 0);
3171 TREE_TYPE (refs_expr
) = cast_type2
;
3174 refs_expr
= build_int_2 (0, 0);
3176 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
3177 by generate_method_descriptors, which is called above. */
3178 initlist
= build_protocol_initializer (TREE_TYPE (decl
),
3179 protocol_name_expr
, refs_expr
,
3180 UOBJC_INSTANCE_METHODS_decl
,
3181 UOBJC_CLASS_METHODS_decl
);
3182 finish_decl (decl
, initlist
, NULL_TREE
);
3184 /* Mark the decl as used to avoid "defined but not used" warning. */
3185 TREE_USED (decl
) = 1;
3190 build_protocol_initializer (type
, protocol_name
, protocol_list
,
3191 instance_methods
, class_methods
)
3195 tree instance_methods
;
3198 tree initlist
= NULL_TREE
, expr
;
3199 static tree cast_type
= 0;
3205 (build_tree_list (NULL_TREE
,
3206 xref_tag (RECORD_TYPE
,
3207 get_identifier (UTAG_CLASS
))),
3208 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
3210 /* Filling the "isa" in with one allows the runtime system to
3211 detect that the version change...should remove before final release. */
3213 expr
= build_int_2 (PROTOCOL_VERSION
, 0);
3214 TREE_TYPE (expr
) = cast_type
;
3215 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3216 initlist
= tree_cons (NULL_TREE
, protocol_name
, initlist
);
3217 initlist
= tree_cons (NULL_TREE
, protocol_list
, initlist
);
3219 if (!instance_methods
)
3220 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3223 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
3224 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3228 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
3231 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
3232 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
3235 return build_constructor (type
, nreverse (initlist
));
3238 /* struct objc_category {
3239 char *category_name;
3241 struct objc_method_list *instance_methods;
3242 struct objc_method_list *class_methods;
3243 struct objc_protocol_list *protocols;
3247 build_category_template ()
3249 tree decl_specs
, field_decl
, field_decl_chain
;
3251 objc_category_template
= start_struct (RECORD_TYPE
,
3252 get_identifier (UTAG_CATEGORY
));
3253 /* char *category_name; */
3255 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3257 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("category_name"));
3259 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3260 field_decl_chain
= field_decl
;
3262 /* char *class_name; */
3264 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3265 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_name"));
3267 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3268 chainon (field_decl_chain
, field_decl
);
3270 /* struct objc_method_list *instance_methods; */
3272 decl_specs
= build_tree_list (NULL_TREE
,
3273 xref_tag (RECORD_TYPE
,
3274 get_identifier (UTAG_METHOD_LIST
)));
3276 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("instance_methods"));
3278 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3279 chainon (field_decl_chain
, field_decl
);
3281 /* struct objc_method_list *class_methods; */
3283 decl_specs
= build_tree_list (NULL_TREE
,
3284 xref_tag (RECORD_TYPE
,
3285 get_identifier (UTAG_METHOD_LIST
)));
3287 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class_methods"));
3289 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3290 chainon (field_decl_chain
, field_decl
);
3292 /* struct objc_protocol **protocol_list; */
3294 decl_specs
= build_tree_list (NULL_TREE
,
3295 xref_tag (RECORD_TYPE
,
3296 get_identifier (UTAG_PROTOCOL
)));
3298 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3299 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3301 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3302 chainon (field_decl_chain
, field_decl
);
3304 finish_struct (objc_category_template
, field_decl_chain
, NULL_TREE
);
3307 /* struct objc_selector {
3313 build_selector_template ()
3316 tree decl_specs
, field_decl
, field_decl_chain
;
3318 objc_selector_template
3319 = start_struct (RECORD_TYPE
, get_identifier (UTAG_SELECTOR
));
3323 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_VOID
]);
3324 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_id"));
3326 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3327 field_decl_chain
= field_decl
;
3329 /* char *sel_type; */
3331 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3332 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sel_type"));
3334 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3335 chainon (field_decl_chain
, field_decl
);
3337 finish_struct (objc_selector_template
, field_decl_chain
, NULL_TREE
);
3340 /* struct objc_class {
3341 struct objc_class *isa;
3342 struct objc_class *super_class;
3347 struct objc_ivar_list *ivars;
3348 struct objc_method_list *methods;
3349 if (flag_next_runtime)
3350 struct objc_cache *cache;
3352 struct sarray *dtable;
3353 struct objc_class *subclass_list;
3354 struct objc_class *sibling_class;
3356 struct objc_protocol_list *protocols;
3360 build_class_template ()
3362 tree decl_specs
, field_decl
, field_decl_chain
;
3365 = start_struct (RECORD_TYPE
, get_identifier (UTAG_CLASS
));
3367 /* struct objc_class *isa; */
3369 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3370 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("isa"));
3372 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3373 field_decl_chain
= field_decl
;
3375 /* struct objc_class *super_class; */
3377 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3379 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("super_class"));
3381 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3382 chainon (field_decl_chain
, field_decl
);
3386 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3387 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("name"));
3389 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3390 chainon (field_decl_chain
, field_decl
);
3394 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3395 field_decl
= get_identifier ("version");
3397 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3398 chainon (field_decl_chain
, field_decl
);
3402 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3403 field_decl
= get_identifier ("info");
3405 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3406 chainon (field_decl_chain
, field_decl
);
3408 /* long instance_size; */
3410 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_LONG
]);
3411 field_decl
= get_identifier ("instance_size");
3413 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3414 chainon (field_decl_chain
, field_decl
);
3416 /* struct objc_ivar_list *ivars; */
3418 decl_specs
= build_tree_list (NULL_TREE
,
3419 xref_tag (RECORD_TYPE
,
3420 get_identifier (UTAG_IVAR_LIST
)));
3421 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivars"));
3423 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3424 chainon (field_decl_chain
, field_decl
);
3426 /* struct objc_method_list *methods; */
3428 decl_specs
= build_tree_list (NULL_TREE
,
3429 xref_tag (RECORD_TYPE
,
3430 get_identifier (UTAG_METHOD_LIST
)));
3431 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("methods"));
3433 = grokfield (input_filename
, lineno
, field_decl
, decl_specs
, NULL_TREE
);
3434 chainon (field_decl_chain
, field_decl
);
3436 if (flag_next_runtime
)
3438 /* struct objc_cache *cache; */
3440 decl_specs
= build_tree_list (NULL_TREE
,
3441 xref_tag (RECORD_TYPE
,
3442 get_identifier ("objc_cache")));
3443 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("cache"));
3444 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3445 decl_specs
, NULL_TREE
);
3446 chainon (field_decl_chain
, field_decl
);
3450 /* struct sarray *dtable; */
3452 decl_specs
= build_tree_list (NULL_TREE
,
3453 xref_tag (RECORD_TYPE
,
3454 get_identifier ("sarray")));
3455 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("dtable"));
3456 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3457 decl_specs
, NULL_TREE
);
3458 chainon (field_decl_chain
, field_decl
);
3460 /* struct objc_class *subclass_list; */
3462 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3464 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("subclass_list"));
3465 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3466 decl_specs
, NULL_TREE
);
3467 chainon (field_decl_chain
, field_decl
);
3469 /* struct objc_class *sibling_class; */
3471 decl_specs
= build_tree_list (NULL_TREE
, objc_class_template
);
3473 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("sibling_class"));
3474 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3475 decl_specs
, NULL_TREE
);
3476 chainon (field_decl_chain
, field_decl
);
3479 /* struct objc_protocol **protocol_list; */
3481 decl_specs
= build_tree_list (NULL_TREE
,
3482 xref_tag (RECORD_TYPE
,
3483 get_identifier (UTAG_PROTOCOL
)));
3485 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("protocol_list"));
3487 = build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3488 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3489 decl_specs
, NULL_TREE
);
3490 chainon (field_decl_chain
, field_decl
);
3493 finish_struct (objc_class_template
, field_decl_chain
, NULL_TREE
);
3496 /* Generate appropriate forward declarations for an implementation. */
3499 synth_forward_declarations ()
3501 tree sc_spec
, decl_specs
, an_id
;
3503 /* extern struct objc_class _OBJC_CLASS_<my_name>; */
3505 an_id
= synth_id_with_class_suffix ("_OBJC_CLASS", implementation_context
);
3507 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
3508 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
3509 UOBJC_CLASS_decl
= define_decl (an_id
, decl_specs
);
3510 TREE_USED (UOBJC_CLASS_decl
) = 1;
3511 DECL_ARTIFICIAL (UOBJC_CLASS_decl
) = 1;
3513 /* extern struct objc_class _OBJC_METACLASS_<my_name>; */
3515 an_id
= synth_id_with_class_suffix ("_OBJC_METACLASS",
3516 implementation_context
);
3518 UOBJC_METACLASS_decl
= define_decl (an_id
, decl_specs
);
3519 TREE_USED (UOBJC_METACLASS_decl
) = 1;
3520 DECL_ARTIFICIAL(UOBJC_METACLASS_decl
) = 1;
3522 /* Pre-build the following entities - for speed/convenience. */
3524 an_id
= get_identifier ("super_class");
3525 ucls_super_ref
= build_component_ref (UOBJC_CLASS_decl
, an_id
);
3526 uucls_super_ref
= build_component_ref (UOBJC_METACLASS_decl
, an_id
);
3530 error_with_ivar (message
, decl
, rawdecl
)
3537 report_error_function (DECL_SOURCE_FILE (decl
));
3539 fprintf (stderr
, "%s:%d: ",
3540 DECL_SOURCE_FILE (decl
), DECL_SOURCE_LINE (decl
));
3541 bzero (errbuf
, BUFSIZE
);
3542 fprintf (stderr
, "%s `%s'\n", message
, gen_declaration (rawdecl
, errbuf
));
3545 #define USERTYPE(t) \
3546 (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \
3547 || TREE_CODE (t) == ENUMERAL_TYPE)
3550 check_ivars (inter
, imp
)
3554 tree intdecls
= CLASS_IVARS (inter
);
3555 tree impdecls
= CLASS_IVARS (imp
);
3556 tree rawintdecls
= CLASS_RAW_IVARS (inter
);
3557 tree rawimpdecls
= CLASS_RAW_IVARS (imp
);
3563 if (intdecls
== 0 && impdecls
== 0)
3565 if (intdecls
== 0 || impdecls
== 0)
3567 error ("inconsistent instance variable specification");
3571 t1
= TREE_TYPE (intdecls
); t2
= TREE_TYPE (impdecls
);
3573 if (!comptypes (t1
, t2
))
3575 if (DECL_NAME (intdecls
) == DECL_NAME (impdecls
))
3577 error_with_ivar ("conflicting instance variable type",
3578 impdecls
, rawimpdecls
);
3579 error_with_ivar ("previous declaration of",
3580 intdecls
, rawintdecls
);
3582 else /* both the type and the name don't match */
3584 error ("inconsistent instance variable specification");
3589 else if (DECL_NAME (intdecls
) != DECL_NAME (impdecls
))
3591 error_with_ivar ("conflicting instance variable name",
3592 impdecls
, rawimpdecls
);
3593 error_with_ivar ("previous declaration of",
3594 intdecls
, rawintdecls
);
3597 intdecls
= TREE_CHAIN (intdecls
);
3598 impdecls
= TREE_CHAIN (impdecls
);
3599 rawintdecls
= TREE_CHAIN (rawintdecls
);
3600 rawimpdecls
= TREE_CHAIN (rawimpdecls
);
3604 /* Set super_type to the data type node for struct objc_super *,
3605 first defining struct objc_super itself.
3606 This needs to be done just once per compilation. */
3609 build_super_template ()
3611 tree record
, decl_specs
, field_decl
, field_decl_chain
;
3613 record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_SUPER
));
3615 /* struct objc_object *self; */
3617 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
3618 field_decl
= get_identifier ("self");
3619 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, field_decl
);
3620 field_decl
= grokfield (input_filename
, lineno
,
3621 field_decl
, decl_specs
, NULL_TREE
);
3622 field_decl_chain
= field_decl
;
3624 /* struct objc_class *class; */
3626 decl_specs
= get_identifier (UTAG_CLASS
);
3627 decl_specs
= build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
, decl_specs
));
3628 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("class"));
3630 field_decl
= grokfield (input_filename
, lineno
,
3631 field_decl
, decl_specs
, NULL_TREE
);
3632 chainon (field_decl_chain
, field_decl
);
3634 finish_struct (record
, field_decl_chain
, NULL_TREE
);
3636 /* `struct objc_super *' */
3637 super_type
= groktypename (build_tree_list (build_tree_list (NULL_TREE
,
3639 build1 (INDIRECT_REF
,
3640 NULL_TREE
, NULL_TREE
)));
3644 /* struct objc_ivar {
3651 build_ivar_template ()
3653 tree objc_ivar_id
, objc_ivar_record
;
3654 tree decl_specs
, field_decl
, field_decl_chain
;
3656 objc_ivar_id
= get_identifier (UTAG_IVAR
);
3657 objc_ivar_record
= start_struct (RECORD_TYPE
, objc_ivar_id
);
3659 /* char *ivar_name; */
3661 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3662 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_name"));
3664 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3665 decl_specs
, NULL_TREE
);
3666 field_decl_chain
= field_decl
;
3668 /* char *ivar_type; */
3670 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_CHAR
]);
3671 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("ivar_type"));
3673 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3674 decl_specs
, NULL_TREE
);
3675 chainon (field_decl_chain
, field_decl
);
3677 /* int ivar_offset; */
3679 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3680 field_decl
= get_identifier ("ivar_offset");
3682 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3683 decl_specs
, NULL_TREE
);
3684 chainon (field_decl_chain
, field_decl
);
3686 finish_struct (objc_ivar_record
, field_decl_chain
, NULL_TREE
);
3688 return objc_ivar_record
;
3693 struct objc_ivar ivar_list[ivar_count];
3697 build_ivar_list_template (list_type
, size
)
3701 tree objc_ivar_list_record
;
3702 tree decl_specs
, field_decl
, field_decl_chain
;
3704 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3706 /* int ivar_count; */
3708 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3709 field_decl
= get_identifier ("ivar_count");
3711 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3712 decl_specs
, NULL_TREE
);
3713 field_decl_chain
= field_decl
;
3715 /* struct objc_ivar ivar_list[]; */
3717 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3718 field_decl
= build_nt (ARRAY_REF
, get_identifier ("ivar_list"),
3719 build_int_2 (size
, 0));
3721 field_decl
= grokfield (input_filename
, lineno
,
3722 field_decl
, decl_specs
, NULL_TREE
);
3723 chainon (field_decl_chain
, field_decl
);
3725 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3727 return objc_ivar_list_record
;
3733 struct objc_method method_list[method_count];
3737 build_method_list_template (list_type
, size
)
3741 tree objc_ivar_list_record
;
3742 tree decl_specs
, field_decl
, field_decl_chain
;
3744 objc_ivar_list_record
= start_struct (RECORD_TYPE
, NULL_TREE
);
3746 /* int method_next; */
3751 xref_tag (RECORD_TYPE
,
3752 get_identifier (UTAG_METHOD_PROTOTYPE_LIST
)));
3754 = build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("method_next"));
3755 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3756 decl_specs
, NULL_TREE
);
3757 field_decl_chain
= field_decl
;
3759 /* int method_count; */
3761 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_INT
]);
3762 field_decl
= get_identifier ("method_count");
3764 field_decl
= grokfield (input_filename
, lineno
,
3765 field_decl
, decl_specs
, NULL_TREE
);
3766 chainon (field_decl_chain
, field_decl
);
3768 /* struct objc_method method_list[]; */
3770 decl_specs
= build_tree_list (NULL_TREE
, list_type
);
3771 field_decl
= build_nt (ARRAY_REF
, get_identifier ("method_list"),
3772 build_int_2 (size
, 0));
3774 field_decl
= grokfield (input_filename
, lineno
,
3775 field_decl
, decl_specs
, NULL_TREE
);
3776 chainon (field_decl_chain
, field_decl
);
3778 finish_struct (objc_ivar_list_record
, field_decl_chain
, NULL_TREE
);
3780 return objc_ivar_list_record
;
3784 build_ivar_list_initializer (type
, field_decl
)
3788 tree initlist
= NULL_TREE
;
3792 tree ivar
= NULL_TREE
;
3795 if (DECL_NAME (field_decl
))
3796 ivar
= tree_cons (NULL_TREE
,
3797 add_objc_string (DECL_NAME (field_decl
),
3801 /* Unnamed bit-field ivar (yuck). */
3802 ivar
= tree_cons (NULL_TREE
, build_int_2 (0, 0), ivar
);
3805 encode_field_decl (field_decl
,
3806 obstack_object_size (&util_obstack
),
3807 OBJC_ENCODE_DONT_INLINE_DEFS
);
3809 /* Null terminate string. */
3810 obstack_1grow (&util_obstack
, 0);
3814 add_objc_string (get_identifier (obstack_finish (&util_obstack
)),
3817 obstack_free (&util_obstack
, util_firstobj
);
3823 build_int_2 ((TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl
))
3828 initlist
= tree_cons (NULL_TREE
,
3829 build_constructor (type
, nreverse (ivar
)),
3832 field_decl
= TREE_CHAIN (field_decl
);
3836 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3840 generate_ivars_list (type
, name
, size
, list
)
3846 tree sc_spec
, decl_specs
, decl
, initlist
;
3848 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
3849 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
3851 decl
= start_decl (synth_id_with_class_suffix (name
, implementation_context
),
3852 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
3854 initlist
= build_tree_list (NULL_TREE
, build_int_2 (size
, 0));
3855 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
3858 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
3865 generate_ivar_lists ()
3867 tree initlist
, ivar_list_template
, chain
;
3868 tree cast
, variable_length_type
;
3871 generating_instance_variables
= 1;
3873 if (!objc_ivar_template
)
3874 objc_ivar_template
= build_ivar_template ();
3878 (build_tree_list (NULL_TREE
, xref_tag (RECORD_TYPE
,
3879 get_identifier (UTAG_IVAR_LIST
))),
3881 variable_length_type
= groktypename (cast
);
3883 /* Only generate class variables for the root of the inheritance
3884 hierarchy since these will be the same for every class. */
3886 if (CLASS_SUPER_NAME (implementation_template
) == NULL_TREE
3887 && (chain
= TYPE_FIELDS (objc_class_template
)))
3889 size
= list_length (chain
);
3891 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3892 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3894 UOBJC_CLASS_VARIABLES_decl
3895 = generate_ivars_list (ivar_list_template
, "_OBJC_CLASS_VARIABLES",
3897 TREE_TYPE (UOBJC_CLASS_VARIABLES_decl
) = variable_length_type
;
3900 UOBJC_CLASS_VARIABLES_decl
= 0;
3902 chain
= CLASS_IVARS (implementation_template
);
3905 size
= list_length (chain
);
3906 ivar_list_template
= build_ivar_list_template (objc_ivar_template
, size
);
3907 initlist
= build_ivar_list_initializer (objc_ivar_template
, chain
);
3909 UOBJC_INSTANCE_VARIABLES_decl
3910 = generate_ivars_list (ivar_list_template
, "_OBJC_INSTANCE_VARIABLES",
3912 TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl
) = variable_length_type
;
3915 UOBJC_INSTANCE_VARIABLES_decl
= 0;
3917 generating_instance_variables
= 0;
3921 build_dispatch_table_initializer (type
, entries
)
3925 tree initlist
= NULL_TREE
;
3929 tree elemlist
= NULL_TREE
;
3931 elemlist
= tree_cons (NULL_TREE
,
3932 build_selector (METHOD_SEL_NAME (entries
)),
3935 elemlist
= tree_cons (NULL_TREE
,
3936 add_objc_string (METHOD_ENCODING (entries
),
3940 elemlist
= tree_cons (NULL_TREE
,
3941 build_unary_op (ADDR_EXPR
,
3942 METHOD_DEFINITION (entries
), 1),
3945 initlist
= tree_cons (NULL_TREE
,
3946 build_constructor (type
, nreverse (elemlist
)),
3949 entries
= TREE_CHAIN (entries
);
3953 return build_constructor (build_array_type (type
, 0), nreverse (initlist
));
3956 /* To accomplish method prototyping without generating all kinds of
3957 inane warnings, the definition of the dispatch table entries were
3960 struct objc_method { SEL _cmd; ...; id (*_imp)(); };
3962 struct objc_method { SEL _cmd; ...; void *_imp; }; */
3965 build_method_template ()
3968 tree decl_specs
, field_decl
, field_decl_chain
;
3970 _SLT_record
= start_struct (RECORD_TYPE
, get_identifier (UTAG_METHOD
));
3972 #ifdef OBJC_INT_SELECTORS
3973 /* unsigned int _cmd; */
3974 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_UNSIGNED
],
3976 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_INT
], decl_specs
);
3977 field_decl
= get_identifier ("_cmd");
3978 #else /* not OBJC_INT_SELECTORS */
3979 /* struct objc_selector *_cmd; */
3980 decl_specs
= tree_cons (NULL_TREE
,
3981 xref_tag (RECORD_TYPE
,
3982 get_identifier (TAG_SELECTOR
)),
3984 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_cmd"));
3985 #endif /* not OBJC_INT_SELECTORS */
3987 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3988 decl_specs
, NULL_TREE
);
3989 field_decl_chain
= field_decl
;
3991 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_CHAR
], NULL_TREE
);
3992 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
,
3993 get_identifier ("method_types"));
3994 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
3995 decl_specs
, NULL_TREE
);
3996 chainon (field_decl_chain
, field_decl
);
4000 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_VOID
], NULL_TREE
);
4001 field_decl
= build1 (INDIRECT_REF
, NULL_TREE
, get_identifier ("_imp"));
4002 field_decl
= grokfield (input_filename
, lineno
, field_decl
,
4003 decl_specs
, NULL_TREE
);
4004 chainon (field_decl_chain
, field_decl
);
4006 finish_struct (_SLT_record
, field_decl_chain
, NULL_TREE
);
4013 generate_dispatch_table (type
, name
, size
, list
)
4019 tree sc_spec
, decl_specs
, decl
, initlist
;
4021 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4022 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
4024 decl
= start_decl (synth_id_with_class_suffix (name
, implementation_context
),
4025 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
4027 initlist
= build_tree_list (NULL_TREE
, build_int_2 (0, 0));
4028 initlist
= tree_cons (NULL_TREE
, build_int_2 (size
, 0), initlist
);
4029 initlist
= tree_cons (NULL_TREE
, list
, initlist
);
4032 build_constructor (TREE_TYPE (decl
), nreverse (initlist
)),
4039 generate_dispatch_tables ()
4041 tree initlist
, chain
, method_list_template
;
4042 tree cast
, variable_length_type
;
4045 if (!objc_method_template
)
4046 objc_method_template
= build_method_template ();
4050 (build_tree_list (NULL_TREE
,
4051 xref_tag (RECORD_TYPE
,
4052 get_identifier (UTAG_METHOD_LIST
))),
4055 variable_length_type
= groktypename (cast
);
4057 chain
= CLASS_CLS_METHODS (implementation_context
);
4060 size
= list_length (chain
);
4062 method_list_template
4063 = build_method_list_template (objc_method_template
, size
);
4065 = build_dispatch_table_initializer (objc_method_template
, chain
);
4067 UOBJC_CLASS_METHODS_decl
4068 = generate_dispatch_table (method_list_template
,
4069 ((TREE_CODE (implementation_context
)
4070 == CLASS_IMPLEMENTATION_TYPE
)
4071 ? "_OBJC_CLASS_METHODS"
4072 : "_OBJC_CATEGORY_CLASS_METHODS"),
4074 TREE_TYPE (UOBJC_CLASS_METHODS_decl
) = variable_length_type
;
4077 UOBJC_CLASS_METHODS_decl
= 0;
4079 chain
= CLASS_NST_METHODS (implementation_context
);
4082 size
= list_length (chain
);
4084 method_list_template
4085 = build_method_list_template (objc_method_template
, size
);
4087 = build_dispatch_table_initializer (objc_method_template
, chain
);
4089 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
4090 UOBJC_INSTANCE_METHODS_decl
4091 = generate_dispatch_table (method_list_template
,
4092 "_OBJC_INSTANCE_METHODS",
4095 /* We have a category. */
4096 UOBJC_INSTANCE_METHODS_decl
4097 = generate_dispatch_table (method_list_template
,
4098 "_OBJC_CATEGORY_INSTANCE_METHODS",
4100 TREE_TYPE (UOBJC_INSTANCE_METHODS_decl
) = variable_length_type
;
4103 UOBJC_INSTANCE_METHODS_decl
= 0;
4107 generate_protocol_list (i_or_p
)
4110 static tree cast_type
= 0;
4111 tree initlist
, decl_specs
, sc_spec
;
4112 tree refs_decl
, expr_decl
, lproto
, e
, plist
;
4115 if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
4116 || TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4117 plist
= CLASS_PROTOCOL_LIST (i_or_p
);
4118 else if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4119 plist
= PROTOCOL_LIST (i_or_p
);
4127 (build_tree_list (NULL_TREE
,
4128 xref_tag (RECORD_TYPE
,
4129 get_identifier (UTAG_PROTOCOL
))),
4130 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
)));
4133 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4134 if (TREE_CODE (TREE_VALUE (lproto
)) == PROTOCOL_INTERFACE_TYPE
4135 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto
)))
4138 /* Build initializer. */
4139 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), NULL_TREE
);
4141 e
= build_int_2 (size
, 0);
4142 TREE_TYPE (e
) = cast_type
;
4143 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4145 for (lproto
= plist
; lproto
; lproto
= TREE_CHAIN (lproto
))
4147 tree pval
= TREE_VALUE (lproto
);
4149 if (TREE_CODE (pval
) == PROTOCOL_INTERFACE_TYPE
4150 && PROTOCOL_FORWARD_DECL (pval
))
4152 e
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (pval
), 0);
4153 initlist
= tree_cons (NULL_TREE
, e
, initlist
);
4157 /* static struct objc_protocol *refs[n]; */
4159 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4160 decl_specs
= tree_cons (NULL_TREE
, xref_tag (RECORD_TYPE
,
4161 get_identifier (UTAG_PROTOCOL
)),
4164 if (TREE_CODE (i_or_p
) == PROTOCOL_INTERFACE_TYPE
)
4165 expr_decl
= build_nt (ARRAY_REF
,
4166 synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS",
4168 build_int_2 (size
+ 2, 0));
4169 else if (TREE_CODE (i_or_p
) == CLASS_INTERFACE_TYPE
)
4170 expr_decl
= build_nt (ARRAY_REF
,
4171 synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS",
4173 build_int_2 (size
+ 2, 0));
4174 else if (TREE_CODE (i_or_p
) == CATEGORY_INTERFACE_TYPE
)
4176 = build_nt (ARRAY_REF
,
4177 synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS",
4179 build_int_2 (size
+ 2, 0));
4181 expr_decl
= build1 (INDIRECT_REF
, NULL_TREE
, expr_decl
);
4183 refs_decl
= start_decl (expr_decl
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
4185 finish_decl (refs_decl
, build_constructor (TREE_TYPE (refs_decl
),
4186 nreverse (initlist
)),
4193 build_category_initializer (type
, cat_name
, class_name
,
4194 instance_methods
, class_methods
, protocol_list
)
4198 tree instance_methods
;
4202 tree initlist
= NULL_TREE
, expr
;
4204 initlist
= tree_cons (NULL_TREE
, cat_name
, initlist
);
4205 initlist
= tree_cons (NULL_TREE
, class_name
, initlist
);
4207 if (!instance_methods
)
4208 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4211 expr
= build_unary_op (ADDR_EXPR
, instance_methods
, 0);
4212 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4215 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4218 expr
= build_unary_op (ADDR_EXPR
, class_methods
, 0);
4219 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4222 /* protocol_list = */
4224 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4227 static tree cast_type2
;
4233 (build_tree_list (NULL_TREE
,
4234 xref_tag (RECORD_TYPE
,
4235 get_identifier (UTAG_PROTOCOL
))),
4236 build1 (INDIRECT_REF
, NULL_TREE
,
4237 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4239 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4240 TREE_TYPE (expr
) = cast_type2
;
4241 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4244 return build_constructor (type
, nreverse (initlist
));
4247 /* struct objc_class {
4248 struct objc_class *isa;
4249 struct objc_class *super_class;
4254 struct objc_ivar_list *ivars;
4255 struct objc_method_list *methods;
4256 if (flag_next_runtime)
4257 struct objc_cache *cache;
4259 struct sarray *dtable;
4260 struct objc_class *subclass_list;
4261 struct objc_class *sibling_class;
4263 struct objc_protocol_list *protocols;
4267 build_shared_structure_initializer (type
, isa
, super
, name
, size
, status
,
4268 dispatch_table
, ivar_list
, protocol_list
)
4275 tree dispatch_table
;
4279 tree initlist
= NULL_TREE
, expr
;
4282 initlist
= tree_cons (NULL_TREE
, isa
, initlist
);
4285 initlist
= tree_cons (NULL_TREE
, super
, initlist
);
4288 initlist
= tree_cons (NULL_TREE
, default_conversion (name
), initlist
);
4291 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4294 initlist
= tree_cons (NULL_TREE
, build_int_2 (status
, 0), initlist
);
4296 /* instance_size = */
4297 initlist
= tree_cons (NULL_TREE
, size
, initlist
);
4299 /* objc_ivar_list = */
4301 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4304 expr
= build_unary_op (ADDR_EXPR
, ivar_list
, 0);
4305 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4308 /* objc_method_list = */
4309 if (!dispatch_table
)
4310 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4313 expr
= build_unary_op (ADDR_EXPR
, dispatch_table
, 0);
4314 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4317 if (flag_next_runtime
)
4318 /* method_cache = */
4319 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4323 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4325 /* subclass_list = */
4326 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4328 /* sibling_class = */
4329 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4332 /* protocol_list = */
4333 if (! protocol_list
)
4334 initlist
= tree_cons (NULL_TREE
, build_int_2 (0, 0), initlist
);
4337 static tree cast_type2
;
4343 (build_tree_list (NULL_TREE
,
4344 xref_tag (RECORD_TYPE
,
4345 get_identifier (UTAG_PROTOCOL
))),
4346 build1 (INDIRECT_REF
, NULL_TREE
,
4347 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
))));
4349 expr
= build_unary_op (ADDR_EXPR
, protocol_list
, 0);
4350 TREE_TYPE (expr
) = cast_type2
;
4351 initlist
= tree_cons (NULL_TREE
, expr
, initlist
);
4354 return build_constructor (type
, nreverse (initlist
));
4357 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
4360 generate_category (cat
)
4363 tree sc_spec
, decl_specs
, decl
;
4364 tree initlist
, cat_name_expr
, class_name_expr
;
4365 tree protocol_decl
, category
;
4367 add_class_reference (CLASS_NAME (cat
));
4368 cat_name_expr
= add_objc_string (CLASS_SUPER_NAME (cat
), class_names
);
4370 class_name_expr
= add_objc_string (CLASS_NAME (cat
), class_names
);
4372 category
= CLASS_CATEGORY_LIST (implementation_template
);
4374 /* find the category interface from the class it is associated with */
4377 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
4379 category
= CLASS_CATEGORY_LIST (category
);
4382 if (category
&& CLASS_PROTOCOL_LIST (category
))
4384 generate_protocol_references (CLASS_PROTOCOL_LIST (category
));
4385 protocol_decl
= generate_protocol_list (category
);
4390 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
4391 decl_specs
= tree_cons (NULL_TREE
, objc_category_template
, sc_spec
);
4393 decl
= start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY",
4394 implementation_context
),
4395 decl_specs
, 1, NULL_TREE
, NULL_TREE
);
4397 initlist
= build_category_initializer (TREE_TYPE (decl
),
4398 cat_name_expr
, class_name_expr
,
4399 UOBJC_INSTANCE_METHODS_decl
,
4400 UOBJC_CLASS_METHODS_decl
,
4403 TREE_USED (decl
) = 1;
4404 finish_decl (decl
, initlist
, NULL_TREE
);
4407 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
4408 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4411 generate_shared_structures ()
4413 tree sc_spec
, decl_specs
, decl
;
4414 tree name_expr
, super_expr
, root_expr
;
4415 tree my_root_id
= NULL_TREE
, my_super_id
= NULL_TREE
;
4416 tree cast_type
, initlist
, protocol_decl
;
4418 my_super_id
= CLASS_SUPER_NAME (implementation_template
);
4421 add_class_reference (my_super_id
);
4423 /* Compute "my_root_id" - this is required for code generation.
4424 the "isa" for all meta class structures points to the root of
4425 the inheritance hierarchy (e.g. "__Object")... */
4426 my_root_id
= my_super_id
;
4429 tree my_root_int
= lookup_interface (my_root_id
);
4431 if (my_root_int
&& CLASS_SUPER_NAME (my_root_int
))
4432 my_root_id
= CLASS_SUPER_NAME (my_root_int
);
4439 /* No super class. */
4440 my_root_id
= CLASS_NAME (implementation_template
);
4443 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
4444 objc_class_template
),
4445 build1 (INDIRECT_REF
,
4446 NULL_TREE
, NULL_TREE
)));
4448 name_expr
= add_objc_string (CLASS_NAME (implementation_template
),
4451 /* Install class `isa' and `super' pointers at runtime. */
4454 super_expr
= add_objc_string (my_super_id
, class_names
);
4455 super_expr
= build_c_cast (cast_type
, super_expr
); /* cast! */
4458 super_expr
= build_int_2 (0, 0);
4460 root_expr
= add_objc_string (my_root_id
, class_names
);
4461 root_expr
= build_c_cast (cast_type
, root_expr
); /* cast! */
4463 if (CLASS_PROTOCOL_LIST (implementation_template
))
4465 generate_protocol_references
4466 (CLASS_PROTOCOL_LIST (implementation_template
));
4467 protocol_decl
= generate_protocol_list (implementation_template
);
4472 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
4474 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
4475 decl_specs
= tree_cons (NULL_TREE
, objc_class_template
, sc_spec
);
4477 decl
= start_decl (DECL_NAME (UOBJC_METACLASS_decl
), decl_specs
, 1,
4478 NULL_TREE
, NULL_TREE
);
4481 = build_shared_structure_initializer
4483 root_expr
, super_expr
, name_expr
,
4484 build_int_2 ((TREE_INT_CST_LOW (TYPE_SIZE (objc_class_template
))
4488 UOBJC_CLASS_METHODS_decl
,
4489 UOBJC_CLASS_VARIABLES_decl
,
4492 finish_decl (decl
, initlist
, NULL_TREE
);
4494 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
4496 decl
= start_decl (DECL_NAME (UOBJC_CLASS_decl
), decl_specs
, 1,
4497 NULL_TREE
, NULL_TREE
);
4500 = build_shared_structure_initializer
4502 build_unary_op (ADDR_EXPR
, UOBJC_METACLASS_decl
, 0),
4503 super_expr
, name_expr
,
4506 (TYPE_SIZE (CLASS_STATIC_TEMPLATE (implementation_template
)))
4510 UOBJC_INSTANCE_METHODS_decl
,
4511 UOBJC_INSTANCE_VARIABLES_decl
,
4514 finish_decl (decl
, initlist
, NULL_TREE
);
4518 synth_id_with_class_suffix (preamble
, ctxt
)
4523 if (TREE_CODE (ctxt
) == CLASS_IMPLEMENTATION_TYPE
4524 || TREE_CODE (ctxt
) == CLASS_INTERFACE_TYPE
)
4527 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
4528 string
= (char *) alloca (strlen (preamble
) + strlen (class_name
) + 3);
4529 sprintf (string
, "%s_%s", preamble
,
4530 IDENTIFIER_POINTER (CLASS_NAME (ctxt
)));
4532 else if (TREE_CODE (ctxt
) == CATEGORY_IMPLEMENTATION_TYPE
4533 || TREE_CODE (ctxt
) == CATEGORY_INTERFACE_TYPE
)
4535 /* We have a category. */
4537 = IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
4538 char *class_super_name
4539 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
));
4540 string
= (char *) alloca (strlen (preamble
)
4541 + strlen (class_name
)
4542 + strlen (class_super_name
)
4544 sprintf (string
, "%s_%s_%s", preamble
, class_name
, class_super_name
);
4546 else if (TREE_CODE (ctxt
) == PROTOCOL_INTERFACE_TYPE
)
4548 char *protocol_name
= IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt
));
4550 = (char *) alloca (strlen (preamble
) + strlen (protocol_name
) + 3);
4551 sprintf (string
, "%s_%s", preamble
, protocol_name
);
4553 return get_identifier (string
);
4557 is_objc_type_qualifier (node
)
4560 return (TREE_CODE (node
) == IDENTIFIER_NODE
4561 && (node
== ridpointers
[(int) RID_CONST
]
4562 || node
== ridpointers
[(int) RID_VOLATILE
]
4563 || node
== ridpointers
[(int) RID_IN
]
4564 || node
== ridpointers
[(int) RID_OUT
]
4565 || node
== ridpointers
[(int) RID_INOUT
]
4566 || node
== ridpointers
[(int) RID_BYCOPY
]
4567 || node
== ridpointers
[(int) RID_ONEWAY
]));
4570 /* If type is empty or only type qualifiers are present, add default
4571 type of id (otherwise grokdeclarator will default to int). */
4574 adjust_type_for_id_default (type
)
4577 tree declspecs
, chain
;
4580 return build_tree_list (build_tree_list (NULL_TREE
, objc_object_reference
),
4581 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4583 declspecs
= TREE_PURPOSE (type
);
4585 /* Determine if a typespec is present. */
4586 for (chain
= declspecs
;
4588 chain
= TREE_CHAIN (chain
))
4590 if (!is_objc_type_qualifier (TREE_VALUE (chain
)))
4594 return build_tree_list (tree_cons (NULL_TREE
, objc_object_reference
,
4596 build1 (INDIRECT_REF
, NULL_TREE
, NULL_TREE
));
4601 selector ':' '(' typename ')' identifier
4604 Transform an Objective-C keyword argument into
4605 the C equivalent parameter declarator.
4607 In: key_name, an "identifier_node" (optional).
4608 arg_type, a "tree_list" (optional).
4609 arg_name, an "identifier_node".
4611 Note: It would be really nice to strongly type the preceding
4612 arguments in the function prototype; however, then I
4613 could not use the "accessor" macros defined in "tree.h".
4615 Out: an instance of "keyword_decl". */
4618 build_keyword_decl (key_name
, arg_type
, arg_name
)
4625 /* If no type is specified, default to "id". */
4626 arg_type
= adjust_type_for_id_default (arg_type
);
4628 keyword_decl
= make_node (KEYWORD_DECL
);
4630 TREE_TYPE (keyword_decl
) = arg_type
;
4631 KEYWORD_ARG_NAME (keyword_decl
) = arg_name
;
4632 KEYWORD_KEY_NAME (keyword_decl
) = key_name
;
4634 return keyword_decl
;
4637 /* Given a chain of keyword_decl's, synthesize the full keyword selector. */
4640 build_keyword_selector (selector
)
4644 tree key_chain
, key_name
;
4647 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4649 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4650 key_name
= KEYWORD_KEY_NAME (key_chain
);
4651 else if (TREE_CODE (selector
) == TREE_LIST
)
4652 key_name
= TREE_PURPOSE (key_chain
);
4655 len
+= IDENTIFIER_LENGTH (key_name
) + 1;
4657 /* Just a ':' arg. */
4661 buf
= (char *)alloca (len
+ 1);
4662 bzero (buf
, len
+ 1);
4664 for (key_chain
= selector
; key_chain
; key_chain
= TREE_CHAIN (key_chain
))
4666 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4667 key_name
= KEYWORD_KEY_NAME (key_chain
);
4668 else if (TREE_CODE (selector
) == TREE_LIST
)
4669 key_name
= TREE_PURPOSE (key_chain
);
4672 strcat (buf
, IDENTIFIER_POINTER (key_name
));
4676 return get_identifier (buf
);
4679 /* Used for declarations and definitions. */
4682 build_method_decl (code
, ret_type
, selector
, add_args
)
4683 enum tree_code code
;
4690 /* If no type is specified, default to "id". */
4691 ret_type
= adjust_type_for_id_default (ret_type
);
4693 method_decl
= make_node (code
);
4694 TREE_TYPE (method_decl
) = ret_type
;
4696 /* If we have a keyword selector, create an identifier_node that
4697 represents the full selector name (`:' included)... */
4698 if (TREE_CODE (selector
) == KEYWORD_DECL
)
4700 METHOD_SEL_NAME (method_decl
) = build_keyword_selector (selector
);
4701 METHOD_SEL_ARGS (method_decl
) = selector
;
4702 METHOD_ADD_ARGS (method_decl
) = add_args
;
4706 METHOD_SEL_NAME (method_decl
) = selector
;
4707 METHOD_SEL_ARGS (method_decl
) = NULL_TREE
;
4708 METHOD_ADD_ARGS (method_decl
) = NULL_TREE
;
4714 #define METHOD_DEF 0
4715 #define METHOD_REF 1
4717 /* Used by `build_message_expr' and `comp_method_types'. Return an
4718 argument list for method METH. CONTEXT is either METHOD_DEF or
4719 METHOD_REF, saying whether we are trying to define a method or call
4720 one. SUPERFLAG says this is for a send to super; this makes a
4721 difference for the NeXT calling sequence in which the lookup and
4722 the method call are done together. */
4725 get_arg_type_list (meth
, context
, superflag
)
4732 /* Receiver type. */
4733 if (flag_next_runtime
&& superflag
)
4734 arglist
= build_tree_list (NULL_TREE
, super_type
);
4735 else if (context
== METHOD_DEF
)
4736 arglist
= build_tree_list (NULL_TREE
, TREE_TYPE (self_decl
));
4738 arglist
= build_tree_list (NULL_TREE
, id_type
);
4740 /* Selector type - will eventually change to `int'. */
4741 chainon (arglist
, build_tree_list (NULL_TREE
, selector_type
));
4743 /* Build a list of argument types. */
4744 for (akey
= METHOD_SEL_ARGS (meth
); akey
; akey
= TREE_CHAIN (akey
))
4746 tree arg_decl
= groktypename_in_parm_context (TREE_TYPE (akey
));
4747 chainon (arglist
, build_tree_list (NULL_TREE
, TREE_TYPE (arg_decl
)));
4750 if (METHOD_ADD_ARGS (meth
) == (tree
)1)
4751 /* We have a `, ...' immediately following the selector,
4752 finalize the arglist...simulate get_parm_info (0). */
4754 else if (METHOD_ADD_ARGS (meth
))
4756 /* we have a variable length selector */
4757 tree add_arg_list
= TREE_CHAIN (METHOD_ADD_ARGS (meth
));
4758 chainon (arglist
, add_arg_list
);
4761 /* finalize the arglist...simulate get_parm_info (1) */
4762 chainon (arglist
, build_tree_list (NULL_TREE
, void_type_node
));
4768 check_duplicates (hsh
)
4771 tree meth
= NULL_TREE
;
4779 /* We have two methods with the same name and different types. */
4781 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
) ? '-' : '+';
4783 warning ("multiple declarations for method `%s'",
4784 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
4786 warn_with_method ("using", type
, meth
);
4787 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
4788 warn_with_method ("also found", type
, loop
->value
);
4794 /* If RECEIVER is a class reference, return the identifier node for the
4795 referenced class. RECEIVER is created by get_class_reference, so we
4796 check the exact form created depending on which runtimes are used. */
4799 receiver_is_class_object (receiver
)
4802 tree chain
, exp
, arg
;
4803 if (flag_next_runtime
)
4805 /* The receiver is a variable created by build_class_reference_decl. */
4806 if (TREE_CODE (receiver
) == VAR_DECL
4807 && TREE_TYPE (receiver
) == objc_class_type
)
4808 /* Look up the identifier. */
4809 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
4810 if (TREE_PURPOSE (chain
) == receiver
)
4811 return TREE_VALUE (chain
);
4815 /* The receiver is a function call that returns an id. Check if
4816 it is a call to objc_getClass, if so, pick up the class name. */
4817 if ((exp
= TREE_OPERAND (receiver
, 0))
4818 && TREE_CODE (exp
) == ADDR_EXPR
4819 && (exp
= TREE_OPERAND (exp
, 0))
4820 && TREE_CODE (exp
) == FUNCTION_DECL
4821 && exp
== objc_get_class_decl
4822 /* we have a call to objc_getClass! */
4823 && (arg
= TREE_OPERAND (receiver
, 1))
4824 && TREE_CODE (arg
) == TREE_LIST
4825 && (arg
= TREE_VALUE (arg
)))
4828 if (TREE_CODE (arg
) == ADDR_EXPR
4829 && (arg
= TREE_OPERAND (arg
, 0))
4830 && TREE_CODE (arg
) == STRING_CST
)
4831 /* Finally, we have the class name. */
4832 return get_identifier (TREE_STRING_POINTER (arg
));
4838 /* If we are currently building a message expr, this holds
4839 the identifier of the selector of the message. This is
4840 used when printing warnings about argument mismatches. */
4842 static tree building_objc_message_expr
= 0;
4845 maybe_building_objc_message_expr ()
4847 return building_objc_message_expr
;
4850 /* Construct an expression for sending a message.
4851 MESS has the object to send to in TREE_PURPOSE
4852 and the argument list (including selector) in TREE_VALUE.
4854 (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...);
4855 (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */
4858 build_message_expr (mess
)
4861 tree receiver
= TREE_PURPOSE (mess
);
4862 tree selector
, self_object
;
4863 tree rtype
, sel_name
;
4864 tree args
= TREE_VALUE (mess
);
4865 tree method_params
= NULL_TREE
;
4866 tree method_prototype
= NULL_TREE
;
4868 int statically_typed
= 0, statically_allocated
= 0;
4869 tree class_ident
= 0;
4871 /* 1 if this is sending to the superclass. */
4874 if (!doing_objc_thang
)
4877 if (TREE_CODE (receiver
) == ERROR_MARK
)
4878 return error_mark_node
;
4880 /* Determine receiver type. */
4881 rtype
= TREE_TYPE (receiver
);
4882 super
= IS_SUPER (rtype
);
4886 if (TREE_STATIC_TEMPLATE (rtype
))
4887 statically_allocated
= 1;
4888 else if (TREE_CODE (rtype
) == POINTER_TYPE
4889 && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype
)))
4890 statically_typed
= 1;
4891 else if ((flag_next_runtime
4892 || (TREE_CODE (receiver
) == CALL_EXPR
&& IS_ID (rtype
)))
4893 && (class_ident
= receiver_is_class_object (receiver
)))
4895 else if (! IS_ID (rtype
)
4896 /* Allow any type that matches objc_class_type. */
4897 && ! comptypes (rtype
, objc_class_type
))
4899 bzero (errbuf
, BUFSIZE
);
4900 warning ("invalid receiver type `%s'",
4901 gen_declaration (rtype
, errbuf
));
4904 if (statically_allocated
)
4905 receiver
= build_unary_op (ADDR_EXPR
, receiver
, 0);
4907 /* Don't evaluate the receiver twice. */
4908 receiver
= save_expr (receiver
);
4909 self_object
= receiver
;
4912 /* If sending to `super', use current self as the object. */
4913 self_object
= self_decl
;
4915 /* Obtain the full selector name. */
4917 if (TREE_CODE (args
) == IDENTIFIER_NODE
)
4918 /* A unary selector. */
4920 else if (TREE_CODE (args
) == TREE_LIST
)
4921 sel_name
= build_keyword_selector (args
);
4923 /* Build the parameter list to give to the method. */
4925 method_params
= NULL_TREE
;
4926 if (TREE_CODE (args
) == TREE_LIST
)
4928 tree chain
= args
, prev
= NULL_TREE
;
4930 /* We have a keyword selector--check for comma expressions. */
4933 tree element
= TREE_VALUE (chain
);
4935 /* We have a comma expression, must collapse... */
4936 if (TREE_CODE (element
) == TREE_LIST
)
4939 TREE_CHAIN (prev
) = element
;
4944 chain
= TREE_CHAIN (chain
);
4946 method_params
= args
;
4949 /* Determine operation return type. */
4951 if (IS_SUPER (rtype
))
4955 if (CLASS_SUPER_NAME (implementation_template
))
4958 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
4960 if (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
)
4961 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4963 method_prototype
= lookup_class_method_static (iface
, sel_name
);
4965 if (iface
&& !method_prototype
)
4966 warning ("`%s' does not respond to `%s'",
4967 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template
)),
4968 IDENTIFIER_POINTER (sel_name
));
4972 error ("no super class declared in interface for `%s'",
4973 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
4974 return error_mark_node
;
4978 else if (statically_allocated
)
4980 tree ctype
= TREE_TYPE (rtype
);
4981 tree iface
= lookup_interface (TYPE_NAME (rtype
));
4984 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
4986 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
4988 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
4991 if (!method_prototype
)
4992 warning ("`%s' does not respond to `%s'",
4993 IDENTIFIER_POINTER (TYPE_NAME (rtype
)),
4994 IDENTIFIER_POINTER (sel_name
));
4996 else if (statically_typed
)
4998 tree ctype
= TREE_TYPE (rtype
);
5000 /* `self' is now statically_typed. All methods should be visible
5001 within the context of the implementation. */
5002 if (implementation_context
5003 && CLASS_NAME (implementation_context
) == TYPE_NAME (ctype
))
5006 = lookup_instance_method_static (implementation_template
,
5009 if (! method_prototype
&& TYPE_PROTOCOL_LIST (ctype
))
5011 = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype
),
5014 if (! method_prototype
5015 && implementation_template
!= implementation_context
)
5016 /* The method is not published in the interface. Check
5019 = lookup_method (CLASS_NST_METHODS (implementation_context
),
5026 if ((iface
= lookup_interface (TYPE_NAME (ctype
))))
5027 method_prototype
= lookup_instance_method_static (iface
, sel_name
);
5029 if (! method_prototype
)
5031 tree protocol_list
= TYPE_PROTOCOL_LIST (ctype
);
5034 = lookup_method_in_protocol_list (protocol_list
,
5039 if (!method_prototype
)
5040 warning ("`%s' does not respond to `%s'",
5041 IDENTIFIER_POINTER (TYPE_NAME (ctype
)),
5042 IDENTIFIER_POINTER (sel_name
));
5044 else if (class_ident
)
5046 if (implementation_context
5047 && CLASS_NAME (implementation_context
) == class_ident
)
5050 = lookup_class_method_static (implementation_template
, sel_name
);
5052 if (!method_prototype
5053 && implementation_template
!= implementation_context
)
5054 /* The method is not published in the interface. Check
5057 = lookup_method (CLASS_CLS_METHODS (implementation_context
),
5064 if ((iface
= lookup_interface (class_ident
)))
5065 method_prototype
= lookup_class_method_static (iface
, sel_name
);
5068 if (!method_prototype
)
5070 warning ("cannot find class (factory) method.");
5071 warning ("return type for `%s' defaults to id",
5072 IDENTIFIER_POINTER (sel_name
));
5075 else if (IS_PROTOCOL_QUALIFIED_ID (rtype
))
5077 /* An anonymous object that has been qualified with a protocol. */
5079 tree protocol_list
= TYPE_PROTOCOL_LIST (rtype
);
5081 method_prototype
= lookup_method_in_protocol_list (protocol_list
,
5084 if (!method_prototype
)
5088 warning ("method `%s' not implemented by protocol.",
5089 IDENTIFIER_POINTER (sel_name
));
5091 /* Try and find the method signature in the global pools. */
5093 if (!(hsh
= hash_lookup (nst_method_hash_list
, sel_name
)))
5094 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5096 if (!(method_prototype
= check_duplicates (hsh
)))
5097 warning ("return type defaults to id");
5104 /* We think we have an instance...loophole: extern id Object; */
5105 hsh
= hash_lookup (nst_method_hash_list
, sel_name
);
5107 /* For various loopholes, like sending messages to self in a
5109 hsh
= hash_lookup (cls_method_hash_list
, sel_name
);
5111 method_prototype
= check_duplicates (hsh
);
5112 if (!method_prototype
)
5114 warning ("cannot find method.");
5115 warning ("return type for `%s' defaults to id",
5116 IDENTIFIER_POINTER (sel_name
));
5120 /* Save the selector name for printing error messages. */
5121 building_objc_message_expr
= sel_name
;
5123 /* Build the parameters list for looking up the method.
5124 These are the object itself and the selector. */
5126 if (flag_typed_selectors
)
5127 selector
= build_typed_selector_reference (sel_name
, method_prototype
);
5129 selector
= build_selector_reference (sel_name
);
5131 retval
= build_objc_method_call (super
, method_prototype
,
5132 receiver
, self_object
,
5133 selector
, method_params
);
5135 building_objc_message_expr
= 0;
5140 /* Build a tree expression to send OBJECT the operation SELECTOR,
5141 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
5142 assuming the method has prototype METHOD_PROTOTYPE.
5143 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
5144 Use METHOD_PARAMS as list of args to pass to the method.
5145 If SUPER_FLAG is nonzero, we look up the superclass's method. */
5148 build_objc_method_call (super_flag
, method_prototype
, lookup_object
, object
,
5149 selector
, method_params
)
5151 tree method_prototype
, lookup_object
, object
, selector
, method_params
;
5153 tree sender
= (super_flag
? umsg_super_decl
: umsg_decl
);
5154 tree rcv_p
= (super_flag
5155 ? build_pointer_type (xref_tag (RECORD_TYPE
,
5156 get_identifier (TAG_SUPER
)))
5159 if (flag_next_runtime
)
5161 if (! method_prototype
)
5163 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5164 tree_cons (NULL_TREE
, selector
,
5166 assemble_external (sender
);
5167 return build_function_call (sender
, method_params
);
5171 /* This is a real kludge, but it is used only for the Next.
5172 Clobber the data type of SENDER temporarily to accept
5173 all the arguments for this operation, and to return
5174 whatever this operation returns. */
5175 tree arglist
= NULL_TREE
;
5178 /* Save the proper contents of SENDER's data type. */
5179 tree savarg
= TYPE_ARG_TYPES (TREE_TYPE (sender
));
5180 tree savret
= TREE_TYPE (TREE_TYPE (sender
));
5182 /* Install this method's argument types. */
5183 arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5185 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = arglist
;
5187 /* Install this method's return type. */
5188 TREE_TYPE (TREE_TYPE (sender
))
5189 = groktypename (TREE_TYPE (method_prototype
));
5191 /* Call SENDER with all the parameters. This will do type
5192 checking using the arg types for this method. */
5193 method_params
= tree_cons (NULL_TREE
, lookup_object
,
5194 tree_cons (NULL_TREE
, selector
,
5196 assemble_external (sender
);
5197 retval
= build_function_call (sender
, method_params
);
5199 /* Restore SENDER's return/argument types. */
5200 TYPE_ARG_TYPES (TREE_TYPE (sender
)) = savarg
;
5201 TREE_TYPE (TREE_TYPE (sender
)) = savret
;
5207 /* This is the portable way.
5208 First call the lookup function to get a pointer to the method,
5209 then cast the pointer, then call it with the method arguments. */
5212 /* Avoid trouble since we may evaluate each of these twice. */
5213 object
= save_expr (object
);
5214 selector
= save_expr (selector
);
5216 lookup_object
= build_c_cast (rcv_p
, lookup_object
);
5218 assemble_external (sender
);
5220 = build_function_call (sender
,
5221 tree_cons (NULL_TREE
, lookup_object
,
5222 tree_cons (NULL_TREE
, selector
,
5225 /* If we have a method prototype, construct the data type this
5226 method needs, and cast what we got from SENDER into a pointer
5228 if (method_prototype
)
5230 tree arglist
= get_arg_type_list (method_prototype
, METHOD_REF
,
5232 tree valtype
= groktypename (TREE_TYPE (method_prototype
));
5233 tree fake_function_type
= build_function_type (valtype
, arglist
);
5234 TREE_TYPE (method
) = build_pointer_type (fake_function_type
);
5238 = build_pointer_type (build_function_type (ptr_type_node
, NULL_TREE
));
5240 /* Pass the object to the method. */
5241 assemble_external (method
);
5242 return build_function_call (method
,
5243 tree_cons (NULL_TREE
, object
,
5244 tree_cons (NULL_TREE
, selector
,
5250 build_protocol_reference (p
)
5253 tree decl
, ident
, ptype
;
5255 push_obstacks_nochange ();
5256 end_temporary_allocation ();
5258 /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
5260 ident
= synth_id_with_class_suffix ("_OBJC_PROTOCOL", p
);
5262 = groktypename (build_tree_list (build_tree_list (NULL_TREE
,
5263 objc_protocol_template
),
5266 if (IDENTIFIER_GLOBAL_VALUE (ident
))
5267 decl
= IDENTIFIER_GLOBAL_VALUE (ident
); /* Set by pushdecl. */
5270 decl
= build_decl (VAR_DECL
, ident
, ptype
);
5271 DECL_EXTERNAL (decl
) = 1;
5272 TREE_PUBLIC (decl
) = 1;
5273 TREE_USED (decl
) = 1;
5274 DECL_ARTIFICIAL (decl
) = 1;
5276 make_decl_rtl (decl
, 0, 1);
5277 pushdecl_top_level (decl
);
5280 PROTOCOL_FORWARD_DECL (p
) = decl
;
5285 build_protocol_expr (protoname
)
5291 if (!doing_objc_thang
)
5294 p
= lookup_protocol (protoname
);
5298 error ("Cannot find protocol declaration for `%s'",
5299 IDENTIFIER_POINTER (protoname
));
5300 return error_mark_node
;
5303 if (!PROTOCOL_FORWARD_DECL (p
))
5304 build_protocol_reference (p
);
5306 expr
= build_unary_op (ADDR_EXPR
, PROTOCOL_FORWARD_DECL (p
), 0);
5308 TREE_TYPE (expr
) = protocol_type
;
5314 build_selector_expr (selnamelist
)
5319 if (!doing_objc_thang
)
5322 /* Obtain the full selector name. */
5323 if (TREE_CODE (selnamelist
) == IDENTIFIER_NODE
)
5324 /* A unary selector. */
5325 selname
= selnamelist
;
5326 else if (TREE_CODE (selnamelist
) == TREE_LIST
)
5327 selname
= build_keyword_selector (selnamelist
);
5329 if (flag_typed_selectors
)
5330 return build_typed_selector_reference (selname
, 0);
5332 return build_selector_reference (selname
);
5336 build_encode_expr (type
)
5342 if (!doing_objc_thang
)
5345 encode_type (type
, obstack_object_size (&util_obstack
),
5346 OBJC_ENCODE_INLINE_DEFS
);
5347 obstack_1grow (&util_obstack
, 0); /* null terminate string */
5348 string
= obstack_finish (&util_obstack
);
5350 /* Synthesize a string that represents the encoded struct/union. */
5351 result
= my_build_string (strlen (string
) + 1, string
);
5352 obstack_free (&util_obstack
, util_firstobj
);
5357 build_ivar_reference (id
)
5360 if (TREE_CODE (method_context
) == CLASS_METHOD_DECL
)
5362 /* Historically, a class method that produced objects (factory
5363 method) would assign `self' to the instance that it
5364 allocated. This would effectively turn the class method into
5365 an instance method. Following this assignment, the instance
5366 variables could be accessed. That practice, while safe,
5367 violates the simple rule that a class method should not refer
5368 to an instance variable. It's better to catch the cases
5369 where this is done unknowingly than to support the above
5371 warning ("instance variable `%s' accessed in class method",
5372 IDENTIFIER_POINTER (id
));
5373 TREE_TYPE (self_decl
) = instance_type
; /* cast */
5376 return build_component_ref (build_indirect_ref (self_decl
, "->"), id
);
5379 #define HASH_ALLOC_LIST_SIZE 170
5380 #define ATTR_ALLOC_LIST_SIZE 170
5381 #define SIZEHASHTABLE 257
5384 #define HASHFUNCTION(key) ((HOST_WIDE_INT) key & 0x7fffffff)
5389 nst_method_hash_list
= (hash
*)xmalloc (SIZEHASHTABLE
* sizeof (hash
));
5390 cls_method_hash_list
= (hash
*)xmalloc (SIZEHASHTABLE
* sizeof (hash
));
5392 if (!nst_method_hash_list
|| !cls_method_hash_list
)
5393 perror ("unable to allocate space in objc-tree.c");
5398 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
5400 nst_method_hash_list
[i
] = 0;
5401 cls_method_hash_list
[i
] = 0;
5407 hash_enter (hashlist
, method
)
5411 static hash hash_alloc_list
= 0;
5412 static int hash_alloc_index
= 0;
5414 int slot
= HASHFUNCTION (METHOD_SEL_NAME (method
)) % SIZEHASHTABLE
;
5416 if (! hash_alloc_list
|| hash_alloc_index
>= HASH_ALLOC_LIST_SIZE
)
5418 hash_alloc_index
= 0;
5419 hash_alloc_list
= (hash
) xmalloc (sizeof (struct hashed_entry
)
5420 * HASH_ALLOC_LIST_SIZE
);
5421 if (! hash_alloc_list
)
5422 perror ("unable to allocate in objc-tree.c");
5424 obj
= &hash_alloc_list
[hash_alloc_index
++];
5426 obj
->next
= hashlist
[slot
];
5429 hashlist
[slot
] = obj
; /* append to front */
5433 hash_lookup (hashlist
, sel_name
)
5439 target
= hashlist
[HASHFUNCTION (sel_name
) % SIZEHASHTABLE
];
5443 if (sel_name
== METHOD_SEL_NAME (target
->key
))
5446 target
= target
->next
;
5452 hash_add_attr (entry
, value
)
5456 static attr attr_alloc_list
= 0;
5457 static int attr_alloc_index
= 0;
5460 if (! attr_alloc_list
|| attr_alloc_index
>= ATTR_ALLOC_LIST_SIZE
)
5462 attr_alloc_index
= 0;
5463 attr_alloc_list
= (attr
) xmalloc (sizeof (struct hashed_attribute
)
5464 * ATTR_ALLOC_LIST_SIZE
);
5465 if (! attr_alloc_list
)
5466 perror ("unable to allocate in objc-tree.c");
5468 obj
= &attr_alloc_list
[attr_alloc_index
++];
5469 obj
->next
= entry
->list
;
5472 entry
->list
= obj
; /* append to front */
5476 lookup_method (mchain
, method
)
5482 if (TREE_CODE (method
) == IDENTIFIER_NODE
)
5485 key
= METHOD_SEL_NAME (method
);
5489 if (METHOD_SEL_NAME (mchain
) == key
)
5491 mchain
= TREE_CHAIN (mchain
);
5497 lookup_instance_method_static (interface
, ident
)
5501 tree inter
= interface
;
5502 tree chain
= CLASS_NST_METHODS (inter
);
5503 tree meth
= NULL_TREE
;
5507 if ((meth
= lookup_method (chain
, ident
)))
5510 if (CLASS_CATEGORY_LIST (inter
))
5512 tree category
= CLASS_CATEGORY_LIST (inter
);
5513 chain
= CLASS_NST_METHODS (category
);
5517 if ((meth
= lookup_method (chain
, ident
)))
5520 /* Check for instance methods in protocols in categories. */
5521 if (CLASS_PROTOCOL_LIST (category
))
5523 if ((meth
= (lookup_method_in_protocol_list
5524 (CLASS_PROTOCOL_LIST (category
), ident
, 0))))
5528 if ((category
= CLASS_CATEGORY_LIST (category
)))
5529 chain
= CLASS_NST_METHODS (category
);
5534 if (CLASS_PROTOCOL_LIST (inter
))
5536 if ((meth
= (lookup_method_in_protocol_list
5537 (CLASS_PROTOCOL_LIST (inter
), ident
, 0))))
5541 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5542 chain
= CLASS_NST_METHODS (inter
);
5550 lookup_class_method_static (interface
, ident
)
5554 tree inter
= interface
;
5555 tree chain
= CLASS_CLS_METHODS (inter
);
5556 tree meth
= NULL_TREE
;
5557 tree root_inter
= NULL_TREE
;
5561 if ((meth
= lookup_method (chain
, ident
)))
5564 if (CLASS_CATEGORY_LIST (inter
))
5566 tree category
= CLASS_CATEGORY_LIST (inter
);
5567 chain
= CLASS_CLS_METHODS (category
);
5571 if ((meth
= lookup_method (chain
, ident
)))
5574 /* Check for class methods in protocols in categories. */
5575 if (CLASS_PROTOCOL_LIST (category
))
5577 if ((meth
= (lookup_method_in_protocol_list
5578 (CLASS_PROTOCOL_LIST (category
), ident
, 1))))
5582 if ((category
= CLASS_CATEGORY_LIST (category
)))
5583 chain
= CLASS_CLS_METHODS (category
);
5588 /* Check for class methods in protocols. */
5589 if (CLASS_PROTOCOL_LIST (inter
))
5591 if ((meth
= (lookup_method_in_protocol_list
5592 (CLASS_PROTOCOL_LIST (inter
), ident
, 1))))
5597 if ((inter
= lookup_interface (CLASS_SUPER_NAME (inter
))))
5598 chain
= CLASS_CLS_METHODS (inter
);
5602 /* Simulate wrap around. */
5603 return lookup_instance_method_static (root_inter
, ident
);
5607 add_class_method (class, method
)
5614 /* We will have allocated the method parameter declarations on the
5615 maybepermanent_obstack. Need to make sure they stick around! */
5618 if (!(mth
= lookup_method (CLASS_CLS_METHODS (class), method
)))
5620 /* put method on list in reverse order */
5621 TREE_CHAIN (method
) = CLASS_CLS_METHODS (class);
5622 CLASS_CLS_METHODS (class) = method
;
5626 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5627 error ("duplicate definition of class method `%s'.",
5628 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5631 /* Check types; if different, complain. */
5632 if (!comp_proto_with_proto (method
, mth
))
5633 error ("duplicate declaration of class method `%s'.",
5634 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5638 if (!(hsh
= hash_lookup (cls_method_hash_list
, METHOD_SEL_NAME (method
))))
5640 /* Install on a global chain. */
5641 hash_enter (cls_method_hash_list
, method
);
5645 /* Check types; if different, add to a list. */
5646 if (!comp_proto_with_proto (method
, hsh
->key
))
5647 hash_add_attr (hsh
, method
);
5653 add_instance_method (class, method
)
5660 /* We will have allocated the method parameter declarations on the
5661 maybepermanent_obstack. Need to make sure they stick around! */
5664 if (!(mth
= lookup_method (CLASS_NST_METHODS (class), method
)))
5666 /* Put method on list in reverse order. */
5667 TREE_CHAIN (method
) = CLASS_NST_METHODS (class);
5668 CLASS_NST_METHODS (class) = method
;
5672 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
5673 error ("duplicate definition of instance method `%s'.",
5674 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5677 /* Check types; if different, complain. */
5678 if (!comp_proto_with_proto (method
, mth
))
5679 error ("duplicate declaration of instance method `%s'.",
5680 IDENTIFIER_POINTER (METHOD_SEL_NAME (mth
)));
5684 if (!(hsh
= hash_lookup (nst_method_hash_list
, METHOD_SEL_NAME (method
))))
5686 /* Install on a global chain. */
5687 hash_enter (nst_method_hash_list
, method
);
5691 /* Check types; if different, add to a list. */
5692 if (!comp_proto_with_proto (method
, hsh
->key
))
5693 hash_add_attr (hsh
, method
);
5702 /* Put interfaces on list in reverse order. */
5703 TREE_CHAIN (class) = interface_chain
;
5704 interface_chain
= class;
5705 return interface_chain
;
5709 add_category (class, category
)
5713 /* Put categories on list in reverse order. */
5714 tree cat
= CLASS_CATEGORY_LIST (class);
5718 if (CLASS_SUPER_NAME (cat
) == CLASS_SUPER_NAME (category
))
5719 warning ("duplicate interface declaration for category `%s(%s)'",
5720 IDENTIFIER_POINTER (CLASS_NAME (class)),
5721 IDENTIFIER_POINTER (CLASS_SUPER_NAME (category
)));
5722 cat
= CLASS_CATEGORY_LIST (cat
);
5725 CLASS_CATEGORY_LIST (category
) = CLASS_CATEGORY_LIST (class);
5726 CLASS_CATEGORY_LIST (class) = category
;
5729 /* Called after parsing each instance variable declaration. Necessary to
5730 preserve typedefs and implement public/private...
5732 PUBLIC is 1 for public, 0 for protected, and 2 for private. */
5735 add_instance_variable (class, public, declarator
, declspecs
, width
)
5742 tree field_decl
, raw_decl
;
5744 raw_decl
= build_tree_list (declspecs
, declarator
);
5746 if (CLASS_RAW_IVARS (class))
5747 chainon (CLASS_RAW_IVARS (class), raw_decl
);
5749 CLASS_RAW_IVARS (class) = raw_decl
;
5751 field_decl
= grokfield (input_filename
, lineno
,
5752 declarator
, declspecs
, width
);
5754 /* Overload the public attribute, it is not used for FIELD_DECLs. */
5758 TREE_PUBLIC (field_decl
) = 0;
5759 TREE_PRIVATE (field_decl
) = 0;
5760 TREE_PROTECTED (field_decl
) = 1;
5764 TREE_PUBLIC (field_decl
) = 1;
5765 TREE_PRIVATE (field_decl
) = 0;
5766 TREE_PROTECTED (field_decl
) = 0;
5770 TREE_PUBLIC (field_decl
) = 0;
5771 TREE_PRIVATE (field_decl
) = 1;
5772 TREE_PROTECTED (field_decl
) = 0;
5777 if (CLASS_IVARS (class))
5778 chainon (CLASS_IVARS (class), field_decl
);
5780 CLASS_IVARS (class) = field_decl
;
5786 is_ivar (decl_chain
, ident
)
5790 for ( ; decl_chain
; decl_chain
= TREE_CHAIN (decl_chain
))
5791 if (DECL_NAME (decl_chain
) == ident
)
5796 /* True if the ivar is private and we are not in its implementation. */
5802 if (TREE_PRIVATE (decl
)
5803 && ! is_ivar (CLASS_IVARS (implementation_template
), DECL_NAME (decl
)))
5805 error ("instance variable `%s' is declared private",
5806 IDENTIFIER_POINTER (DECL_NAME (decl
)));
5813 /* We have an instance variable reference;, check to see if it is public. */
5816 is_public (expr
, identifier
)
5820 tree basetype
= TREE_TYPE (expr
);
5821 enum tree_code code
= TREE_CODE (basetype
);
5824 if (code
== RECORD_TYPE
)
5826 if (TREE_STATIC_TEMPLATE (basetype
))
5828 if (!lookup_interface (TYPE_NAME (basetype
)))
5830 error ("Cannot find interface declaration for `%s'",
5831 IDENTIFIER_POINTER (TYPE_NAME (basetype
)));
5835 if ((decl
= is_ivar (TYPE_FIELDS (basetype
), identifier
)))
5837 if (TREE_PUBLIC (decl
))
5840 /* Important difference between the Stepstone translator:
5841 all instance variables should be public within the context
5842 of the implementation. */
5843 if (implementation_context
5844 && (((TREE_CODE (implementation_context
)
5845 == CLASS_IMPLEMENTATION_TYPE
)
5846 || (TREE_CODE (implementation_context
)
5847 == CATEGORY_IMPLEMENTATION_TYPE
))
5848 && (CLASS_NAME (implementation_context
)
5849 == TYPE_NAME (basetype
))))
5850 return ! is_private (decl
);
5852 error ("instance variable `%s' is declared %s",
5853 IDENTIFIER_POINTER (identifier
),
5854 TREE_PRIVATE (decl
) ? "private" : "protected");
5859 else if (implementation_context
&& (basetype
== objc_object_reference
))
5861 TREE_TYPE (expr
) = uprivate_record
;
5862 warning ("static access to object of type `id'");
5869 /* Implement @defs (<classname>) within struct bodies. */
5872 get_class_ivars (interface
)
5875 if (!doing_objc_thang
)
5878 return build_ivar_chain (interface
, 1);
5881 /* Make sure all entries in CHAIN are also in LIST. */
5884 check_methods (chain
, list
, mtype
)
5893 if (!lookup_method (list
, chain
))
5897 if (TREE_CODE (implementation_context
)
5898 == CLASS_IMPLEMENTATION_TYPE
)
5899 warning ("incomplete implementation of class `%s'",
5900 IDENTIFIER_POINTER (CLASS_NAME (implementation_context
)));
5901 else if (TREE_CODE (implementation_context
)
5902 == CATEGORY_IMPLEMENTATION_TYPE
)
5903 warning ("incomplete implementation of category `%s'",
5904 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
5908 warning ("method definition for `%c%s' not found",
5909 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
5912 chain
= TREE_CHAIN (chain
);
5919 conforms_to_protocol (class, protocol
)
5925 tree p
= CLASS_PROTOCOL_LIST (class);
5927 while (p
&& TREE_VALUE (p
) != TREE_VALUE (protocol
))
5932 tree super
= (CLASS_SUPER_NAME (class)
5933 ? lookup_interface (CLASS_SUPER_NAME (class))
5935 int tmp
= super
? conforms_to_protocol (super
, protocol
) : 0;
5940 protocol
= TREE_CHAIN (protocol
);
5946 /* Make sure all methods in CHAIN are accessible as MTYPE methods in
5947 CONTEXT. This is one of two mechanisms to check protocol integrity. */
5950 check_methods_accessible (chain
, context
, mtype
)
5957 tree base_context
= context
;
5961 context
= base_context
;
5965 list
= CLASS_CLS_METHODS (context
);
5967 list
= CLASS_NST_METHODS (context
);
5969 if (lookup_method (list
, chain
))
5972 else if (TREE_CODE (context
) == CLASS_IMPLEMENTATION_TYPE
5973 || TREE_CODE (context
) == CLASS_INTERFACE_TYPE
)
5974 context
= (CLASS_SUPER_NAME (context
)
5975 ? lookup_interface (CLASS_SUPER_NAME (context
))
5978 else if (TREE_CODE (context
) == CATEGORY_IMPLEMENTATION_TYPE
5979 || TREE_CODE (context
) == CATEGORY_INTERFACE_TYPE
)
5980 context
= (CLASS_NAME (context
)
5981 ? lookup_interface (CLASS_NAME (context
))
5987 if (context
== NULL_TREE
)
5991 if (TREE_CODE (implementation_context
)
5992 == CLASS_IMPLEMENTATION_TYPE
)
5993 warning ("incomplete implementation of class `%s'",
5995 (CLASS_NAME (implementation_context
)));
5996 else if (TREE_CODE (implementation_context
)
5997 == CATEGORY_IMPLEMENTATION_TYPE
)
5998 warning ("incomplete implementation of category `%s'",
6000 (CLASS_SUPER_NAME (implementation_context
)));
6003 warning ("method definition for `%c%s' not found",
6004 mtype
, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain
)));
6007 chain
= TREE_CHAIN (chain
); /* next method... */
6013 check_protocols (proto_list
, type
, name
)
6018 for ( ; proto_list
; proto_list
= TREE_CHAIN (proto_list
))
6020 tree p
= TREE_VALUE (proto_list
);
6022 if (TREE_CODE (p
) == PROTOCOL_INTERFACE_TYPE
)
6026 /* Ensure that all protocols have bodies. */
6027 if (flag_warn_protocol
) {
6028 f1
= check_methods (PROTOCOL_CLS_METHODS (p
),
6029 CLASS_CLS_METHODS (implementation_context
),
6031 f2
= check_methods (PROTOCOL_NST_METHODS (p
),
6032 CLASS_NST_METHODS (implementation_context
),
6035 f1
= check_methods_accessible (PROTOCOL_CLS_METHODS (p
),
6036 implementation_context
,
6038 f2
= check_methods_accessible (PROTOCOL_NST_METHODS (p
),
6039 implementation_context
,
6044 warning ("%s `%s' does not fully implement the `%s' protocol",
6045 type
, name
, IDENTIFIER_POINTER (PROTOCOL_NAME (p
)));
6050 ; /* An identifier if we could not find a protocol. */
6053 /* Check protocols recursively. */
6054 if (PROTOCOL_LIST (p
))
6057 = lookup_interface (CLASS_SUPER_NAME (implementation_template
));
6058 if (! conforms_to_protocol (super_class
, PROTOCOL_LIST (p
)))
6059 check_protocols (PROTOCOL_LIST (p
), type
, name
);
6064 /* Make sure that the class CLASS_NAME is defined
6065 CODE says which kind of thing CLASS_NAME ought to be.
6066 It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE,
6067 CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE.
6069 If CODE is CLASS_INTERFACE_TYPE, we also do a push_obstacks_nochange
6070 whose matching pop is in continue_class. */
6073 start_class (code
, class_name
, super_name
, protocol_list
)
6074 enum tree_code code
;
6081 if (code
== CLASS_INTERFACE_TYPE
)
6083 push_obstacks_nochange ();
6084 end_temporary_allocation ();
6087 if (!doing_objc_thang
)
6090 class = make_node (code
);
6091 TYPE_BINFO (class) = make_tree_vec (5);
6093 CLASS_NAME (class) = class_name
;
6094 CLASS_SUPER_NAME (class) = super_name
;
6095 CLASS_CLS_METHODS (class) = NULL_TREE
;
6097 if (! is_class_name (class_name
) && (decl
= lookup_name (class_name
)))
6099 error ("`%s' redeclared as different kind of symbol",
6100 IDENTIFIER_POINTER (class_name
));
6101 error_with_decl (decl
, "previous declaration of `%s'");
6104 if (code
== CLASS_IMPLEMENTATION_TYPE
)
6107 static tree implemented_classes
= 0;
6108 tree chain
= implemented_classes
;
6109 for (chain
= implemented_classes
; chain
; chain
= TREE_CHAIN (chain
))
6110 if (TREE_VALUE (chain
) == class_name
)
6112 error ("reimplementation of class `%s'",
6113 IDENTIFIER_POINTER (class_name
));
6114 return error_mark_node
;
6116 implemented_classes
= perm_tree_cons (NULL_TREE
, class_name
,
6117 implemented_classes
);
6120 /* Pre-build the following entities - for speed/convenience. */
6122 self_id
= get_identifier ("self");
6124 ucmd_id
= get_identifier ("_cmd");
6127 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6128 if (!objc_super_template
)
6129 objc_super_template
= build_super_template ();
6131 /* Reset for multiple classes per file. */
6134 implementation_context
= class;
6136 /* Lookup the interface for this implementation. */
6138 if (!(implementation_template
= lookup_interface (class_name
)))
6140 warning ("Cannot find interface declaration for `%s'",
6141 IDENTIFIER_POINTER (class_name
));
6142 add_class (implementation_template
= implementation_context
);
6145 /* If a super class has been specified in the implementation,
6146 insure it conforms to the one specified in the interface. */
6149 && (super_name
!= CLASS_SUPER_NAME (implementation_template
)))
6151 tree previous_name
= CLASS_SUPER_NAME (implementation_template
);
6152 char *name
= previous_name
? IDENTIFIER_POINTER (previous_name
) : "";
6153 error ("conflicting super class name `%s'",
6154 IDENTIFIER_POINTER (super_name
));
6155 error ("previous declaration of `%s'", name
);
6158 else if (! super_name
)
6160 CLASS_SUPER_NAME (implementation_context
)
6161 = CLASS_SUPER_NAME (implementation_template
);
6165 else if (code
== CLASS_INTERFACE_TYPE
)
6167 if (lookup_interface (class_name
))
6168 warning ("duplicate interface declaration for class `%s'",
6169 IDENTIFIER_POINTER (class_name
));
6174 CLASS_PROTOCOL_LIST (class)
6175 = lookup_and_install_protocols (protocol_list
);
6178 else if (code
== CATEGORY_INTERFACE_TYPE
)
6180 tree class_category_is_assoc_with
;
6182 /* For a category, class_name is really the name of the class that
6183 the following set of methods will be associated with. We must
6184 find the interface so that can derive the objects template. */
6186 if (!(class_category_is_assoc_with
= lookup_interface (class_name
)))
6188 error ("Cannot find interface declaration for `%s'",
6189 IDENTIFIER_POINTER (class_name
));
6190 exit (FATAL_EXIT_CODE
);
6193 add_category (class_category_is_assoc_with
, class);
6196 CLASS_PROTOCOL_LIST (class)
6197 = lookup_and_install_protocols (protocol_list
);
6200 else if (code
== CATEGORY_IMPLEMENTATION_TYPE
)
6202 /* Pre-build the following entities for speed/convenience. */
6204 self_id
= get_identifier ("self");
6206 ucmd_id
= get_identifier ("_cmd");
6209 = build_tree_list (get_identifier ("__unused__"), NULL_TREE
);
6210 if (!objc_super_template
)
6211 objc_super_template
= build_super_template ();
6213 /* Reset for multiple classes per file. */
6216 implementation_context
= class;
6218 /* For a category, class_name is really the name of the class that
6219 the following set of methods will be associated with. We must
6220 find the interface so that can derive the objects template. */
6222 if (!(implementation_template
= lookup_interface (class_name
)))
6224 error ("Cannot find interface declaration for `%s'",
6225 IDENTIFIER_POINTER (class_name
));
6226 exit (FATAL_EXIT_CODE
);
6233 continue_class (class)
6236 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
6237 || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6239 struct imp_entry
*imp_entry
;
6242 /* Check consistency of the instance variables. */
6244 if (CLASS_IVARS (class))
6245 check_ivars (implementation_template
, class);
6247 /* code generation */
6249 ivar_context
= build_private_template (implementation_template
);
6251 if (!objc_class_template
)
6252 build_class_template ();
6255 = (struct imp_entry
*) xmalloc (sizeof (struct imp_entry
))))
6256 perror ("unable to allocate in objc-tree.c");
6258 imp_entry
->next
= imp_list
;
6259 imp_entry
->imp_context
= class;
6260 imp_entry
->imp_template
= implementation_template
;
6262 synth_forward_declarations ();
6263 imp_entry
->class_decl
= UOBJC_CLASS_decl
;
6264 imp_entry
->meta_decl
= UOBJC_METACLASS_decl
;
6266 /* Append to front and increment count. */
6267 imp_list
= imp_entry
;
6268 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6273 return ivar_context
;
6276 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6278 tree record
= xref_tag (RECORD_TYPE
, CLASS_NAME (class));
6280 if (!TYPE_FIELDS (record
))
6282 finish_struct (record
, build_ivar_chain (class, 0), NULL_TREE
);
6283 CLASS_STATIC_TEMPLATE (class) = record
;
6285 /* Mark this record as a class template for static typing. */
6286 TREE_STATIC_TEMPLATE (record
) = 1;
6293 return error_mark_node
;
6296 /* This is called once we see the "@end" in an interface/implementation. */
6299 finish_class (class)
6302 if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE
)
6304 /* All code generation is done in finish_objc. */
6306 if (implementation_template
!= implementation_context
)
6308 /* Ensure that all method listed in the interface contain bodies. */
6309 check_methods (CLASS_CLS_METHODS (implementation_template
),
6310 CLASS_CLS_METHODS (implementation_context
), '+');
6311 check_methods (CLASS_NST_METHODS (implementation_template
),
6312 CLASS_NST_METHODS (implementation_context
), '-');
6314 if (CLASS_PROTOCOL_LIST (implementation_template
))
6315 check_protocols (CLASS_PROTOCOL_LIST (implementation_template
),
6317 IDENTIFIER_POINTER (CLASS_NAME (implementation_context
)));
6321 else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE
)
6323 tree category
= CLASS_CATEGORY_LIST (implementation_template
);
6325 /* Find the category interface from the class it is associated with. */
6328 if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category
))
6330 category
= CLASS_CATEGORY_LIST (category
);
6335 /* Ensure all method listed in the interface contain bodies. */
6336 check_methods (CLASS_CLS_METHODS (category
),
6337 CLASS_CLS_METHODS (implementation_context
), '+');
6338 check_methods (CLASS_NST_METHODS (category
),
6339 CLASS_NST_METHODS (implementation_context
), '-');
6341 if (CLASS_PROTOCOL_LIST (category
))
6342 check_protocols (CLASS_PROTOCOL_LIST (category
),
6344 IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
6348 else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE
)
6351 char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (class));
6352 char *string
= (char *) alloca (strlen (class_name
) + 3);
6354 /* extern struct objc_object *_<my_name>; */
6356 sprintf (string
, "_%s", class_name
);
6358 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_EXTERN
]);
6359 decl_specs
= tree_cons (NULL_TREE
, objc_object_reference
, decl_specs
);
6360 define_decl (build1 (INDIRECT_REF
, NULL_TREE
, get_identifier (string
)),
6366 add_protocol (protocol
)
6369 /* Put protocol on list in reverse order. */
6370 TREE_CHAIN (protocol
) = protocol_chain
;
6371 protocol_chain
= protocol
;
6372 return protocol_chain
;
6376 lookup_protocol (ident
)
6381 for (chain
= protocol_chain
; chain
; chain
= TREE_CHAIN (chain
))
6383 if (ident
== PROTOCOL_NAME (chain
))
6391 start_protocol (code
, name
, list
)
6392 enum tree_code code
;
6398 if (!doing_objc_thang
)
6401 /* This is as good a place as any. Need to invoke push_tag_toplevel. */
6402 if (!objc_protocol_template
)
6403 objc_protocol_template
= build_protocol_template ();
6405 protocol
= make_node (code
);
6406 TYPE_BINFO (protocol
) = make_tree_vec (2);
6408 PROTOCOL_NAME (protocol
) = name
;
6409 PROTOCOL_LIST (protocol
) = list
;
6411 lookup_and_install_protocols (list
);
6413 if (lookup_protocol (name
))
6414 warning ("duplicate declaration for protocol `%s'",
6415 IDENTIFIER_POINTER (name
));
6417 add_protocol (protocol
);
6419 PROTOCOL_FORWARD_DECL (protocol
) = NULL_TREE
;
6425 finish_protocol (protocol
)
6431 /* "Encode" a data type into a string, which grows in util_obstack.
6432 ??? What is the FORMAT? Someone please document this! */
6435 encode_type_qualifiers (declspecs
)
6440 for (spec
= declspecs
; spec
; spec
= TREE_CHAIN (spec
))
6442 if (ridpointers
[(int) RID_CONST
] == TREE_VALUE (spec
))
6443 obstack_1grow (&util_obstack
, 'r');
6444 else if (ridpointers
[(int) RID_IN
] == TREE_VALUE (spec
))
6445 obstack_1grow (&util_obstack
, 'n');
6446 else if (ridpointers
[(int) RID_INOUT
] == TREE_VALUE (spec
))
6447 obstack_1grow (&util_obstack
, 'N');
6448 else if (ridpointers
[(int) RID_OUT
] == TREE_VALUE (spec
))
6449 obstack_1grow (&util_obstack
, 'o');
6450 else if (ridpointers
[(int) RID_BYCOPY
] == TREE_VALUE (spec
))
6451 obstack_1grow (&util_obstack
, 'O');
6452 else if (ridpointers
[(int) RID_ONEWAY
] == TREE_VALUE (spec
))
6453 obstack_1grow (&util_obstack
, 'V');
6457 /* Encode a pointer type. */
6460 encode_pointer (type
, curtype
, format
)
6465 tree pointer_to
= TREE_TYPE (type
);
6467 if (TREE_CODE (pointer_to
) == RECORD_TYPE
)
6469 if (TYPE_NAME (pointer_to
)
6470 && TREE_CODE (TYPE_NAME (pointer_to
)) == IDENTIFIER_NODE
)
6472 char *name
= IDENTIFIER_POINTER (TYPE_NAME (pointer_to
));
6474 if (strcmp (name
, TAG_OBJECT
) == 0) /* '@' */
6476 obstack_1grow (&util_obstack
, '@');
6479 else if (TREE_STATIC_TEMPLATE (pointer_to
))
6481 if (generating_instance_variables
)
6483 obstack_1grow (&util_obstack
, '@');
6484 obstack_1grow (&util_obstack
, '"');
6485 obstack_grow (&util_obstack
, name
, strlen (name
));
6486 obstack_1grow (&util_obstack
, '"');
6491 obstack_1grow (&util_obstack
, '@');
6495 else if (strcmp (name
, TAG_CLASS
) == 0) /* '#' */
6497 obstack_1grow (&util_obstack
, '#');
6500 #ifndef OBJC_INT_SELECTORS
6501 else if (strcmp (name
, TAG_SELECTOR
) == 0) /* ':' */
6503 obstack_1grow (&util_obstack
, ':');
6506 #endif /* OBJC_INT_SELECTORS */
6509 else if (TREE_CODE (pointer_to
) == INTEGER_TYPE
6510 && TYPE_MODE (pointer_to
) == QImode
)
6512 obstack_1grow (&util_obstack
, '*');
6516 /* We have a type that does not get special treatment. */
6518 /* NeXT extension */
6519 obstack_1grow (&util_obstack
, '^');
6520 encode_type (pointer_to
, curtype
, format
);
6524 encode_array (type
, curtype
, format
)
6529 tree an_int_cst
= TYPE_SIZE (type
);
6530 tree array_of
= TREE_TYPE (type
);
6533 /* An incomplete array is treated like a pointer. */
6534 if (an_int_cst
== NULL
)
6536 encode_pointer (type
, curtype
, format
);
6540 sprintf (buffer
, "[%d",
6541 (TREE_INT_CST_LOW (an_int_cst
)
6542 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
6544 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6545 encode_type (array_of
, curtype
, format
);
6546 obstack_1grow (&util_obstack
, ']');
6551 encode_aggregate_within (type
, curtype
, format
, left
, right
)
6558 if (obstack_object_size (&util_obstack
) > 0
6559 && *(obstack_next_free (&util_obstack
) - 1) == '^')
6561 tree name
= TYPE_NAME (type
);
6563 /* we have a reference; this is a NeXT extension. */
6565 if (obstack_object_size (&util_obstack
) - curtype
== 1
6566 && format
== OBJC_ENCODE_INLINE_DEFS
)
6568 /* Output format of struct for first level only. */
6569 tree fields
= TYPE_FIELDS (type
);
6571 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6573 obstack_1grow (&util_obstack
, left
);
6574 obstack_grow (&util_obstack
,
6575 IDENTIFIER_POINTER (name
),
6576 strlen (IDENTIFIER_POINTER (name
)));
6577 obstack_1grow (&util_obstack
, '=');
6581 obstack_1grow (&util_obstack
, left
);
6582 obstack_grow (&util_obstack
, "?=", 2);
6585 for ( ; fields
; fields
= TREE_CHAIN (fields
))
6586 encode_field_decl (fields
, curtype
, format
);
6588 obstack_1grow (&util_obstack
, right
);
6591 else if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6593 obstack_1grow (&util_obstack
, left
);
6594 obstack_grow (&util_obstack
,
6595 IDENTIFIER_POINTER (name
),
6596 strlen (IDENTIFIER_POINTER (name
)));
6597 obstack_1grow (&util_obstack
, right
);
6602 /* We have an untagged structure or a typedef. */
6603 obstack_1grow (&util_obstack
, left
);
6604 obstack_1grow (&util_obstack
, '?');
6605 obstack_1grow (&util_obstack
, right
);
6611 tree name
= TYPE_NAME (type
);
6612 tree fields
= TYPE_FIELDS (type
);
6614 if (format
== OBJC_ENCODE_INLINE_DEFS
6615 || generating_instance_variables
)
6617 obstack_1grow (&util_obstack
, left
);
6618 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6619 obstack_grow (&util_obstack
,
6620 IDENTIFIER_POINTER (name
),
6621 strlen (IDENTIFIER_POINTER (name
)));
6623 obstack_1grow (&util_obstack
, '?');
6625 obstack_1grow (&util_obstack
, '=');
6627 for (; fields
; fields
= TREE_CHAIN (fields
))
6629 if (generating_instance_variables
)
6631 tree fname
= DECL_NAME (fields
);
6633 obstack_1grow (&util_obstack
, '"');
6634 if (fname
&& TREE_CODE (fname
) == IDENTIFIER_NODE
)
6636 obstack_grow (&util_obstack
,
6637 IDENTIFIER_POINTER (fname
),
6638 strlen (IDENTIFIER_POINTER (fname
)));
6641 obstack_1grow (&util_obstack
, '"');
6644 encode_field_decl (fields
, curtype
, format
);
6647 obstack_1grow (&util_obstack
, right
);
6652 obstack_1grow (&util_obstack
, left
);
6653 if (name
&& TREE_CODE (name
) == IDENTIFIER_NODE
)
6654 obstack_grow (&util_obstack
,
6655 IDENTIFIER_POINTER (name
),
6656 strlen (IDENTIFIER_POINTER (name
)));
6658 /* We have an untagged structure or a typedef. */
6659 obstack_1grow (&util_obstack
, '?');
6661 obstack_1grow (&util_obstack
, right
);
6667 encode_aggregate (type
, curtype
, format
)
6672 enum tree_code code
= TREE_CODE (type
);
6678 encode_aggregate_within(type
, curtype
, format
, '{', '}');
6683 encode_aggregate_within(type
, curtype
, format
, '(', ')');
6688 obstack_1grow (&util_obstack
, 'i');
6696 /* Support bitfields. The current version of Objective-C does not support
6697 them. The string will consist of one or more "b:n"'s where n is an
6698 integer describing the width of the bitfield. Currently, classes in
6699 the kit implement a method "-(char *)describeBitfieldStruct:" that
6700 simulates this. If they do not implement this method, the archiver
6701 assumes the bitfield is 16 bits wide (padded if necessary) and packed
6702 according to the GNU compiler. After looking at the "kit", it appears
6703 that all classes currently rely on this default behavior, rather than
6704 hand generating this string (which is tedious). */
6707 encode_bitfield (width
, format
)
6712 sprintf (buffer
, "b%d", width
);
6713 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
6716 /* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */
6719 encode_type (type
, curtype
, format
)
6724 enum tree_code code
= TREE_CODE (type
);
6726 if (code
== INTEGER_TYPE
)
6728 if (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type
)) == 0
6729 && TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type
)) == 0)
6731 /* Unsigned integer types. */
6733 if (TYPE_MODE (type
) == QImode
)
6734 obstack_1grow (&util_obstack
, 'C');
6735 else if (TYPE_MODE (type
) == HImode
)
6736 obstack_1grow (&util_obstack
, 'S');
6737 else if (TYPE_MODE (type
) == SImode
)
6739 if (type
== long_unsigned_type_node
)
6740 obstack_1grow (&util_obstack
, 'L');
6742 obstack_1grow (&util_obstack
, 'I');
6744 else if (TYPE_MODE (type
) == DImode
)
6745 obstack_1grow (&util_obstack
, 'Q');
6749 /* Signed integer types. */
6751 if (TYPE_MODE (type
) == QImode
)
6752 obstack_1grow (&util_obstack
, 'c');
6753 else if (TYPE_MODE (type
) == HImode
)
6754 obstack_1grow (&util_obstack
, 's');
6755 else if (TYPE_MODE (type
) == SImode
)
6757 if (type
== long_integer_type_node
)
6758 obstack_1grow (&util_obstack
, 'l');
6760 obstack_1grow (&util_obstack
, 'i');
6763 else if (TYPE_MODE (type
) == DImode
)
6764 obstack_1grow (&util_obstack
, 'q');
6768 else if (code
== REAL_TYPE
)
6770 /* Floating point types. */
6772 if (TYPE_MODE (type
) == SFmode
)
6773 obstack_1grow (&util_obstack
, 'f');
6774 else if (TYPE_MODE (type
) == DFmode
6775 || TYPE_MODE (type
) == TFmode
)
6776 obstack_1grow (&util_obstack
, 'd');
6779 else if (code
== VOID_TYPE
)
6780 obstack_1grow (&util_obstack
, 'v');
6782 else if (code
== ARRAY_TYPE
)
6783 encode_array (type
, curtype
, format
);
6785 else if (code
== POINTER_TYPE
)
6786 encode_pointer (type
, curtype
, format
);
6788 else if (code
== RECORD_TYPE
|| code
== UNION_TYPE
|| code
== ENUMERAL_TYPE
)
6789 encode_aggregate (type
, curtype
, format
);
6791 else if (code
== FUNCTION_TYPE
) /* '?' */
6792 obstack_1grow (&util_obstack
, '?');
6796 encode_field_decl (field_decl
, curtype
, format
)
6803 /* If this field is obviously a bitfield, or is a bitfield that has been
6804 clobbered to look like a ordinary integer mode, go ahead and generate
6805 the bitfield typing information. */
6806 type
= TREE_TYPE (field_decl
);
6807 if (DECL_BIT_FIELD (field_decl
))
6808 encode_bitfield (DECL_FIELD_SIZE (field_decl
), format
);
6809 else if (TREE_CODE (TYPE_SIZE (type
)) == INTEGER_CST
6810 && DECL_FIELD_SIZE (field_decl
)
6811 && TYPE_MODE (type
) > DECL_MODE (field_decl
))
6812 encode_bitfield (DECL_FIELD_SIZE (field_decl
), format
);
6814 encode_type (TREE_TYPE (field_decl
), curtype
, format
);
6818 expr_last (complex_expr
)
6824 while ((next
= TREE_OPERAND (complex_expr
, 0)))
6825 complex_expr
= next
;
6827 return complex_expr
;
6830 /* The selector of the current method,
6831 or NULL if we aren't compiling a method. */
6834 maybe_objc_method_name (decl
)
6838 return METHOD_SEL_NAME (method_context
);
6843 /* Transform a method definition into a function definition as follows:
6844 - synthesize the first two arguments, "self" and "_cmd". */
6847 start_method_def (method
)
6852 /* Required to implement _msgSuper. */
6853 method_context
= method
;
6854 UOBJC_SUPER_decl
= NULL_TREE
;
6856 /* Must be called BEFORE start_function. */
6859 /* Generate prototype declarations for arguments..."new-style". */
6861 if (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
)
6862 decl_specs
= build_tree_list (NULL_TREE
, uprivate_record
);
6864 /* Really a `struct objc_class *'. However, we allow people to
6865 assign to self, which changes its type midstream. */
6866 decl_specs
= build_tree_list (NULL_TREE
, objc_object_reference
);
6868 push_parm_decl (build_tree_list
6869 (build_tree_list (decl_specs
,
6870 build1 (INDIRECT_REF
, NULL_TREE
, self_id
)),
6871 build_tree_list (unused_list
, NULL_TREE
)));
6873 #ifdef OBJC_INT_SELECTORS
6874 decl_specs
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_UNSIGNED
]);
6875 decl_specs
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_INT
], decl_specs
);
6876 push_parm_decl (build_tree_list (build_tree_list (decl_specs
, ucmd_id
),
6877 build_tree_list (unused_list
, NULL_TREE
)));
6878 #else /* not OBJC_INT_SELECTORS */
6879 decl_specs
= build_tree_list (NULL_TREE
,
6880 xref_tag (RECORD_TYPE
,
6881 get_identifier (TAG_SELECTOR
)));
6882 push_parm_decl (build_tree_list
6883 (build_tree_list (decl_specs
,
6884 build1 (INDIRECT_REF
, NULL_TREE
, ucmd_id
)),
6885 build_tree_list (unused_list
, NULL_TREE
)));
6886 #endif /* not OBJC_INT_SELECTORS */
6888 /* Generate argument declarations if a keyword_decl. */
6889 if (METHOD_SEL_ARGS (method
))
6891 tree arglist
= METHOD_SEL_ARGS (method
);
6894 tree arg_spec
= TREE_PURPOSE (TREE_TYPE (arglist
));
6895 tree arg_decl
= TREE_VALUE (TREE_TYPE (arglist
));
6899 tree last_expr
= expr_last (arg_decl
);
6901 /* Unite the abstract decl with its name. */
6902 TREE_OPERAND (last_expr
, 0) = KEYWORD_ARG_NAME (arglist
);
6903 push_parm_decl (build_tree_list
6904 (build_tree_list (arg_spec
, arg_decl
),
6905 build_tree_list (NULL_TREE
, NULL_TREE
)));
6907 /* Unhook: restore the abstract declarator. */
6908 TREE_OPERAND (last_expr
, 0) = NULL_TREE
;
6912 push_parm_decl (build_tree_list
6913 (build_tree_list (arg_spec
,
6914 KEYWORD_ARG_NAME (arglist
)),
6915 build_tree_list (NULL_TREE
, NULL_TREE
)));
6917 arglist
= TREE_CHAIN (arglist
);
6922 if (METHOD_ADD_ARGS (method
) > (tree
)1)
6924 /* We have a variable length selector - in "prototype" format. */
6925 tree akey
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
6928 /* This must be done prior to calling pushdecl. pushdecl is
6929 going to change our chain on us. */
6930 tree nextkey
= TREE_CHAIN (akey
);
6938 warn_with_method (message
, mtype
, method
)
6943 if (count_error (1) == 0)
6946 report_error_function (DECL_SOURCE_FILE (method
));
6948 fprintf (stderr
, "%s:%d: warning: ",
6949 DECL_SOURCE_FILE (method
), DECL_SOURCE_LINE (method
));
6950 bzero (errbuf
, BUFSIZE
);
6951 fprintf (stderr
, "%s `%c%s'\n",
6952 message
, mtype
, gen_method_decl (method
, errbuf
));
6955 /* Return 1 if METHOD is consistent with PROTO. */
6958 comp_method_with_proto (method
, proto
)
6961 static tree function_type
= 0;
6963 /* Create a function_type node once. */
6966 push_obstacks_nochange ();
6967 end_temporary_allocation ();
6968 function_type
= make_node (FUNCTION_TYPE
);
6972 /* Install argument types - normally set by build_function_type. */
6973 TYPE_ARG_TYPES (function_type
) = get_arg_type_list (proto
, METHOD_DEF
, 0);
6975 /* install return type */
6976 TREE_TYPE (function_type
) = groktypename (TREE_TYPE (proto
));
6978 return comptypes (TREE_TYPE (METHOD_DEFINITION (method
)), function_type
);
6981 /* Return 1 if PROTO1 is consistent with PROTO2. */
6984 comp_proto_with_proto (proto1
, proto2
)
6985 tree proto1
, proto2
;
6987 static tree function_type1
= 0, function_type2
= 0;
6989 /* Create a couple function_type node's once. */
6990 if (!function_type1
)
6992 push_obstacks_nochange ();
6993 end_temporary_allocation ();
6994 function_type1
= make_node (FUNCTION_TYPE
);
6995 function_type2
= make_node (FUNCTION_TYPE
);
6999 /* Install argument types; normally set by build_function_type. */
7000 TYPE_ARG_TYPES (function_type1
) = get_arg_type_list (proto1
, METHOD_REF
, 0);
7001 TYPE_ARG_TYPES (function_type2
) = get_arg_type_list (proto2
, METHOD_REF
, 0);
7003 /* Install return type. */
7004 TREE_TYPE (function_type1
) = groktypename (TREE_TYPE (proto1
));
7005 TREE_TYPE (function_type2
) = groktypename (TREE_TYPE (proto2
));
7007 return comptypes (function_type1
, function_type2
);
7010 /* - Generate an identifier for the function. the format is "_n_cls",
7011 where 1 <= n <= nMethods, and cls is the name the implementation we
7013 - Install the return type from the method declaration.
7014 - If we have a prototype, check for type consistency. */
7017 really_start_method (method
, parmlist
)
7018 tree method
, parmlist
;
7020 tree sc_spec
, ret_spec
, ret_decl
, decl_specs
;
7021 tree method_decl
, method_id
;
7022 char *buf
, *sel_name
, *class_name
, *cat_name
;
7024 /* Synth the storage class & assemble the return type. */
7025 sc_spec
= tree_cons (NULL_TREE
, ridpointers
[(int) RID_STATIC
], NULL_TREE
);
7026 ret_spec
= TREE_PURPOSE (TREE_TYPE (method
));
7027 decl_specs
= chainon (sc_spec
, ret_spec
);
7029 sel_name
= IDENTIFIER_POINTER (METHOD_SEL_NAME (method
));
7030 class_name
= IDENTIFIER_POINTER (CLASS_NAME (implementation_context
));
7031 cat_name
= ((TREE_CODE (implementation_context
)
7032 == CLASS_IMPLEMENTATION_TYPE
)
7034 : IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context
)));
7037 /* Make sure this is big enough for any plausible method label. */
7038 buf
= (char *) alloca (50 + strlen (sel_name
) + strlen (class_name
)
7039 + (cat_name
? strlen (cat_name
) : 0));
7041 OBJC_GEN_METHOD_LABEL (buf
, TREE_CODE (method
) == INSTANCE_METHOD_DECL
,
7042 class_name
, cat_name
, sel_name
, method_slot
);
7044 method_id
= get_identifier (buf
);
7046 method_decl
= build_nt (CALL_EXPR
, method_id
, parmlist
, NULL_TREE
);
7048 /* Check the declarator portion of the return type for the method. */
7049 if ((ret_decl
= TREE_VALUE (TREE_TYPE (method
))))
7051 /* Unite the complex decl (specified in the abstract decl) with the
7052 function decl just synthesized..(int *), (int (*)()), (int (*)[]). */
7053 tree save_expr
= expr_last (ret_decl
);
7055 TREE_OPERAND (save_expr
, 0) = method_decl
;
7056 method_decl
= ret_decl
;
7058 /* Fool the parser into thinking it is starting a function. */
7059 start_function (decl_specs
, method_decl
, NULL_TREE
, NULL_TREE
, 0);
7061 /* Unhook: this has the effect of restoring the abstract declarator. */
7062 TREE_OPERAND (save_expr
, 0) = NULL_TREE
;
7067 TREE_VALUE (TREE_TYPE (method
)) = method_decl
;
7069 /* Fool the parser into thinking it is starting a function. */
7070 start_function (decl_specs
, method_decl
, NULL_TREE
, NULL_TREE
, 0);
7072 /* Unhook: this has the effect of restoring the abstract declarator. */
7073 TREE_VALUE (TREE_TYPE (method
)) = NULL_TREE
;
7076 METHOD_DEFINITION (method
) = current_function_decl
;
7078 if (implementation_template
!= implementation_context
)
7082 if (TREE_CODE (method
) == INSTANCE_METHOD_DECL
)
7083 proto
= lookup_instance_method_static (implementation_template
,
7084 METHOD_SEL_NAME (method
));
7086 proto
= lookup_class_method_static (implementation_template
,
7087 METHOD_SEL_NAME (method
));
7089 if (proto
&& ! comp_method_with_proto (method
, proto
))
7091 char type
= (TREE_CODE (method
) == INSTANCE_METHOD_DECL
? '-' : '+');
7093 warn_with_method ("conflicting types for", type
, method
);
7094 warn_with_method ("previous declaration of", type
, proto
);
7099 /* The following routine is always called...this "architecture" is to
7100 accommodate "old-style" variable length selectors.
7102 - a:a b:b // prototype ; id c; id d; // old-style. */
7105 continue_method_def ()
7109 if (METHOD_ADD_ARGS (method_context
) == (tree
)1)
7110 /* We have a `, ...' immediately following the selector. */
7111 parmlist
= get_parm_info (0);
7113 parmlist
= get_parm_info (1); /* place a `void_at_end' */
7115 /* Set self_decl from the first argument...this global is used by
7116 build_ivar_reference calling build_indirect_ref. */
7117 self_decl
= TREE_PURPOSE (parmlist
);
7120 really_start_method (method_context
, parmlist
);
7121 store_parm_decls ();
7124 /* Called by the parser, from the `pushlevel' production. */
7129 if (!UOBJC_SUPER_decl
)
7131 UOBJC_SUPER_decl
= start_decl (get_identifier (UTAG_SUPER
),
7132 build_tree_list (NULL_TREE
,
7133 objc_super_template
),
7134 0, NULL_TREE
, NULL_TREE
);
7136 finish_decl (UOBJC_SUPER_decl
, NULL_TREE
, NULL_TREE
);
7138 /* This prevents `unused variable' warnings when compiling with -Wall. */
7139 TREE_USED (UOBJC_SUPER_decl
) = 1;
7140 DECL_ARTIFICIAL (UOBJC_SUPER_decl
) = 1;
7144 /* _n_Method (id self, SEL sel, ...)
7146 struct objc_super _S;
7147 _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...);
7151 get_super_receiver ()
7155 tree super_expr
, super_expr_list
;
7157 /* Set receiver to self. */
7158 super_expr
= build_component_ref (UOBJC_SUPER_decl
, self_id
);
7159 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, self_decl
);
7160 super_expr_list
= build_tree_list (NULL_TREE
, super_expr
);
7162 /* Set class to begin searching. */
7163 super_expr
= build_component_ref (UOBJC_SUPER_decl
,
7164 get_identifier ("class"));
7166 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
7168 /* [_cls, __cls]Super are "pre-built" in
7169 synth_forward_declarations. */
7171 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
,
7172 ((TREE_CODE (method_context
)
7173 == INSTANCE_METHOD_DECL
)
7175 : uucls_super_ref
));
7179 /* We have a category. */
7181 tree super_name
= CLASS_SUPER_NAME (implementation_template
);
7186 error ("no super class declared in interface for `%s'",
7187 IDENTIFIER_POINTER (CLASS_NAME (implementation_template
)));
7188 return error_mark_node
;
7191 if (flag_next_runtime
)
7193 super_class
= get_class_reference (super_name
);
7194 if (TREE_CODE (method_context
) == CLASS_METHOD_DECL
)
7196 = build_component_ref (build_indirect_ref (super_class
, "->"),
7197 get_identifier ("isa"));
7201 add_class_reference (super_name
);
7202 super_class
= (TREE_CODE (method_context
) == INSTANCE_METHOD_DECL
7203 ? objc_get_class_decl
: objc_get_meta_class_decl
);
7204 assemble_external (super_class
);
7206 = build_function_call
7210 my_build_string (IDENTIFIER_LENGTH (super_name
) + 1,
7211 IDENTIFIER_POINTER (super_name
))));
7214 TREE_TYPE (super_class
) = TREE_TYPE (ucls_super_ref
);
7215 super_expr
= build_modify_expr (super_expr
, NOP_EXPR
, super_class
);
7218 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7220 super_expr
= build_unary_op (ADDR_EXPR
, UOBJC_SUPER_decl
, 0);
7221 chainon (super_expr_list
, build_tree_list (NULL_TREE
, super_expr
));
7223 return build_compound_expr (super_expr_list
);
7227 error ("[super ...] must appear in a method context");
7228 return error_mark_node
;
7233 encode_method_def (func_decl
)
7238 int max_parm_end
= 0;
7243 encode_type (TREE_TYPE (TREE_TYPE (func_decl
)),
7244 obstack_object_size (&util_obstack
),
7245 OBJC_ENCODE_INLINE_DEFS
);
7248 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7249 parms
= TREE_CHAIN (parms
))
7251 int parm_end
= (forwarding_offset (parms
)
7252 + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms
)))
7255 if (!offset_is_register
&& parm_end
> max_parm_end
)
7256 max_parm_end
= parm_end
;
7259 stack_size
= max_parm_end
- OBJC_FORWARDING_MIN_OFFSET
;
7261 sprintf (buffer
, "%d", stack_size
);
7262 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7264 /* Argument types. */
7265 for (parms
= DECL_ARGUMENTS (func_decl
); parms
;
7266 parms
= TREE_CHAIN (parms
))
7269 encode_type (TREE_TYPE (parms
),
7270 obstack_object_size (&util_obstack
),
7271 OBJC_ENCODE_INLINE_DEFS
);
7273 /* Compute offset. */
7274 sprintf (buffer
, "%d", forwarding_offset (parms
));
7276 /* Indicate register. */
7277 if (offset_is_register
)
7278 obstack_1grow (&util_obstack
, '+');
7280 obstack_grow (&util_obstack
, buffer
, strlen (buffer
));
7283 obstack_1grow (&util_obstack
, 0);
7284 result
= get_identifier (obstack_finish (&util_obstack
));
7285 obstack_free (&util_obstack
, util_firstobj
);
7290 finish_method_def ()
7292 METHOD_ENCODING (method_context
) = encode_method_def (current_function_decl
);
7294 finish_function (0);
7296 /* Required to implement _msgSuper. This must be done AFTER finish_function,
7297 since the optimizer may find "may be used before set" errors. */
7298 method_context
= NULL_TREE
;
7303 lang_report_error_function (decl
)
7308 fprintf (stderr
, "In method `%s'\n",
7309 IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context
)));
7319 is_complex_decl (type
)
7322 return (TREE_CODE (type
) == ARRAY_TYPE
7323 || TREE_CODE (type
) == FUNCTION_TYPE
7324 || (TREE_CODE (type
) == POINTER_TYPE
&& ! IS_ID (type
)));
7328 /* Code to convert a decl node into text for a declaration in C. */
7330 static char tmpbuf
[256];
7333 adorn_decl (decl
, str
)
7337 enum tree_code code
= TREE_CODE (decl
);
7339 if (code
== ARRAY_REF
)
7341 tree an_int_cst
= TREE_OPERAND (decl
, 1);
7343 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_CST
)
7344 sprintf (str
+ strlen (str
), "[%d]", TREE_INT_CST_LOW (an_int_cst
));
7349 else if (code
== ARRAY_TYPE
)
7351 tree an_int_cst
= TYPE_SIZE (decl
);
7352 tree array_of
= TREE_TYPE (decl
);
7354 if (an_int_cst
&& TREE_CODE (an_int_cst
) == INTEGER_TYPE
)
7355 sprintf (str
+ strlen (str
), "[%d]",
7356 (TREE_INT_CST_LOW (an_int_cst
)
7357 / TREE_INT_CST_LOW (TYPE_SIZE (array_of
))));
7362 else if (code
== CALL_EXPR
)
7364 tree chain
= TREE_PURPOSE (TREE_OPERAND (decl
, 1));
7369 gen_declaration (chain
, str
);
7370 chain
= TREE_CHAIN (chain
);
7377 else if (code
== FUNCTION_TYPE
)
7379 tree chain
= TYPE_ARG_TYPES (decl
);
7382 while (chain
&& TREE_VALUE (chain
) != void_type_node
)
7384 gen_declaration (TREE_VALUE (chain
), str
);
7385 chain
= TREE_CHAIN (chain
);
7386 if (chain
&& TREE_VALUE (chain
) != void_type_node
)
7392 else if (code
== INDIRECT_REF
)
7394 strcpy (tmpbuf
, "*");
7395 if (TREE_TYPE (decl
) && TREE_CODE (TREE_TYPE (decl
)) == TREE_LIST
)
7399 for (chain
= nreverse (copy_list (TREE_TYPE (decl
)));
7401 chain
= TREE_CHAIN (chain
))
7403 if (TREE_CODE (TREE_VALUE (chain
)) == IDENTIFIER_NODE
)
7405 strcat (tmpbuf
, " ");
7406 strcat (tmpbuf
, IDENTIFIER_POINTER (TREE_VALUE (chain
)));
7410 strcat (tmpbuf
, " ");
7412 strcat (tmpbuf
, str
);
7413 strcpy (str
, tmpbuf
);
7416 else if (code
== POINTER_TYPE
)
7418 strcpy (tmpbuf
, "*");
7419 if (TREE_READONLY (decl
) || TYPE_VOLATILE (decl
))
7421 if (TREE_READONLY (decl
))
7422 strcat (tmpbuf
, " const");
7423 if (TYPE_VOLATILE (decl
))
7424 strcat (tmpbuf
, " volatile");
7426 strcat (tmpbuf
, " ");
7428 strcat (tmpbuf
, str
);
7429 strcpy (str
, tmpbuf
);
7434 gen_declarator (decl
, buf
, name
)
7441 enum tree_code code
= TREE_CODE (decl
);
7451 op
= TREE_OPERAND (decl
, 0);
7453 /* We have a pointer to a function or array...(*)(), (*)[] */
7454 if ((code
== ARRAY_REF
|| code
== CALL_EXPR
)
7455 && op
&& TREE_CODE (op
) == INDIRECT_REF
)
7458 str
= gen_declarator (op
, buf
, name
);
7462 strcpy (tmpbuf
, "(");
7463 strcat (tmpbuf
, str
);
7464 strcat (tmpbuf
, ")");
7465 strcpy (str
, tmpbuf
);
7468 adorn_decl (decl
, str
);
7477 /* This clause is done iteratively rather than recursively. */
7480 op
= (is_complex_decl (TREE_TYPE (decl
))
7481 ? TREE_TYPE (decl
) : NULL_TREE
);
7483 adorn_decl (decl
, str
);
7485 /* We have a pointer to a function or array...(*)(), (*)[] */
7486 if (code
== POINTER_TYPE
7487 && op
&& (TREE_CODE (op
) == FUNCTION_TYPE
7488 || TREE_CODE (op
) == ARRAY_TYPE
))
7490 strcpy (tmpbuf
, "(");
7491 strcat (tmpbuf
, str
);
7492 strcat (tmpbuf
, ")");
7493 strcpy (str
, tmpbuf
);
7496 decl
= (is_complex_decl (TREE_TYPE (decl
))
7497 ? TREE_TYPE (decl
) : NULL_TREE
);
7500 while (decl
&& (code
= TREE_CODE (decl
)))
7505 case IDENTIFIER_NODE
:
7506 /* Will only happen if we are processing a "raw" expr-decl. */
7507 strcpy (buf
, IDENTIFIER_POINTER (decl
));
7518 /* We have an abstract declarator or a _DECL node. */
7526 gen_declspecs (declspecs
, buf
, raw
)
7535 for (chain
= nreverse (copy_list (declspecs
));
7536 chain
; chain
= TREE_CHAIN (chain
))
7538 tree aspec
= TREE_VALUE (chain
);
7540 if (TREE_CODE (aspec
) == IDENTIFIER_NODE
)
7541 strcat (buf
, IDENTIFIER_POINTER (aspec
));
7542 else if (TREE_CODE (aspec
) == RECORD_TYPE
)
7544 if (TYPE_NAME (aspec
))
7546 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7548 if (! TREE_STATIC_TEMPLATE (aspec
))
7549 strcat (buf
, "struct ");
7550 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7555 tree chain
= protocol_list
;
7562 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7563 chain
= TREE_CHAIN (chain
);
7572 strcat (buf
, "untagged struct");
7575 else if (TREE_CODE (aspec
) == UNION_TYPE
)
7577 if (TYPE_NAME (aspec
))
7579 if (! TREE_STATIC_TEMPLATE (aspec
))
7580 strcat (buf
, "union ");
7581 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7584 strcat (buf
, "untagged union");
7587 else if (TREE_CODE (aspec
) == ENUMERAL_TYPE
)
7589 if (TYPE_NAME (aspec
))
7591 if (! TREE_STATIC_TEMPLATE (aspec
))
7592 strcat (buf
, "enum ");
7593 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (aspec
)));
7596 strcat (buf
, "untagged enum");
7599 else if (TREE_CODE (aspec
) == TYPE_DECL
&& DECL_NAME (aspec
))
7600 strcat (buf
, IDENTIFIER_POINTER (DECL_NAME (aspec
)));
7602 else if (IS_ID (aspec
))
7604 tree protocol_list
= TYPE_PROTOCOL_LIST (aspec
);
7609 tree chain
= protocol_list
;
7616 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7617 chain
= TREE_CHAIN (chain
);
7624 if (TREE_CHAIN (chain
))
7630 /* Type qualifiers. */
7631 if (TREE_READONLY (declspecs
))
7632 strcat (buf
, "const ");
7633 if (TYPE_VOLATILE (declspecs
))
7634 strcat (buf
, "volatile ");
7636 switch (TREE_CODE (declspecs
))
7638 /* Type specifiers. */
7641 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7643 /* Signed integer types. */
7645 if (declspecs
== short_integer_type_node
)
7646 strcat (buf
, "short int ");
7647 else if (declspecs
== integer_type_node
)
7648 strcat (buf
, "int ");
7649 else if (declspecs
== long_integer_type_node
)
7650 strcat (buf
, "long int ");
7651 else if (declspecs
== long_long_integer_type_node
)
7652 strcat (buf
, "long long int ");
7653 else if (declspecs
== signed_char_type_node
7654 || declspecs
== char_type_node
)
7655 strcat (buf
, "char ");
7657 /* Unsigned integer types. */
7659 else if (declspecs
== short_unsigned_type_node
)
7660 strcat (buf
, "unsigned short ");
7661 else if (declspecs
== unsigned_type_node
)
7662 strcat (buf
, "unsigned int ");
7663 else if (declspecs
== long_unsigned_type_node
)
7664 strcat (buf
, "unsigned long ");
7665 else if (declspecs
== long_long_unsigned_type_node
)
7666 strcat (buf
, "unsigned long long ");
7667 else if (declspecs
== unsigned_char_type_node
)
7668 strcat (buf
, "unsigned char ");
7672 declspecs
= TYPE_MAIN_VARIANT (declspecs
);
7674 if (declspecs
== float_type_node
)
7675 strcat (buf
, "float ");
7676 else if (declspecs
== double_type_node
)
7677 strcat (buf
, "double ");
7678 else if (declspecs
== long_double_type_node
)
7679 strcat (buf
, "long double ");
7683 if (TYPE_NAME (declspecs
)
7684 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7686 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7688 if (! TREE_STATIC_TEMPLATE (declspecs
))
7689 strcat (buf
, "struct ");
7690 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7694 tree chain
= protocol_list
;
7701 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7702 chain
= TREE_CHAIN (chain
);
7711 strcat (buf
, "untagged struct");
7717 if (TYPE_NAME (declspecs
)
7718 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7720 strcat (buf
, "union ");
7721 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7726 strcat (buf
, "untagged union ");
7730 if (TYPE_NAME (declspecs
)
7731 && TREE_CODE (TYPE_NAME (declspecs
)) == IDENTIFIER_NODE
)
7733 strcat (buf
, "enum ");
7734 strcat (buf
, IDENTIFIER_POINTER (TYPE_NAME (declspecs
)));
7739 strcat (buf
, "untagged enum ");
7743 strcat (buf
, "void ");
7748 tree protocol_list
= TYPE_PROTOCOL_LIST (declspecs
);
7753 tree chain
= protocol_list
;
7760 (PROTOCOL_NAME (TREE_VALUE (chain
))));
7761 chain
= TREE_CHAIN (chain
);
7778 gen_declaration (atype_or_adecl
, buf
)
7779 tree atype_or_adecl
;
7784 if (TREE_CODE (atype_or_adecl
) == TREE_LIST
)
7786 tree declspecs
; /* "identifier_node", "record_type" */
7787 tree declarator
; /* "array_ref", "indirect_ref", "call_expr"... */
7789 /* We have a "raw", abstract declarator (typename). */
7790 declarator
= TREE_VALUE (atype_or_adecl
);
7791 declspecs
= TREE_PURPOSE (atype_or_adecl
);
7793 gen_declspecs (declspecs
, buf
, 1);
7797 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7804 tree declspecs
; /* "integer_type", "real_type", "record_type"... */
7805 tree declarator
; /* "array_type", "function_type", "pointer_type". */
7807 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7808 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7809 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7810 atype
= TREE_TYPE (atype_or_adecl
);
7812 /* Assume we have a *_type node. */
7813 atype
= atype_or_adecl
;
7815 if (is_complex_decl (atype
))
7819 /* Get the declaration specifier; it is at the end of the list. */
7820 declarator
= chain
= atype
;
7822 chain
= TREE_TYPE (chain
); /* not TREE_CHAIN (chain); */
7823 while (is_complex_decl (chain
));
7830 declarator
= NULL_TREE
;
7833 gen_declspecs (declspecs
, buf
, 0);
7835 if (TREE_CODE (atype_or_adecl
) == FIELD_DECL
7836 || TREE_CODE (atype_or_adecl
) == PARM_DECL
7837 || TREE_CODE (atype_or_adecl
) == FUNCTION_DECL
)
7839 char *decl_name
= (DECL_NAME (atype_or_adecl
)
7840 ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl
))
7846 strcat (buf
, gen_declarator (declarator
, declbuf
, decl_name
));
7849 else if (decl_name
[0])
7852 strcat (buf
, decl_name
);
7855 else if (declarator
)
7858 strcat (buf
, gen_declarator (declarator
, declbuf
, ""));
7865 #define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth))))
7868 gen_method_decl (method
, buf
)
7874 if (RAW_TYPESPEC (method
) != objc_object_reference
)
7877 gen_declaration (TREE_TYPE (method
), buf
);
7881 chain
= METHOD_SEL_ARGS (method
);
7884 /* We have a chain of keyword_decls. */
7887 if (KEYWORD_KEY_NAME (chain
))
7888 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain
)));
7891 if (RAW_TYPESPEC (chain
) != objc_object_reference
)
7894 gen_declaration (TREE_TYPE (chain
), buf
);
7898 strcat (buf
, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain
)));
7899 if ((chain
= TREE_CHAIN (chain
)))
7904 if (METHOD_ADD_ARGS (method
) == (tree
)1)
7905 strcat (buf
, ", ...");
7906 else if (METHOD_ADD_ARGS (method
))
7908 /* We have a tree list node as generate by get_parm_info. */
7909 chain
= TREE_PURPOSE (METHOD_ADD_ARGS (method
));
7911 /* Know we have a chain of parm_decls. */
7915 gen_declaration (chain
, buf
);
7916 chain
= TREE_CHAIN (chain
);
7922 /* We have a unary selector. */
7923 strcat (buf
, IDENTIFIER_POINTER (METHOD_SEL_NAME (method
)));
7931 dump_interface (fp
, chain
)
7935 char *buf
= (char *)xmalloc (256);
7936 char *my_name
= IDENTIFIER_POINTER (CLASS_NAME (chain
));
7937 tree ivar_decls
= CLASS_RAW_IVARS (chain
);
7938 tree nst_methods
= CLASS_NST_METHODS (chain
);
7939 tree cls_methods
= CLASS_CLS_METHODS (chain
);
7941 fprintf (fp
, "\n@interface %s", my_name
);
7943 if (CLASS_SUPER_NAME (chain
))
7945 char *super_name
= IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain
));
7946 fprintf (fp
, " : %s\n", super_name
);
7953 fprintf (fp
, "{\n");
7957 fprintf (fp
, "\t%s;\n", gen_declaration (ivar_decls
, buf
));
7958 ivar_decls
= TREE_CHAIN (ivar_decls
);
7961 fprintf (fp
, "}\n");
7967 fprintf (fp
, "- %s;\n", gen_method_decl (nst_methods
, buf
));
7968 nst_methods
= TREE_CHAIN (nst_methods
);
7974 fprintf (fp
, "+ %s;\n", gen_method_decl (cls_methods
, buf
));
7975 cls_methods
= TREE_CHAIN (cls_methods
);
7977 fprintf (fp
, "\n@end");
7980 /* Demangle function for Objective-C */
7982 objc_demangle (mangled
)
7983 const char *mangled
;
7985 char *demangled
, *cp
;
7987 if (mangled
[0] == '_' &&
7988 (mangled
[1] == 'i' || mangled
[1] == 'c') &&
7991 cp
= demangled
= xmalloc(strlen(mangled
) + 2);
7992 if (mangled
[1] == 'i')
7993 *cp
++ = '-'; /* for instance method */
7995 *cp
++ = '+'; /* for class method */
7996 *cp
++ = '['; /* opening left brace */
7997 strcpy(cp
, mangled
+3); /* tack on the rest of the mangled name */
7998 while (*cp
&& *cp
== '_')
7999 cp
++; /* skip any initial underbars in class name */
8000 cp
= strchr(cp
, '_'); /* find first non-initial underbar */
8003 free(demangled
); /* not mangled name */
8006 if (cp
[1] == '_') /* easy case: no category name */
8008 *cp
++ = ' '; /* replace two '_' with one ' ' */
8009 strcpy(cp
, mangled
+ (cp
- demangled
) + 2);
8013 *cp
++ = '('; /* less easy case: category name */
8014 cp
= strchr(cp
, '_');
8017 free(demangled
); /* not mangled name */
8021 *cp
++ = ' '; /* overwriting 1st char of method name... */
8022 strcpy(cp
, mangled
+ (cp
- demangled
)); /* get it back */
8024 while (*cp
&& *cp
== '_')
8025 cp
++; /* skip any initial underbars in method name */
8028 *cp
= ':'; /* replace remaining '_' with ':' */
8029 *cp
++ = ']'; /* closing right brace */
8030 *cp
++ = 0; /* string terminator */
8034 return mangled
; /* not an objc mangled name */
8038 objc_printable_name (decl
, kind
)
8042 return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl
)));
8048 /* Add the special tree codes of Objective C to the tables. */
8050 #define LAST_CODE LAST_AND_UNUSED_TREE_CODE
8052 gcc_obstack_init (&util_obstack
);
8053 util_firstobj
= (char *) obstack_finish (&util_obstack
);
8055 bcopy (objc_tree_code_type
,
8056 tree_code_type
+ (int) LAST_CODE
,
8057 (int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
);
8058 bcopy ((char *) objc_tree_code_length
,
8059 (char *) (tree_code_length
+ (int) LAST_CODE
),
8060 (((int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
)
8062 bcopy ((char *) objc_tree_code_name
,
8063 (char *) (tree_code_name
+ (int) LAST_CODE
),
8064 (((int) LAST_OBJC_TREE_CODE
- (int) LAST_CODE
)
8065 * sizeof (char *)));
8067 errbuf
= (char *)xmalloc (BUFSIZE
);
8069 synth_module_prologue ();
8071 /* Change the default error function */
8072 decl_printable_name
= (char* (*)()) objc_printable_name
;
8078 struct imp_entry
*impent
;
8080 /* The internally generated initializers appear to have missing braces.
8081 Don't warn about this. */
8082 int save_warn_missing_braces
= warn_missing_braces
;
8083 warn_missing_braces
= 0;
8085 generate_forward_declaration_to_string_table ();
8087 #ifdef OBJC_PROLOGUE
8091 /* Process the static instances here because initialization of objc_symtab
8093 if (objc_static_instances
)
8094 generate_static_references ();
8096 if (implementation_context
|| class_names_chain
8097 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8098 generate_objc_symtab_decl ();
8100 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8102 implementation_context
= impent
->imp_context
;
8103 implementation_template
= impent
->imp_template
;
8105 UOBJC_CLASS_decl
= impent
->class_decl
;
8106 UOBJC_METACLASS_decl
= impent
->meta_decl
;
8108 if (TREE_CODE (implementation_context
) == CLASS_IMPLEMENTATION_TYPE
)
8110 /* all of the following reference the string pool... */
8111 generate_ivar_lists ();
8112 generate_dispatch_tables ();
8113 generate_shared_structures ();
8117 generate_dispatch_tables ();
8118 generate_category (implementation_context
);
8122 /* If we are using an array of selectors, we must always
8123 finish up the array decl even if no selectors were used. */
8124 if (! flag_next_runtime
|| sel_ref_chain
)
8125 build_selector_translation_table ();
8128 generate_protocols ();
8130 if (implementation_context
|| class_names_chain
|| objc_static_instances
8131 || meth_var_names_chain
|| meth_var_types_chain
|| sel_ref_chain
)
8133 /* Arrange for Objc data structures to be initialized at run time. */
8134 char *init_name
= build_module_descriptor ();
8136 assemble_constructor (init_name
);
8139 /* Dump the class references. This forces the appropriate classes
8140 to be linked into the executable image, preserving unix archive
8141 semantics. This can be removed when we move to a more dynamically
8142 linked environment. */
8144 for (chain
= cls_ref_chain
; chain
; chain
= TREE_CHAIN (chain
))
8146 handle_class_ref (chain
);
8147 if (TREE_PURPOSE (chain
))
8148 generate_classref_translation_entry (chain
);
8151 for (impent
= imp_list
; impent
; impent
= impent
->next
)
8152 handle_impent (impent
);
8154 /* Dump the string table last. */
8156 generate_strings ();
8158 if (flag_gen_declaration
)
8160 add_class (implementation_context
);
8161 dump_interface (gen_declaration_file
, implementation_context
);
8169 /* Run through the selector hash tables and print a warning for any
8170 selector which has multiple methods. */
8172 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8173 for (hsh
= cls_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8176 tree meth
= hsh
->key
;
8177 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8181 warning ("potential selector conflict for method `%s'",
8182 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8183 warn_with_method ("found", type
, meth
);
8184 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8185 warn_with_method ("found", type
, loop
->value
);
8188 for (slot
= 0; slot
< SIZEHASHTABLE
; slot
++)
8189 for (hsh
= nst_method_hash_list
[slot
]; hsh
; hsh
= hsh
->next
)
8192 tree meth
= hsh
->key
;
8193 char type
= (TREE_CODE (meth
) == INSTANCE_METHOD_DECL
8197 warning ("potential selector conflict for method `%s'",
8198 IDENTIFIER_POINTER (METHOD_SEL_NAME (meth
)));
8199 warn_with_method ("found", type
, meth
);
8200 for (loop
= hsh
->list
; loop
; loop
= loop
->next
)
8201 warn_with_method ("found", type
, loop
->value
);
8205 warn_missing_braces
= save_warn_missing_braces
;
8208 /* Subroutines of finish_objc. */
8211 generate_classref_translation_entry (chain
)
8214 tree expr
, name
, decl_specs
, decl
, sc_spec
;
8217 type
= TREE_TYPE (TREE_PURPOSE (chain
));
8219 expr
= add_objc_string (TREE_VALUE (chain
), class_names
);
8220 expr
= build_c_cast (type
, expr
); /* cast! */
8222 name
= DECL_NAME (TREE_PURPOSE (chain
));
8224 sc_spec
= build_tree_list (NULL_TREE
, ridpointers
[(int) RID_STATIC
]);
8226 /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */
8227 decl_specs
= tree_cons (NULL_TREE
, type
, sc_spec
);
8229 /* The decl that is returned from start_decl is the one that we
8230 forward declared in build_class_reference. */
8231 decl
= start_decl (name
, decl_specs
, 1, NULL_TREE
, NULL_TREE
);
8232 finish_decl (decl
, expr
, NULL_TREE
);
8237 handle_class_ref (chain
)
8240 char *name
= IDENTIFIER_POINTER (TREE_VALUE (chain
));
8241 if (! flag_next_runtime
)
8244 char *string
= (char *) alloca (strlen (name
) + 30);
8247 sprintf (string
, "%sobjc_class_name_%s",
8248 (flag_next_runtime
? "." : "__"), name
);
8250 /* Make a decl for this name, so we can use its address in a tree. */
8251 decl
= build_decl (VAR_DECL
, get_identifier (string
), char_type_node
);
8252 DECL_EXTERNAL (decl
) = 1;
8253 TREE_PUBLIC (decl
) = 1;
8256 rest_of_decl_compilation (decl
, 0, 0, 0);
8258 /* Make following constant read-only (why not)? */
8259 readonly_data_section ();
8261 exp
= build1 (ADDR_EXPR
, string_type_node
, decl
);
8263 /* Align the section properly. */
8264 assemble_constant_align (exp
);
8266 /* Inform the assembler about this new external thing. */
8267 assemble_external (decl
);
8269 /* Output a constant to reference this address. */
8270 output_constant (exp
, int_size_in_bytes (string_type_node
));
8274 /* This overreliance on our assembler (i.e. lack of portability)
8275 should be dealt with at some point. The GNU strategy (above)
8276 won't work either, but it is a start. */
8277 char *string
= (char *) alloca (strlen (name
) + 30);
8278 sprintf (string
, ".reference .objc_class_name_%s", name
);
8279 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8284 handle_impent (impent
)
8285 struct imp_entry
*impent
;
8287 implementation_context
= impent
->imp_context
;
8288 implementation_template
= impent
->imp_template
;
8290 if (TREE_CODE (impent
->imp_context
) == CLASS_IMPLEMENTATION_TYPE
)
8292 char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8293 char *string
= (char *) alloca (strlen (class_name
) + 30);
8295 if (flag_next_runtime
)
8297 /* Grossly unportable.
8298 People should know better than to assume
8299 such things about assembler syntax! */
8300 sprintf (string
, ".objc_class_name_%s=0", class_name
);
8301 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8303 sprintf (string
, ".globl .objc_class_name_%s", class_name
);
8304 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8309 sprintf (string
, "%sobjc_class_name_%s",
8310 (flag_next_runtime
? "." : "__"), class_name
);
8311 assemble_global (string
);
8312 assemble_label (string
);
8316 else if (TREE_CODE (impent
->imp_context
) == CATEGORY_IMPLEMENTATION_TYPE
)
8318 char *class_name
= IDENTIFIER_POINTER (CLASS_NAME (impent
->imp_context
));
8319 char *class_super_name
8320 = IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent
->imp_context
));
8321 char *string
= (char *) alloca (strlen (class_name
)
8322 + strlen (class_super_name
) + 30);
8324 /* Do the same for categories. Even though no references to these
8325 symbols are generated automatically by the compiler, it gives
8326 you a handle to pull them into an archive by hand. */
8327 if (flag_next_runtime
)
8329 /* Grossly unportable. */
8330 sprintf (string
, ".objc_category_name_%s_%s=0",
8331 class_name
, class_super_name
);
8332 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8334 sprintf (string
, ".globl .objc_category_name_%s_%s",
8335 class_name
, class_super_name
);
8336 assemble_asm (my_build_string (strlen (string
) + 1, string
));
8341 sprintf (string
, "%sobjc_category_name_%s_%s",
8342 (flag_next_runtime
? "." : "__"),
8343 class_name
, class_super_name
);
8344 assemble_global (string
);
8345 assemble_label (string
);
8356 char *buf
= (char *)xmalloc (256);
8358 { /* dump function prototypes */
8359 tree loop
= UOBJC_MODULES_decl
;
8361 fprintf (fp
, "\n\nfunction prototypes:\n");
8364 if (TREE_CODE (loop
) == FUNCTION_DECL
&& DECL_INITIAL (loop
))
8366 /* We have a function definition: generate prototype. */
8367 bzero (errbuf
, BUFSIZE
);
8368 gen_declaration (loop
, errbuf
);
8369 fprintf (fp
, "%s;\n", errbuf
);
8371 loop
= TREE_CHAIN (loop
);
8375 /* Dump global chains. */
8377 int i
, index
= 0, offset
= 0;
8380 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
8382 if (hashlist
= nst_method_hash_list
[i
])
8384 fprintf (fp
, "\n\nnst_method_hash_list[%d]:\n", i
);
8388 fprintf (fp
, "-%s;\n", gen_method_decl (hashlist
->key
, buf
));
8389 hashlist
= hashlist
->next
;
8395 for (i
= 0; i
< SIZEHASHTABLE
; i
++)
8397 if (hashlist
= cls_method_hash_list
[i
])
8399 fprintf (fp
, "\n\ncls_method_hash_list[%d]:\n", i
);
8403 fprintf (fp
, "-%s;\n", gen_method_decl (hashlist
->key
, buf
));
8404 hashlist
= hashlist
->next
;
8410 fprintf (fp
, "\nsel_refdef_chain:\n");
8411 for (loop
= sel_refdef_chain
; loop
; loop
= TREE_CHAIN (loop
))
8413 fprintf (fp
, "(index: %4d offset: %4d) %s\n", index
, offset
,
8414 IDENTIFIER_POINTER (TREE_VALUE (loop
)));
8416 /* add one for the '\0' character */
8417 offset
+= IDENTIFIER_LENGTH (TREE_VALUE (loop
)) + 1;
8420 fprintf (fp
, "\n (max_selector_index: %4d.\n", max_selector_index
);
8426 print_lang_statistics ()