]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/objc/objc-gnu-runtime-abi-01.c
Update copyright years in gcc/
[thirdparty/gcc.git] / gcc / objc / objc-gnu-runtime-abi-01.c
CommitLineData
d4c433f9 1/* GNU Runtime ABI version 8
23a5b65a 2 Copyright (C) 2011-2014 Free Software Foundation, Inc.
d764a8e6
IS
3 Contributed by Iain Sandoe (split from objc-act.c)
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3, or (at your option)
10any later version.
11
12GCC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
20
21#include "config.h"
22#include "system.h"
23#include "coretypes.h"
d764a8e6 24#include "tree.h"
d8a2d370 25#include "stringpool.h"
d764a8e6
IS
26
27#ifdef OBJCPLUS
d4a10d0a 28#include "cp/cp-tree.h"
d764a8e6 29#else
d4a10d0a
SB
30#include "c/c-tree.h"
31#include "c/c-lang.h"
d764a8e6
IS
32#endif
33
34#include "langhooks.h"
35#include "c-family/c-objc.h"
36#include "objc-act.h"
37
38/* When building Objective-C++, we are not linking against the C front-end
39 and so need to replicate the C tree-construction functions in some way. */
40#ifdef OBJCPLUS
41#define OBJCP_REMAP_FUNCTIONS
42#include "objcp-decl.h"
43#endif /* OBJCPLUS */
44
45#include "toplev.h"
46#include "ggc.h"
47#include "tree-iterator.h"
48
49#include "objc-runtime-hooks.h"
50#include "objc-runtime-shared-support.h"
f027ee7c 51#include "objc-encoding.h"
d764a8e6
IS
52
53/* GNU runtime private definitions. */
54#define DEF_CONSTANT_STRING_CLASS_NAME "NXConstantString"
55
56#define TAG_GETCLASS "objc_get_class"
57#define TAG_GETMETACLASS "objc_get_meta_class"
58
59#define TAG_MSGSEND "objc_msg_lookup"
60#define TAG_MSGSENDSUPER "objc_msg_lookup_super"
61
62/* GNU-specific tags. */
63
64#define TAG_EXECCLASS "__objc_exec_class"
65#define TAG_GNUINIT "__objc_gnu_init"
66
67/* The version identifies which language generation and runtime
68 the module (file) was compiled for, and is recorded in the
69 module descriptor. */
70#define OBJC_VERSION 8
71
72#define PROTOCOL_VERSION 2
73
74/* This macro provides a method of removing ambiguity between runtimes
75 when LTO is in use on targets supporting multiple runtimes.
944fb799 76
d764a8e6
IS
77 For example, at present, any target that includes an implementation of
78 the NeXT runtime needs to place Objective-C meta-data into specific
944fb799 79 named sections. This should _not_ be done for the GNU runtime, and the
587ae1e3 80 following macro is used to attach Objective-C private attributes that may
d764a8e6
IS
81 be used to identify the runtime for which the meta-data are intended. */
82
83#define OBJCMETA(DECL,VERS,KIND) \
84 if (VERS) \
85 DECL_ATTRIBUTES (DECL) = build_tree_list ((VERS), (KIND));
86
d764a8e6
IS
87static void gnu_runtime_01_initialize (void);
88
89static void build_selector_template (void);
90
91static tree gnu_runtime_abi_01_super_superclassfield_id (void);
92
93static tree gnu_runtime_abi_01_class_decl (tree);
94static tree gnu_runtime_abi_01_metaclass_decl (tree);
95static tree gnu_runtime_abi_01_category_decl (tree);
96static tree gnu_runtime_abi_01_protocol_decl (tree);
97static tree gnu_runtime_abi_01_string_decl (tree, const char *, string_section);
98
99static tree gnu_runtime_abi_01_get_class_reference (tree);
100static tree gnu_runtime_abi_01_build_typed_selector_reference (location_t, tree,
101 tree);
102static tree gnu_runtime_abi_01_get_protocol_reference (location_t, tree);
103static tree gnu_runtime_abi_01_build_ivar_ref (location_t, tree, tree);
104static tree gnu_runtime_abi_01_get_class_super_ref (location_t, struct imp_entry *, bool);
105static tree gnu_runtime_abi_01_get_category_super_ref (location_t, struct imp_entry *, bool);
106
107static tree gnu_runtime_abi_01_receiver_is_class_object (tree);
9771b263
DN
108static void gnu_runtime_abi_01_get_arg_type_list_base (vec<tree, va_gc> **,
109 tree, int, int);
d764a8e6
IS
110static tree gnu_runtime_abi_01_build_objc_method_call (location_t, tree, tree,
111 tree, tree, tree, int);
112
113static bool gnu_runtime_abi_01_setup_const_string_class_decl (void);
114static tree gnu_runtime_abi_01_build_const_string_constructor (location_t, tree,int);
115
116static void objc_generate_v1_gnu_metadata (void);
117
118static tree objc_eh_runtime_type (tree type);
119static tree objc_eh_personality (void);
120static tree objc_build_exc_ptr (struct objc_try_context **);
121static tree build_throw_stmt (location_t, tree, bool);
122static tree begin_catch (struct objc_try_context **, tree, tree, tree, bool);
123static void finish_catch (struct objc_try_context **, tree);
124static tree finish_try_stmt (struct objc_try_context **);
125
944fb799 126bool
d764a8e6
IS
127objc_gnu_runtime_abi_01_init (objc_runtime_hooks *rthooks)
128{
129 /* GNU runtime does not need the compiler to change code in order to do GC. */
130 if (flag_objc_gc)
131 {
132 warning_at (0, 0, "%<-fobjc-gc%> is ignored for %<-fgnu-runtime%>");
133 flag_objc_gc = 0;
134 }
135
136 /* Although I guess we could, we don't currently support SJLJ exceptions for the
137 GNU runtime. */
138 if (flag_objc_sjlj_exceptions)
139 {
140 inform (UNKNOWN_LOCATION, "%<-fobjc-sjlj-exceptions%> is ignored for %<-fgnu-runtime%>");
141 flag_objc_sjlj_exceptions = 0;
142 }
143
d4c433f9
NP
144 /* TODO: Complain if -fobjc-abi-version=N was used. */
145
146 /* TODO: Complain if -fobj-nilcheck was used. */
147
d764a8e6
IS
148 rthooks->initialize = gnu_runtime_01_initialize;
149 rthooks->default_constant_string_class_name = DEF_CONSTANT_STRING_CLASS_NAME;
150 rthooks->tag_getclass = TAG_GETCLASS;
151 rthooks->super_superclassfield_ident = gnu_runtime_abi_01_super_superclassfield_id;
152
153 rthooks->class_decl = gnu_runtime_abi_01_class_decl;
154 rthooks->metaclass_decl = gnu_runtime_abi_01_metaclass_decl;
155 rthooks->category_decl = gnu_runtime_abi_01_category_decl;
156 rthooks->protocol_decl = gnu_runtime_abi_01_protocol_decl;
157 rthooks->string_decl = gnu_runtime_abi_01_string_decl;
158
159 rthooks->get_class_reference = gnu_runtime_abi_01_get_class_reference;
160 rthooks->build_selector_reference = gnu_runtime_abi_01_build_typed_selector_reference;
161 rthooks->get_protocol_reference = gnu_runtime_abi_01_get_protocol_reference;
162 rthooks->build_ivar_reference = gnu_runtime_abi_01_build_ivar_ref;
163 rthooks->get_class_super_ref = gnu_runtime_abi_01_get_class_super_ref;
164 rthooks->get_category_super_ref = gnu_runtime_abi_01_get_category_super_ref;
165
166 rthooks->receiver_is_class_object = gnu_runtime_abi_01_receiver_is_class_object;
167 rthooks->get_arg_type_list_base = gnu_runtime_abi_01_get_arg_type_list_base;
168 rthooks->build_objc_method_call = gnu_runtime_abi_01_build_objc_method_call;
169
170 rthooks->setup_const_string_class_decl =
171 gnu_runtime_abi_01_setup_const_string_class_decl;
172 rthooks->build_const_string_constructor =
173 gnu_runtime_abi_01_build_const_string_constructor;
174
175 rthooks->build_throw_stmt = build_throw_stmt;
176 rthooks->build_exc_ptr = objc_build_exc_ptr;
177 rthooks->begin_catch = begin_catch;
178 rthooks->finish_catch = finish_catch;
179 rthooks->finish_try_stmt = finish_try_stmt;
180
181 rthooks->generate_metadata = objc_generate_v1_gnu_metadata;
182 return true;
183}
184
185static void build_selector_table_decl (void);
186static void build_class_template (void);
187static void build_category_template (void);
188static void build_protocol_template (void);
189
190static GTY(()) tree objc_meta;
191static GTY(()) tree meta_base;
192
193static void gnu_runtime_01_initialize (void)
194{
195 tree type, ftype, IMP_type;
196
197 /* We do not need to mark GNU ObjC metadata for different sections,
198 however, we do need to make sure that it is not mistaken for NeXT
199 metadata. */
200 objc_meta = get_identifier ("OBJC1METG");
201 meta_base = get_identifier ("NONE");
202
203 /* Declare type of selector-objects that represent an operation name. */
204 /* `const struct objc_selector *' */
205 type = xref_tag (RECORD_TYPE, get_identifier (TAG_SELECTOR));
206 type = build_qualified_type (type, TYPE_QUAL_CONST);
207 objc_selector_type = build_pointer_type (type);
208
209 /* typedef id (*IMP)(id, SEL, ...); */
210 ftype = build_varargs_function_type_list (objc_object_type,
211 objc_object_type,
212 objc_selector_type,
213 NULL_TREE);
214
215 IMP_type = build_pointer_type (ftype);
216
217 build_class_template ();
218 build_super_template ();
219 build_protocol_template ();
220 build_category_template ();
221
222 /* GNU runtime messenger entry points. */
223 /* TREE_NOTHROW is cleared for the message-sending functions,
224 because the function that gets called can throw in Obj-C++, or
225 could itself call something that can throw even in Obj-C. */
226
227 /* IMP objc_msg_lookup (id, SEL); */
228 type = build_function_type_list (IMP_type,
229 objc_object_type,
230 objc_selector_type,
231 NULL_TREE);
232
233 umsg_decl = add_builtin_function (TAG_MSGSEND,
234 type, 0, NOT_BUILT_IN,
235 NULL, NULL_TREE);
236 TREE_NOTHROW (umsg_decl) = 0;
237
238 /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
239 type = build_function_type_list (IMP_type,
240 objc_super_type,
241 objc_selector_type,
242 NULL_TREE);
243
244 umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
245 type, 0, NOT_BUILT_IN,
246 NULL, NULL_TREE);
247 TREE_NOTHROW (umsg_super_decl) = 0;
248
249 /* The following GNU runtime entry point is called to initialize
250 each module:
251
252 __objc_exec_class (void *); */
253 type = build_function_type_list (void_type_node,
254 ptr_type_node,
255 NULL_TREE);
256
257 execclass_decl = add_builtin_function (TAG_EXECCLASS,
258 type, 0, NOT_BUILT_IN,
259 NULL, NULL_TREE);
260
261 type = build_function_type_list (objc_object_type,
262 const_string_type_node,
263 NULL_TREE);
264
265 /* id objc_getClass (const char *); */
266 objc_get_class_decl
267 = add_builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
268 NULL, NULL_TREE);
269
270 /* id objc_getMetaClass (const char *); */
944fb799 271 objc_get_meta_class_decl = add_builtin_function (TAG_GETMETACLASS, type,
d764a8e6
IS
272 0, NOT_BUILT_IN, NULL,
273 NULL_TREE);
274
275 /* static SEL _OBJC_SELECTOR_TABLE[]; */
276 build_selector_table_decl ();
944fb799
MS
277
278 /* Stuff for properties.
d764a8e6
IS
279 The codegen relies on this being NULL for GNU. */
280 objc_copyStruct_decl = NULL_TREE;
281
282 /* This is the type of all of the following functions
283 bjc_getPropertyStruct() and objc_setPropertyStruct(). */
284 type = build_function_type_list (void_type_node,
285 ptr_type_node,
286 const_ptr_type_node,
944fb799 287 ptrdiff_type_node,
d764a8e6
IS
288 boolean_type_node,
289 boolean_type_node,
290 NULL_TREE);
291
292 /* Declare the following function:
293 void
944fb799 294 objc_getPropertyStruct (void *destination, const void *source,
d764a8e6
IS
295 ptrdiff_t size, BOOL is_atomic, BOOL has_strong); */
296 objc_getPropertyStruct_decl = add_builtin_function ("objc_getPropertyStruct",
297 type, 0, NOT_BUILT_IN,
298 NULL, NULL_TREE);
299 TREE_NOTHROW (objc_getPropertyStruct_decl) = 0;
300 /* Declare the following function:
301 void
944fb799 302 objc_setPropertyStruct (void *destination, const void *source,
d764a8e6
IS
303 ptrdiff_t size, BOOL is_atomic, BOOL has_strong); */
304 objc_setPropertyStruct_decl = add_builtin_function ("objc_setPropertyStruct",
305 type, 0, NOT_BUILT_IN,
306 NULL, NULL_TREE);
307 TREE_NOTHROW (objc_setPropertyStruct_decl) = 0;
944fb799 308
d764a8e6
IS
309 using_eh_for_cleanups ();
310 lang_hooks.eh_runtime_type = objc_eh_runtime_type;
311 lang_hooks.eh_personality = objc_eh_personality;
312}
313
314/* --- templates --- */
315/* struct _objc_selector {
316 SEL sel_id;
317 char *sel_type;
318 }; */
319
320static void
321build_selector_template (void)
322{
323 tree decls, *chain = NULL;
324
325 objc_selector_template = objc_start_struct (get_identifier (UTAG_SELECTOR));
326
327 /* SEL sel_id; */
328 decls = add_field_decl (objc_selector_type, "sel_id", &chain);
329
330 /* char *sel_type; */
331 add_field_decl (string_type_node, "sel_type", &chain);
332
333 objc_finish_struct (objc_selector_template, decls);
334}
335
336/* struct _objc_class {
337 struct _objc_class *isa;
338 struct _objc_class *super_class;
339 char *name;
340 long version;
341 long info;
342 long instance_size;
343 struct _objc_ivar_list *ivars;
344 struct _objc_method_list *methods;
345 struct sarray *dtable;
346 struct _objc_class *subclass_list;
347 struct _objc_class *sibling_class;
348 struct _objc_protocol_list *protocols;
349 void *gc_object_type;
350 }; */
351
352static void
353build_class_template (void)
354{
355 tree ptype, decls, *chain = NULL;
356
357 objc_class_template = objc_start_struct (get_identifier (UTAG_CLASS));
358
359 /* struct _objc_class *isa; */
360 decls = add_field_decl (build_pointer_type (objc_class_template),
361 "isa", &chain);
362
363 /* struct _objc_class *super_class; */
364 add_field_decl (build_pointer_type (objc_class_template),
365 "super_class", &chain);
366
367 /* char *name; */
368 add_field_decl (string_type_node, "name", &chain);
369
370 /* long version; */
371 add_field_decl (long_integer_type_node, "version", &chain);
372
373 /* long info; */
374 add_field_decl (long_integer_type_node, "info", &chain);
375
376 /* long instance_size; */
377 add_field_decl (long_integer_type_node, "instance_size", &chain);
378
379 /* struct _objc_ivar_list *ivars; */
380 add_field_decl (objc_ivar_list_ptr,"ivars", &chain);
381
382 /* struct _objc_method_list *methods; */
383 add_field_decl (objc_method_list_ptr, "methods", &chain);
384
385 /* struct sarray *dtable; */
386 ptype = build_pointer_type(xref_tag (RECORD_TYPE,
387 get_identifier ("sarray")));
388 add_field_decl (ptype, "dtable", &chain);
389
390 /* struct objc_class *subclass_list; */
391 ptype = build_pointer_type (objc_class_template);
392 add_field_decl (ptype, "subclass_list", &chain);
393
394 /* struct objc_class *sibling_class; */
395 ptype = build_pointer_type (objc_class_template);
396 add_field_decl (ptype, "sibling_class", &chain);
944fb799 397
d764a8e6
IS
398 /* struct _objc_protocol **protocol_list; */
399 ptype = build_pointer_type (build_pointer_type
400 (xref_tag (RECORD_TYPE,
401 get_identifier (UTAG_PROTOCOL))));
402 add_field_decl (ptype, "protocol_list", &chain);
403
404 /* void *gc_object_type; */
405 add_field_decl (build_pointer_type (void_type_node),
406 "gc_object_type", &chain);
407
408 objc_finish_struct (objc_class_template, decls);
409}
410
411/* struct _objc_category {
412 char *category_name;
413 char *class_name;
414 struct _objc_method_list *instance_methods;
415 struct _objc_method_list *class_methods;
416 struct _objc_protocol_list *protocols;
417 }; */
418
419static void
420build_category_template (void)
421{
422 tree ptype, decls, *chain = NULL;
423
424 objc_category_template = objc_start_struct (get_identifier (UTAG_CATEGORY));
425
426 /* char *category_name; */
427 decls = add_field_decl (string_type_node, "category_name", &chain);
428
429 /* char *class_name; */
430 add_field_decl (string_type_node, "class_name", &chain);
431
432 /* struct _objc_method_list *instance_methods; */
433 add_field_decl (objc_method_list_ptr, "instance_methods", &chain);
434
435 /* struct _objc_method_list *class_methods; */
436 add_field_decl (objc_method_list_ptr, "class_methods", &chain);
437
438 /* struct _objc_protocol **protocol_list; */
439 ptype = build_pointer_type (build_pointer_type (objc_protocol_template));
440 add_field_decl (ptype, "protocol_list", &chain);
441
442 objc_finish_struct (objc_category_template, decls);
443}
444
445/* struct _objc_protocol {
446 struct _objc_class *isa;
447 char *protocol_name;
448 struct _objc_protocol **protocol_list;
449 struct _objc__method_prototype_list *instance_methods;
450 struct _objc__method_prototype_list *class_methods;
451 }; */
452
453static void
454build_protocol_template (void)
455{
456 tree ptype, decls, *chain = NULL;
457
458 objc_protocol_template = objc_start_struct (get_identifier (UTAG_PROTOCOL));
459
460 /* struct _objc_class *isa; */
461 ptype = build_pointer_type (xref_tag (RECORD_TYPE,
462 get_identifier (UTAG_CLASS)));
463 decls = add_field_decl (ptype, "isa", &chain);
464
465 /* char *protocol_name; */
466 add_field_decl (string_type_node, "protocol_name", &chain);
467
468 /* struct _objc_protocol **protocol_list; */
469 ptype = build_pointer_type (build_pointer_type (objc_protocol_template));
470 add_field_decl (ptype, "protocol_list", &chain);
471
472 /* struct _objc__method_prototype_list *instance_methods; */
473 add_field_decl (objc_method_proto_list_ptr, "instance_methods", &chain);
474
475 /* struct _objc__method_prototype_list *class_methods; */
476 add_field_decl (objc_method_proto_list_ptr, "class_methods", &chain);
477
478 objc_finish_struct (objc_protocol_template, decls);
479}
480
587ae1e3 481/* --- names, decls + identifiers --- */
d764a8e6
IS
482
483static void
484build_selector_table_decl (void)
485{
486 tree temp;
487
488 build_selector_template ();
489 temp = build_array_type (objc_selector_template, NULL_TREE);
490
491 UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
492 OBJCMETA (UOBJC_SELECTOR_TABLE_decl, objc_meta, meta_base);
493}
494
495
496static tree
497gnu_runtime_abi_01_super_superclassfield_id (void)
498{
499 if (!super_superclassfield_id)
500 super_superclassfield_id = get_identifier ("super_class");
501 return super_superclassfield_id;
502}
503
504
505static tree
506gnu_runtime_abi_01_class_decl (tree klass)
507{
508 tree decl;
509 char buf[BUFSIZE];
944fb799 510 snprintf (buf, BUFSIZE, "_OBJC_Class_%s",
d764a8e6
IS
511 IDENTIFIER_POINTER (CLASS_NAME (klass)));
512 decl = start_var_decl (objc_class_template, buf);
513 OBJCMETA (decl, objc_meta, meta_base);
514 return decl;
515}
516
517static tree
518gnu_runtime_abi_01_metaclass_decl (tree klass)
519{
520 tree decl;
521 char buf[BUFSIZE];
944fb799 522 snprintf (buf, BUFSIZE, "_OBJC_MetaClass_%s",
d764a8e6
IS
523 IDENTIFIER_POINTER (CLASS_NAME (klass)));
524 decl = start_var_decl (objc_class_template, buf);
525 OBJCMETA (decl, objc_meta, meta_base);
526 return decl;
527}
528
529static tree
530gnu_runtime_abi_01_category_decl (tree klass)
531{
532 tree decl;
533 char buf[BUFSIZE];
944fb799 534 snprintf (buf, BUFSIZE, "_OBJC_Category_%s_on_%s",
d764a8e6
IS
535 IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass)),
536 IDENTIFIER_POINTER (CLASS_NAME (klass)));
537 decl = start_var_decl (objc_category_template, buf);
538 OBJCMETA (decl, objc_meta, meta_base);
539 return decl;
540}
541
542static tree
543gnu_runtime_abi_01_protocol_decl (tree p)
544{
545 tree decl;
546 char buf[BUFSIZE];
547
548 /* static struct _objc_protocol _OBJC_Protocol_<mumble>; */
549 snprintf (buf, BUFSIZE, "_OBJC_Protocol_%s",
550 IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
551 decl = start_var_decl (objc_protocol_template, buf);
552 OBJCMETA (decl, objc_meta, meta_base);
553 return decl;
554}
555
556static tree
944fb799 557gnu_runtime_abi_01_string_decl (tree type, const char *name,
d764a8e6
IS
558 string_section where ATTRIBUTE_UNUSED)
559{
560 tree decl = start_var_decl (type, name);
561 OBJCMETA (decl, objc_meta, meta_base);
562 return decl;
563}
564
565/* --- entry --- */
566
567static tree
568gnu_runtime_abi_01_get_class_reference (tree ident)
569{
570 tree params;
571
572 add_class_reference (ident);
573
944fb799 574 params = build_tree_list (NULL_TREE, my_build_string_pointer
d764a8e6
IS
575 (IDENTIFIER_LENGTH (ident) + 1,
576 IDENTIFIER_POINTER (ident)));
577
d764a8e6
IS
578 return build_function_call (input_location, objc_get_class_decl, params);
579}
580
6174da1b
NF
581/* Used by build_function_type_for_method. Append the types for
582 receiver & _cmd at the start of a method argument list to ARGTYPES.
583 CONTEXT is either METHOD_DEF or METHOD_REF, saying whether we are
584 trying to define a method or call one. SUPERFLAG says this is for a
585 send to super. METH may be NULL, in the case that there is no
586 prototype. */
d764a8e6 587
6174da1b 588static void
9771b263
DN
589gnu_runtime_abi_01_get_arg_type_list_base (vec<tree, va_gc> **argtypes,
590 tree meth, int context,
d764a8e6
IS
591 int superflag ATTRIBUTE_UNUSED)
592{
6174da1b 593 tree receiver_type;
d764a8e6 594
d764a8e6 595 if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
6174da1b 596 receiver_type = objc_instance_type;
d764a8e6 597 else
6174da1b 598 receiver_type = objc_object_type;
d764a8e6 599
9771b263 600 vec_safe_push (*argtypes, receiver_type);
d764a8e6 601 /* Selector type - will eventually change to `int'. */
9771b263 602 vec_safe_push (*argtypes, objc_selector_type);
d764a8e6
IS
603}
604
605/* Unused for GNU runtime. */
606static tree
607gnu_runtime_abi_01_receiver_is_class_object (tree a ATTRIBUTE_UNUSED)
608{
609 return NULL_TREE;
610}
611
612/* sel_ref_chain is a list whose "value" fields will be instances of
613 identifier_node that represent the selector. LOC is the location of
614 the @selector. */
615
616static tree
617gnu_runtime_abi_01_build_typed_selector_reference (location_t loc, tree ident,
618 tree prototype)
619{
620 tree *chain = &sel_ref_chain;
621 tree expr;
622 int index = 0;
623
624 while (*chain)
625 {
944fb799 626 /* When we do a lookup for @selector () we have no idea of the
d764a8e6 627 prototype - so match the first we find. */
944fb799 628 if (TREE_VALUE (*chain) == ident
d764a8e6
IS
629 && (!prototype || TREE_PURPOSE (*chain) == prototype))
630 goto return_at_index;
631
632 index++;
633 chain = &TREE_CHAIN (*chain);
634 }
635
636 *chain = tree_cons (prototype, ident, NULL_TREE);
637
944fb799 638 /* TODO: Use a vec and keep this in it to (a) avoid re-creating and
d764a8e6
IS
639 (b) provide better diagnostics for the first time an undefined
640 selector is used. */
641 return_at_index:
642 expr = build_unary_op (loc, ADDR_EXPR,
643 build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
644 build_int_cst (NULL_TREE, index)),
645 1);
646 return convert (objc_selector_type, expr);
647}
648
649/* Build a tree expression to send OBJECT the operation SELECTOR,
650 looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
651 assuming the method has prototype METHOD_PROTOTYPE.
652 (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
653 LOC is the location of the expression to build.
654 Use METHOD_PARAMS as list of args to pass to the method.
655 If SUPER_FLAG is nonzero, we look up the superclass's method. */
656
657static tree
658build_objc_method_call (location_t loc, int super_flag, tree method_prototype,
659 tree lookup_object, tree selector,
660 tree method_params)
661{
944fb799 662 tree sender = (super_flag ? umsg_super_decl
d764a8e6
IS
663 : (flag_objc_direct_dispatch ? umsg_fast_decl
664 : umsg_decl));
665 tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
9771b263
DN
666 vec<tree, va_gc> *parms;
667 vec<tree, va_gc> *tv;
d764a8e6
IS
668 unsigned nparm = (method_params ? list_length (method_params) : 0);
669
670 /* If a prototype for the method to be called exists, then cast
671 the sender's return type and arguments to match that of the method.
672 Otherwise, leave sender as is. */
673 tree ret_type
674 = (method_prototype
675 ? TREE_VALUE (TREE_TYPE (method_prototype))
676 : objc_object_type);
6174da1b
NF
677 tree ftype
678 = build_function_type_for_method (ret_type, method_prototype,
679 METHOD_REF, super_flag);
d764a8e6
IS
680 tree sender_cast;
681 tree method, t;
682
683 if (method_prototype && METHOD_TYPE_ATTRIBUTES (method_prototype))
944fb799
MS
684 ftype = build_type_attribute_variant (ftype,
685 METHOD_TYPE_ATTRIBUTES
d764a8e6
IS
686 (method_prototype));
687
688 sender_cast = build_pointer_type (ftype);
689
690 lookup_object = build_c_cast (loc, rcv_p, lookup_object);
691
692 /* Use SAVE_EXPR to avoid evaluating the receiver twice. */
693 lookup_object = save_expr (lookup_object);
694
695 /* Param list + 2 slots for object and selector. */
9771b263
DN
696 vec_alloc (parms, nparm + 2);
697 vec_alloc (tv, 2);
d764a8e6
IS
698
699 /* First, call the lookup function to get a pointer to the method,
700 then cast the pointer, then call it with the method arguments. */
9771b263
DN
701 tv->quick_push (lookup_object);
702 tv->quick_push (selector);
d764a8e6 703 method = build_function_call_vec (loc, sender, tv, NULL);
9771b263 704 vec_free (tv);
d764a8e6
IS
705
706 /* Pass the appropriate object to the method. */
9771b263 707 parms->quick_push ((super_flag ? self_decl : lookup_object));
d764a8e6
IS
708
709 /* Pass the selector to the method. */
9771b263 710 parms->quick_push (selector);
d764a8e6
IS
711 /* Now append the remainder of the parms. */
712 if (nparm)
713 for (; method_params; method_params = TREE_CHAIN (method_params))
9771b263 714 parms->quick_push (TREE_VALUE (method_params));
d764a8e6
IS
715
716 /* Build an obj_type_ref, with the correct cast for the method call. */
717 t = build3 (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
718 t = build_function_call_vec (loc, t, parms, NULL);
9771b263 719 vec_free (parms);
d764a8e6
IS
720 return t;
721}
722
723static tree
724gnu_runtime_abi_01_build_objc_method_call (location_t loc,
725 tree method_prototype,
726 tree receiver,
727 tree rtype ATTRIBUTE_UNUSED,
728 tree sel_name,
729 tree method_params,
730 int super ATTRIBUTE_UNUSED)
731{
944fb799
MS
732 tree selector =
733 gnu_runtime_abi_01_build_typed_selector_reference (loc,
734 sel_name,
d764a8e6
IS
735 method_prototype);
736
737 return build_objc_method_call (loc, super, method_prototype, receiver,
738 selector, method_params);
739}
740
741static tree
742gnu_runtime_abi_01_get_protocol_reference (location_t loc, tree p)
743{
744 tree expr, protocol_struct_type, *chain;
745 if (!PROTOCOL_FORWARD_DECL (p))
746 PROTOCOL_FORWARD_DECL (p) = gnu_runtime_abi_01_protocol_decl (p);
747
748 expr = build_unary_op (loc, ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
749
750 /* ??? Ideally we'd build the reference with objc_protocol_type directly,
751 if we have it, rather than converting it here. */
752 expr = convert (objc_protocol_type, expr);
753
754 /* The @protocol() expression is being compiled into a pointer to a
755 statically allocated instance of the Protocol class. To become
756 usable at runtime, the 'isa' pointer of the instance need to be
757 fixed up at runtime by the runtime library, to point to the
758 actual 'Protocol' class. */
759
760 /* For the GNU runtime, put the static Protocol instance in the list
761 of statically allocated instances, so that we make sure that its
762 'isa' pointer is fixed up at runtime by the GNU runtime library
763 to point to the Protocol class (at runtime, when loading the
764 module, the GNU runtime library loops on the statically allocated
765 instances (as found in the defs field in objc_symtab) and fixups
766 all the 'isa' pointers of those objects). */
767
768 /* This type is a struct containing the fields of a Protocol
769 object. (Cfr. objc_protocol_type instead is the type of a pointer
770 to such a struct). */
944fb799 771 protocol_struct_type = xref_tag (RECORD_TYPE,
d764a8e6
IS
772 get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
773
774 /* Look for the list of Protocol statically allocated instances
775 to fixup at runtime. Create a new list to hold Protocol
776 statically allocated instances, if the list is not found. At
777 present there is only another list, holding NSConstantString
778 static instances to be fixed up at runtime. */
779
780 for (chain = &objc_static_instances;
781 *chain && TREE_VALUE (*chain) != protocol_struct_type;
782 chain = &TREE_CHAIN (*chain));
783
784 if (!*chain)
785 {
786 *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
787 add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
788 class_names);
789 }
790
791 /* Add this statically allocated instance to the Protocol list. */
792 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
793 PROTOCOL_FORWARD_DECL (p),
794 TREE_PURPOSE (*chain));
795 return expr;
796}
797
d4c433f9 798/* For ABI 8 an IVAR is just a fixed offset in the class struct. */
d764a8e6
IS
799
800static tree
944fb799 801gnu_runtime_abi_01_build_ivar_ref (location_t loc ATTRIBUTE_UNUSED,
d764a8e6
IS
802 tree base, tree id)
803{
804 return objc_build_component_ref (base, id);
805}
806
807/* We build super class references as we need them (but keep them once
808 built for the sake of efficiency). */
809
810static tree
944fb799 811gnu_runtime_abi_01_get_class_super_ref (location_t loc ATTRIBUTE_UNUSED,
d764a8e6
IS
812 struct imp_entry *imp, bool inst_meth)
813{
814 if (inst_meth)
815 {
816 if (!ucls_super_ref)
944fb799
MS
817 ucls_super_ref =
818 objc_build_component_ref (imp->class_decl,
d764a8e6
IS
819 get_identifier ("super_class"));
820 return ucls_super_ref;
821 }
822 else
823 {
824 if (!uucls_super_ref)
944fb799
MS
825 uucls_super_ref =
826 objc_build_component_ref (imp->meta_decl,
d764a8e6
IS
827 get_identifier ("super_class"));
828 return uucls_super_ref;
829 }
830}
831
832static tree
944fb799 833gnu_runtime_abi_01_get_category_super_ref (location_t loc ATTRIBUTE_UNUSED,
d764a8e6
IS
834 struct imp_entry *imp, bool inst_meth)
835{
836 tree super_name = CLASS_SUPER_NAME (imp->imp_template);
837 tree super_class;
838
839 add_class_reference (super_name);
840 super_class = (inst_meth ? objc_get_class_decl : objc_get_meta_class_decl);
d764a8e6
IS
841 super_name = my_build_string_pointer (IDENTIFIER_LENGTH (super_name) + 1,
842 IDENTIFIER_POINTER (super_name));
843 /* super_class = get_{meta_}class("CLASS_SUPER_NAME"); */
844 return build_function_call (input_location,
845 super_class,
846 build_tree_list (NULL_TREE, super_name));
847}
848
849static bool
850gnu_runtime_abi_01_setup_const_string_class_decl (void)
851{
852 /* Do nothing, and create no error. */
853 return true;
854}
855
856/* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */
857
858static GTY(()) int num_static_inst;
859
860static tree
861objc_add_static_instance (tree constructor, tree class_decl)
862{
863 tree *chain, decl;
864 char buf[BUFSIZE];
865
866 /* Find the list of static instances for the CLASS_DECL. Create one if
867 not found. */
868 for (chain = &objc_static_instances;
869 *chain && TREE_VALUE (*chain) != class_decl;
870 chain = &TREE_CHAIN (*chain));
871 if (!*chain)
872 {
873 *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
874 add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
875 }
876
877 snprintf (buf, BUFSIZE, "_OBJC_INSTANCE_%d", num_static_inst++);
878 decl = build_decl (input_location,
879 VAR_DECL, get_identifier (buf), class_decl);
880 TREE_STATIC (decl) = 1;
881 DECL_ARTIFICIAL (decl) = 1;
882 TREE_USED (decl) = 1;
883 DECL_INITIAL (decl) = constructor;
884 DECL_CONTEXT (decl) = NULL;
885 OBJCMETA (decl, objc_meta, meta_base);
886
887 /* We may be writing something else just now.
944fb799 888 Postpone till end of input. */
d764a8e6
IS
889 DECL_DEFER_OUTPUT (decl) = 1;
890 pushdecl_top_level (decl);
891 rest_of_decl_compilation (decl, 1, 0);
892
893 /* Add the DECL to the head of this CLASS' list. */
894 TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
895
896 return decl;
897}
898
899static tree
900gnu_runtime_abi_01_build_const_string_constructor (location_t loc, tree string,
901 int length)
902{
903 tree constructor, fields;
9771b263 904 vec<constructor_elt, va_gc> *v = NULL;
944fb799 905
d764a8e6
IS
906 /* GNU: (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length }) */
907 fields = TYPE_FIELDS (internal_const_str_type);
908 CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, 0));
909
910 fields = DECL_CHAIN (fields);
944fb799 911 CONSTRUCTOR_APPEND_ELT (v, fields, build_unary_op (loc,
d764a8e6
IS
912 ADDR_EXPR, string, 1));
913
914 fields = DECL_CHAIN (fields);
915 CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, length));
916 constructor = objc_build_constructor (internal_const_str_type, v);
917
918 constructor = objc_add_static_instance (constructor, constant_string_type);
919 return constructor;
920}
921
922/* --- metadata - module initializer --- */
923
924/* The GNU runtime requires us to provide a static initializer function
925 for each module:
926
927 static void __objc_gnu_init (void) {
928 __objc_exec_class (&L_OBJC_MODULES);
929 } */
930
931
932static void
933build_module_initializer_routine (void)
934{
935 tree body;
936
937#ifdef OBJCPLUS
938 push_lang_context (lang_name_c); /* extern "C" */
939#endif
940
941 objc_push_parm (build_decl (input_location,
942 PARM_DECL, NULL_TREE, void_type_node));
943#ifdef OBJCPLUS
944 objc_start_function (get_identifier (TAG_GNUINIT),
945 build_function_type_list (void_type_node, NULL_TREE),
946 NULL_TREE, NULL_TREE);
947#else
948 objc_start_function (get_identifier (TAG_GNUINIT),
949 build_function_type_list (void_type_node, NULL_TREE),
a04a722b 950 NULL_TREE, objc_get_parm_info (0, NULL_TREE));
d764a8e6
IS
951#endif
952 body = c_begin_compound_stmt (true);
953 add_stmt (build_function_call
954 (input_location,
955 execclass_decl,
956 build_tree_list
957 (NULL_TREE,
958 build_unary_op (input_location, ADDR_EXPR,
959 UOBJC_MODULES_decl, 0))));
960 add_stmt (c_end_compound_stmt (input_location, body, true));
961
962 TREE_PUBLIC (current_function_decl) = 0;
963
964#ifndef OBJCPLUS
965 /* For Objective-C++, we will need to call __objc_gnu_init
966 from objc_generate_static_init_call() below. */
967 DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
968#endif
969
970 GNU_INIT_decl = current_function_decl;
971 finish_function ();
972
973#ifdef OBJCPLUS
974 pop_lang_context ();
975#endif
976}
977
978#ifdef OBJCPLUS
979/* Return 1 if the __objc_gnu_init function has been synthesized and needs
980 to be called by the module initializer routine. */
981
982int
983objc_static_init_needed_p (void)
984{
985 return (GNU_INIT_decl != NULL_TREE);
986}
987
988/* Generate a call to the __objc_gnu_init initializer function. */
989
990tree
991objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
992{
993 add_stmt (build_stmt (input_location, EXPR_STMT,
994 build_function_call (input_location,
995 GNU_INIT_decl, NULL_TREE)));
996
997 return ctors;
998}
999#endif /* OBJCPLUS */
1000
1001/* --- Output GNU Meta-data --- */
1002
1003static void
1004generate_classref_translation_entry (tree chain)
1005{
1006 tree expr, decl, type;
1007
1008 decl = TREE_PURPOSE (chain);
1009 type = TREE_TYPE (decl);
1010
1011 expr = add_objc_string (TREE_VALUE (chain), class_names);
1012 expr = convert (type, expr); /* cast! */
1013
1014 /* This is a class reference. It is re-written by the runtime,
1015 but will be optimized away unless we force it. */
1016 DECL_PRESERVE_P (decl) = 1;
1017 OBJCMETA (decl, objc_meta, meta_base);
1018 finish_var_decl (decl, expr);
1019 return;
1020}
1021
1022
1023static void
1024handle_impent (struct imp_entry *impent)
1025{
1026 char *string;
1027
1028/* objc_implementation_context = impent->imp_context;
1029 implementation_template = impent->imp_template;*/
1030
1031 switch (TREE_CODE (impent->imp_context))
1032 {
1033 case CLASS_IMPLEMENTATION_TYPE:
1034 {
1035 const char *const class_name =
1036 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
944fb799 1037
d764a8e6 1038 string = (char *) alloca (strlen (class_name) + 30);
944fb799 1039
d764a8e6
IS
1040 sprintf (string, "__objc_class_name_%s", class_name);
1041 break;
1042 }
1043 case CATEGORY_IMPLEMENTATION_TYPE:
1044 {
1045 const char *const class_name =
1046 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
1047 const char *const class_super_name =
1048 IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
944fb799 1049
d764a8e6
IS
1050 string = (char *) alloca (strlen (class_name)
1051 + strlen (class_super_name) + 30);
944fb799 1052
d764a8e6
IS
1053 /* Do the same for categories. Even though no references to
1054 these symbols are generated automatically by the compiler,
1055 it gives you a handle to pull them into an archive by
1056 hand. */
1057 sprintf (string, "*__objc_category_name_%s_%s", class_name, class_super_name);
1058 break;
1059 }
1060 default:
1061 return;
1062 }
1063
1064 {
1065 tree decl, init;
1066
1067 init = integer_zero_node;
1068 decl = build_decl (input_location,
1069 VAR_DECL, get_identifier (string), TREE_TYPE (init));
1070 TREE_PUBLIC (decl) = 1;
1071 TREE_READONLY (decl) = 1;
1072 TREE_USED (decl) = 1;
1073 TREE_CONSTANT (decl) = 1;
1074 DECL_CONTEXT (decl) = NULL_TREE;
1075 DECL_ARTIFICIAL (decl) = 1;
1076 TREE_STATIC (decl) = 1;
1077 DECL_INITIAL (decl) = error_mark_node; /* A real initializer is coming... */
1078 /* We must force the reference. */
1079 DECL_PRESERVE_P (decl) = 1;
1080
1081 finish_var_decl(decl, init) ;
1082 }
1083}
1084
1085tree
1086build_protocol_initializer (tree type, tree protocol_name, tree protocol_list,
1087 tree inst_methods, tree class_methods)
1088{
1089 tree expr, ttyp;
1090 location_t loc;
9771b263 1091 vec<constructor_elt, va_gc> *inits = NULL;
d764a8e6
IS
1092
1093 /* TODO: pass the loc in or find it from args. */
1094 loc = input_location;
944fb799 1095 ttyp = build_pointer_type (xref_tag (RECORD_TYPE,
d764a8e6
IS
1096 get_identifier (UTAG_CLASS)));
1097 /* Filling the "isa" in with a version allows the runtime system to
1098 detect this ... */
1099 expr = build_int_cst (ttyp, PROTOCOL_VERSION);
1100
1101 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
1102
1103 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_name);
1104 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_list);
1105
1106 ttyp = objc_method_proto_list_ptr;
1107 if (inst_methods)
1108 expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, inst_methods, 0));
1109 else
1110 expr = convert (ttyp, null_pointer_node);
1111 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
1112
1113 if (class_methods)
1114 expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, class_methods, 0));
1115 else
1116 expr = convert (ttyp, null_pointer_node);
1117 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
1118
1119 return objc_build_constructor (type, inits);
1120}
1121
1122static tree
1123generate_protocol_list (tree i_or_p, tree klass_ctxt)
1124{
1125 tree array_type, ptype, refs_decl, lproto, e, plist;
9771b263 1126 vec<constructor_elt, va_gc> *v = NULL;
d764a8e6
IS
1127 char buf[BUFSIZE];
1128 int size = 0;
1129
1130 switch (TREE_CODE (i_or_p))
1131 {
1132 case CLASS_INTERFACE_TYPE:
1133 case CATEGORY_INTERFACE_TYPE:
1134 plist = CLASS_PROTOCOL_LIST (i_or_p);
1135 break;
1136 case PROTOCOL_INTERFACE_TYPE:
1137 plist = PROTOCOL_LIST (i_or_p);
1138 break;
1139 default:
1140 gcc_unreachable ();
1141 }
1142
1143 /* Compute size. */
1144 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
1145 if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
1146 && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
1147 size++;
1148
1149 /* Build initializer. */
1150 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1151 e = build_int_cst (build_pointer_type (objc_protocol_template), size);
1152 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
1153
1154 for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
1155 {
1156 tree pval = TREE_VALUE (lproto);
1157
1158 if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
1159 && PROTOCOL_FORWARD_DECL (pval))
1160 {
1161 tree fwref = PROTOCOL_FORWARD_DECL (pval);
1162 location_t loc = DECL_SOURCE_LOCATION (fwref) ;
1163 e = build_unary_op (loc, ADDR_EXPR, fwref, 0);
1164 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
1165 }
1166 }
1167
1168 /* static struct objc_protocol *refs[n]; */
1169
1170 switch (TREE_CODE (i_or_p))
1171 {
1172 case PROTOCOL_INTERFACE_TYPE:
944fb799 1173 snprintf (buf, BUFSIZE, "_OBJC_ProtocolRefs_%s",
d764a8e6
IS
1174 IDENTIFIER_POINTER (PROTOCOL_NAME (i_or_p)));
1175 break;
1176 case CLASS_INTERFACE_TYPE:
944fb799 1177 snprintf (buf, BUFSIZE, "_OBJC_ClassProtocols_%s",
d764a8e6
IS
1178 IDENTIFIER_POINTER (CLASS_NAME (i_or_p)));
1179 break;
1180 case CATEGORY_INTERFACE_TYPE:
944fb799 1181 snprintf (buf, BUFSIZE, "_OBJC_CategoryProtocols_%s_%s",
d764a8e6
IS
1182 IDENTIFIER_POINTER (CLASS_NAME (klass_ctxt)),
1183 IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass_ctxt)));
1184 break;
1185 default:
1186 gcc_unreachable ();
1187 }
1188
1189 ptype = build_pointer_type (objc_protocol_template);
1190 array_type = build_sized_array_type (ptype, size + 3);
1191 refs_decl = start_var_decl (array_type, buf);
1192 OBJCMETA (refs_decl, objc_meta, meta_base);
1193 finish_var_decl (refs_decl,
1194 objc_build_constructor (TREE_TYPE (refs_decl), v));
1195
1196 return refs_decl;
1197}
1198
944fb799 1199static tree
d764a8e6
IS
1200generate_v1_meth_descriptor_table (tree chain, tree protocol, const char *prefix)
1201{
1202 tree method_list_template, initlist, decl;
1203 int size;
9771b263 1204 vec<constructor_elt, va_gc> *v = NULL;
d764a8e6
IS
1205 char buf[BUFSIZE];
1206
1207 if (!chain || !prefix)
1208 return NULL_TREE;
1209
1210 if (!objc_method_prototype_template)
1211 objc_method_prototype_template = build_method_prototype_template ();
944fb799 1212
d764a8e6 1213 size = list_length (chain);
944fb799 1214 method_list_template =
d764a8e6
IS
1215 build_method_prototype_list_template (objc_method_prototype_template,
1216 size);
944fb799 1217 snprintf (buf, BUFSIZE, "%s_%s", prefix,
d764a8e6
IS
1218 IDENTIFIER_POINTER (PROTOCOL_NAME (protocol)));
1219
1220 decl = start_var_decl (method_list_template, buf);
1221
1222 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, size));
944fb799 1223 initlist =
d764a8e6
IS
1224 build_descriptor_table_initializer (objc_method_prototype_template,
1225 chain);
1226 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, initlist);
1227 OBJCMETA (decl, objc_meta, meta_base);
1228 finish_var_decl (decl, objc_build_constructor (method_list_template, v));
1229 return decl;
1230}
1231
1232/* For each protocol which was referenced either from a @protocol()
1233 expression, or because a class/category implements it (then a
1234 pointer to the protocol is stored in the struct describing the
1235 class/category), we create a statically allocated instance of the
1236 Protocol class. The code is written in such a way as to generate
1237 as few Protocol objects as possible; we generate a unique Protocol
1238 instance for each protocol, and we don't generate a Protocol
1239 instance if the protocol is never referenced (either from a
1240 @protocol() or from a class/category implementation). These
1241 statically allocated objects can be referred to via the static
1242 (that is, private to this module) symbols _OBJC_PROTOCOL_n.
1243
1244 The statically allocated Protocol objects that we generate here
1245 need to be fixed up at runtime in order to be used: the 'isa'
1246 pointer of the objects need to be set up to point to the 'Protocol'
1247 class, as known at runtime.
1248
1249 The GNU runtime fixes up all protocols before user code from the module
1250 is executed; it requires pointers to those symbols
1251 to be put in the objc_symtab (which is then passed as argument to
1252 the function __objc_exec_class() which the compiler sets up to be
1253 executed automatically when the module is loaded); setup of those
1254 Protocol objects happen in two ways in the GNU runtime: all
1255 Protocol objects referred to by a class or category implementation
1256 are fixed up when the class/category is loaded; all Protocol
1257 objects referred to by a @protocol() expression are added by the
1258 compiler to the list of statically allocated instances to fixup
1259 (the same list holding the statically allocated constant string
1260 objects). Because, as explained above, the compiler generates as
1261 few Protocol objects as possible, some Protocol object might end up
1262 being referenced multiple times when compiled with the GNU runtime,
1263 and end up being fixed up multiple times at runtime initialization.
1264 But that doesn't hurt, it's just a little inefficient. */
1265
1266static void
1267generate_protocols (void)
1268{
1269 tree p, encoding;
1270 tree decl;
1271 tree initlist, protocol_name_expr, refs_decl, refs_expr;
1272
1273 /* If a protocol was directly referenced, pull in indirect references. */
1274 for (p = protocol_chain; p; p = TREE_CHAIN (p))
1275 if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
1276 generate_protocol_references (PROTOCOL_LIST (p));
1277
1278 for (p = protocol_chain; p; p = TREE_CHAIN (p))
1279 {
1280 tree nst_methods = PROTOCOL_NST_METHODS (p);
1281 tree cls_methods = PROTOCOL_CLS_METHODS (p);
1282
1283 /* If protocol wasn't referenced, don't generate any code. */
1284 decl = PROTOCOL_FORWARD_DECL (p);
1285
1286 if (!decl)
1287 continue;
1288
1289 /* Make sure we link in the Protocol class. */
1290 add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
1291
1292 while (nst_methods)
1293 {
1294 if (! METHOD_ENCODING (nst_methods))
1295 {
1296 encoding = encode_method_prototype (nst_methods);
1297 METHOD_ENCODING (nst_methods) = encoding;
1298 }
1299 nst_methods = DECL_CHAIN (nst_methods);
1300 }
1301
944fb799 1302 UOBJC_INSTANCE_METHODS_decl =
d764a8e6
IS
1303 generate_v1_meth_descriptor_table (PROTOCOL_NST_METHODS (p), p,
1304 "_OBJC_PROTOCOL_INSTANCE_METHODS");
1305
1306 while (cls_methods)
1307 {
1308 if (! METHOD_ENCODING (cls_methods))
1309 {
1310 encoding = encode_method_prototype (cls_methods);
1311 METHOD_ENCODING (cls_methods) = encoding;
1312 }
1313
1314 cls_methods = DECL_CHAIN (cls_methods);
1315 }
1316
944fb799 1317 UOBJC_CLASS_METHODS_decl =
d764a8e6
IS
1318 generate_v1_meth_descriptor_table (PROTOCOL_CLS_METHODS (p), p,
1319 "_OBJC_PROTOCOL_CLASS_METHODS");
1320/* generate_method_descriptors (p);*/
1321
1322 if (PROTOCOL_LIST (p))
1323 refs_decl = generate_protocol_list (p, NULL_TREE);
1324 else
1325 refs_decl = 0;
1326
1327 /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
1328 protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
1329
1330 if (refs_decl)
1331 refs_expr = convert (build_pointer_type (build_pointer_type
1332 (objc_protocol_template)),
1333 build_unary_op (input_location,
1334 ADDR_EXPR, refs_decl, 0));
1335 else
1336 refs_expr = build_int_cst (NULL_TREE, 0);
1337
1338 /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
1339 by generate_method_descriptors, which is called above. */
1340 initlist = build_protocol_initializer (TREE_TYPE (decl),
1341 protocol_name_expr, refs_expr,
1342 UOBJC_INSTANCE_METHODS_decl,
1343 UOBJC_CLASS_METHODS_decl);
1344 finish_var_decl (decl, initlist);
1345 }
1346}
1347
1348static tree
1349generate_dispatch_table (tree chain, const char *name)
1350{
1351 tree decl, method_list_template, initlist;
9771b263 1352 vec<constructor_elt, va_gc> *v = NULL;
d764a8e6
IS
1353 int size = list_length (chain);
1354
1355 if (!objc_method_template)
1356 objc_method_template = build_method_template ();
1357
1358 method_list_template = build_method_list_template (objc_method_template,
1359 size);
1360 initlist = build_dispatch_table_initializer (objc_method_template, chain);
1361
1362 decl = start_var_decl (method_list_template, name);
1363
1364 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
944fb799 1365 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
d764a8e6
IS
1366 build_int_cst (integer_type_node, size));
1367 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, initlist);
1368
1369 OBJCMETA (decl, objc_meta, meta_base);
1370 finish_var_decl (decl,
1371 objc_build_constructor (TREE_TYPE (decl), v));
1372
1373 return decl;
1374}
1375
1376/* Init a category. */
1377static tree
1378build_category_initializer (tree type, tree cat_name, tree class_name,
1379 tree inst_methods, tree class_methods,
1380 tree protocol_list)
1381{
1382 tree expr, ltyp;
1383 location_t loc;
9771b263 1384 vec<constructor_elt, va_gc> *v = NULL;
d764a8e6
IS
1385
1386 /* TODO: pass the loc in or find it from args. */
1387 /* TODO: pass the loc in or find it from args. */
1388 loc = UNKNOWN_LOCATION;
1389 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, cat_name);
1390 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, class_name);
1391
1392 ltyp = objc_method_list_ptr;
1393 if (inst_methods)
1394 expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, inst_methods, 0));
1395 else
1396 expr = convert (ltyp, null_pointer_node);
1397 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1398
1399 if (class_methods)
1400 expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, class_methods, 0));
1401 else
1402 expr = convert (ltyp, null_pointer_node);
1403 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1404
1405 /* protocol_list = */
1406 ltyp = build_pointer_type (build_pointer_type (objc_protocol_template));
1407 if (protocol_list)
1408 expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, protocol_list, 0));
1409 else
1410 expr = convert (ltyp, null_pointer_node);
1411 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1412
1413 return objc_build_constructor (type, v);
1414}
1415
1416/* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */
1417
1418static void
1419generate_category (struct imp_entry *impent)
1420{
1421 tree initlist, cat_name_expr, class_name_expr;
1422 tree protocol_decl, category, cat_decl;
1423 tree inst_methods = NULL_TREE, class_methods = NULL_TREE;
1424 tree cat = impent->imp_context;
1425 char buf[BUFSIZE];
1426
1427 cat_decl = impent->class_decl;
1428
1429 add_class_reference (CLASS_NAME (cat));
1430 cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
1431
1432 class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
1433
1434 category = lookup_category (impent->imp_template, CLASS_SUPER_NAME (cat));
1435
1436 if (category && CLASS_PROTOCOL_LIST (category))
1437 {
1438 generate_protocol_references (CLASS_PROTOCOL_LIST (category));
1439 protocol_decl = generate_protocol_list (category, cat);
1440 }
1441 else
1442 protocol_decl = 0;
1443
1444 if (CLASS_NST_METHODS (cat))
1445 {
1446 snprintf (buf, BUFSIZE, "_OBJC_CategoryInstanceMethods_%s_%s",
1447 IDENTIFIER_POINTER (CLASS_NAME (cat)),
1448 IDENTIFIER_POINTER (CLASS_SUPER_NAME (cat)));
1449 inst_methods = generate_dispatch_table (CLASS_NST_METHODS (cat), buf);
1450 }
1451
1452 if (CLASS_CLS_METHODS (cat))
1453 {
1454 snprintf (buf, BUFSIZE, "_OBJC_CategoryClassMethods_%s_%s",
1455 IDENTIFIER_POINTER (CLASS_NAME (cat)),
1456 IDENTIFIER_POINTER (CLASS_SUPER_NAME (cat)));
1457 class_methods = generate_dispatch_table (CLASS_CLS_METHODS (cat), buf);
1458 }
1459
1460 initlist = build_category_initializer (TREE_TYPE (cat_decl),
1461 cat_name_expr, class_name_expr,
1462 inst_methods, class_methods,
1463 protocol_decl);
1464 /* Finish and initialize the forward decl. */
1465 finish_var_decl (cat_decl, initlist);
1466 impent->class_decl = cat_decl;
1467}
1468
1469/* struct _objc_class {
1470 struct objc_class *isa;
1471 struct objc_class *super_class;
1472 char *name;
1473 long version;
1474 long info;
1475 long instance_size;
1476 struct objc_ivar_list *ivars;
1477 struct objc_method_list *methods;
d4c433f9
NP
1478 struct sarray *dtable;
1479 struct objc_class *subclass_list;
1480 struct objc_class *sibling_class;
d764a8e6 1481 struct objc_protocol_list *protocols;
d764a8e6
IS
1482 void *gc_object_type;
1483 }; */
1484
1485static tree
1486build_shared_structure_initializer (tree type, tree isa, tree super,
1487 tree name, tree size, int status,
1488 tree dispatch_table, tree ivar_list,
1489 tree protocol_list)
1490{
1491 tree expr, ltyp;
9771b263 1492 vec<constructor_elt, va_gc> *v = NULL;
d764a8e6
IS
1493
1494 /* isa = */
1495 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, isa);
1496
1497 /* super_class = */
1498 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, super);
1499
1500 /* name = */
1501 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, default_conversion (name));
1502
1503 /* version = */
1504 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1505 build_int_cst (long_integer_type_node, 0));
1506
1507 /* info = */
1508 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1509 build_int_cst (long_integer_type_node, status));
1510
1511 /* instance_size = */
1512 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1513 convert (long_integer_type_node, size));
1514
1515 /* objc_ivar_list = */
1516 if (!ivar_list)
944fb799 1517 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
d764a8e6
IS
1518 build_int_cst (objc_ivar_list_ptr, 0));
1519 else
1520 {
1521 expr = convert (objc_ivar_list_ptr,
944fb799 1522 build_unary_op (input_location, ADDR_EXPR,
d764a8e6
IS
1523 ivar_list, 0));
1524 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1525 }
1526
1527 /* objc_method_list = */
1528 if (!dispatch_table)
944fb799 1529 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
d764a8e6
IS
1530 convert (objc_method_list_ptr, null_pointer_node));
1531 else
1532 {
1533 expr = convert (objc_method_list_ptr,
944fb799 1534 build_unary_op (input_location, ADDR_EXPR,
d764a8e6
IS
1535 dispatch_table, 0));
1536 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1537 }
1538
d4c433f9 1539 /* FIXME: Remove NeXT runtime code. */
d764a8e6
IS
1540 if (flag_next_runtime)
1541 {
1542 ltyp = build_pointer_type (xref_tag (RECORD_TYPE,
1543 get_identifier ("objc_cache")));
1544 /* method_cache = */
1545 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, convert (ltyp, null_pointer_node));
1546 }
1547 else
1548 {
1549 /* dtable = */
1550 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1551
1552 /* subclass_list = */
1553 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1554
1555 /* sibling_class = */
1556 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1557 }
1558
1559 /* protocol_list = */
1560 ltyp = build_pointer_type (build_pointer_type (objc_protocol_template));
1561 if (! protocol_list)
1562 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (ltyp, 0));
1563 else
1564 {
1565 expr = convert (ltyp,
944fb799 1566 build_unary_op (input_location, ADDR_EXPR,
d764a8e6
IS
1567 protocol_list, 0));
1568 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1569 }
1570
d4c433f9 1571 /* FIXME: Remove NeXT runtime code. */
d764a8e6
IS
1572 if (flag_next_runtime)
1573 /* sel_id = NULL */
1574 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1575
1576 /* gc_object_type = NULL */
1577 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1578
1579 return objc_build_constructor (type, v);
1580}
1581
1582
1583static tree
1584generate_ivars_list (tree chain, const char *name)
1585{
1586 tree initlist, ivar_list_template, decl;
1587 int size;
9771b263 1588 vec<constructor_elt, va_gc> *inits = NULL;
d764a8e6
IS
1589
1590 if (!chain)
1591 return NULL_TREE;
1592
1593 if (!objc_ivar_template)
1594 objc_ivar_template = build_ivar_template ();
1595
1596 size = ivar_list_length (chain);
1597
1598 generating_instance_variables = 1;
1599 ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
1600 initlist = build_ivar_list_initializer (objc_ivar_template, chain);
1601 generating_instance_variables = 0;
1602
1603 decl = start_var_decl (ivar_list_template, name);
1604
1605 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, size));
1606 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, initlist);
1607
1608 OBJCMETA (decl, objc_meta, meta_base);
1609 finish_var_decl (decl,
1610 objc_build_constructor (TREE_TYPE (decl), inits));
1611
1612 return decl;
1613}
1614
1615/* static struct objc_class _OBJC_METACLASS_Foo={ ... };
1616 static struct objc_class _OBJC_CLASS_Foo={ ... }; */
1617
1618static void
1619generate_class_structures (struct imp_entry *impent)
1620{
1621 tree name_expr, super_expr, root_expr, class_decl, meta_decl;
1622 tree my_root_id, my_super_id;
1623 tree cast_type, initlist, protocol_decl;
1624 tree inst_methods = NULL_TREE, class_methods = NULL_TREE;
1625 tree chain, inst_ivars = NULL_TREE, class_ivars = NULL_TREE;
1626 location_t loc;
1627 char buf[BUFSIZE];
1628 int cls_flags = 0 ;
944fb799 1629
d764a8e6
IS
1630/* objc_implementation_context = impent->imp_context;
1631 implementation_template = impent->imp_template;*/
1632 class_decl = impent->class_decl;
1633 meta_decl = impent->meta_decl;
1634/* UOBJC_CLASS_decl = impent->class_decl;
1635 UOBJC_METACLASS_decl = impent->meta_decl;*/
944fb799 1636
d764a8e6
IS
1637 loc = DECL_SOURCE_LOCATION (impent->class_decl);
1638
1639 my_super_id = CLASS_SUPER_NAME (impent->imp_template);
1640 if (my_super_id)
1641 {
1642 add_class_reference (my_super_id);
1643
1644 /* Compute "my_root_id" - this is required for code generation.
1645 the "isa" for all meta class structures points to the root of
1646 the inheritance hierarchy (e.g. "__Object")... */
1647 my_root_id = my_super_id;
1648 do
1649 {
1650 tree my_root_int = lookup_interface (my_root_id);
1651
1652 if (my_root_int && CLASS_SUPER_NAME (my_root_int))
1653 my_root_id = CLASS_SUPER_NAME (my_root_int);
1654 else
1655 break;
1656 }
1657 while (1);
1658 }
1659 else
1660 /* No super class. */
1661 my_root_id = CLASS_NAME (impent->imp_template);
1662
1663 cast_type = build_pointer_type (objc_class_template);
1664 name_expr = add_objc_string (CLASS_NAME (impent->imp_template),
1665 class_names);
1666
1667 /* Install class `isa' and `super' pointers at runtime. */
1668 if (my_super_id)
1669 super_expr = add_objc_string (my_super_id, class_names);
1670 else
1671 super_expr = null_pointer_node;
944fb799 1672
d764a8e6
IS
1673 super_expr = build_c_cast (loc, cast_type, super_expr);
1674
1675 root_expr = add_objc_string (my_root_id, class_names);
1676 root_expr = build_c_cast (loc, cast_type, root_expr);
1677
1678 if (CLASS_PROTOCOL_LIST (impent->imp_template))
1679 {
1680 generate_protocol_references (CLASS_PROTOCOL_LIST (impent->imp_template));
1681 protocol_decl = generate_protocol_list (impent->imp_template,
1682 impent->imp_context);
1683 }
1684 else
1685 protocol_decl = NULL_TREE;
1686
1687 if (CLASS_CLS_METHODS (impent->imp_context))
1688 {
1689 snprintf (buf, BUFSIZE, "_OBJC_ClassMethods_%s",
1690 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
1691 class_methods = generate_dispatch_table (CLASS_CLS_METHODS (impent->imp_context),
1692 buf);
1693 }
1694
1695 if (CLASS_SUPER_NAME (impent->imp_template) == NULL_TREE
1696 && (chain = TYPE_FIELDS (objc_class_template)))
1697 {
1698 snprintf (buf, BUFSIZE, "_OBJC_ClassIvars_%s",
1699 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
1700 class_ivars = generate_ivars_list (chain, buf);
1701 }
1702
1703 /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
1704
944fb799
MS
1705 initlist =
1706 build_shared_structure_initializer
d764a8e6
IS
1707 (TREE_TYPE (meta_decl),
1708 root_expr, super_expr, name_expr,
944fb799 1709 convert (integer_type_node,
d764a8e6
IS
1710 TYPE_SIZE_UNIT (objc_class_template)),
1711 CLS_META, class_methods, class_ivars,
1712 protocol_decl);
1713
1714 finish_var_decl (meta_decl, initlist);
1715 impent->meta_decl = meta_decl;
1716
1717 /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
1718 if (CLASS_NST_METHODS (impent->imp_context))
1719 {
1720 snprintf (buf, BUFSIZE, "_OBJC_InstanceMethods_%s",
1721 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
1722 inst_methods = generate_dispatch_table (CLASS_NST_METHODS (impent->imp_context),
1723 buf);
1724 }
1725
1726 if ((chain = CLASS_IVARS (impent->imp_template)))
1727 {
1728 snprintf (buf, BUFSIZE, "_OBJC_InstanceIvars_%s",
1729 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
1730 inst_ivars = generate_ivars_list (chain, buf);
1731 }
1732
944fb799
MS
1733 initlist =
1734 build_shared_structure_initializer
d764a8e6
IS
1735 (TREE_TYPE (class_decl),
1736 build_unary_op (loc, ADDR_EXPR, meta_decl, 0),
1737 super_expr, name_expr,
1738 convert (integer_type_node,
1739 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
1740 (impent->imp_template))),
1741 CLS_FACTORY | cls_flags, inst_methods, inst_ivars,
1742 protocol_decl);
1743
1744 finish_var_decl (class_decl, initlist);
1745 impent->class_decl = class_decl;
1746}
1747
1748/* --- Output GNU Metadata --- */
1749
1750/* TODO: Make this into an array of refs. */
1751static void
1752handle_class_ref (tree chain)
1753{
1754 const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
1755 char *string = (char *) alloca (strlen (name) + 30);
1756 tree decl;
1757 tree exp;
1758
1759 sprintf (string, "__objc_class_name_%s", name);
1760
1761 /* Make a decl for this name, so we can use its address in a tree. */
1762 decl = build_decl (input_location,
1763 VAR_DECL, get_identifier (string), TREE_TYPE (integer_zero_node));
1764 DECL_EXTERNAL (decl) = 1;
1765 TREE_PUBLIC (decl) = 1;
1766 DECL_CONTEXT (decl) = NULL_TREE;
1767 finish_var_decl (decl, 0);
1768
1769 /* Make a decl for the address. */
1770 sprintf (string, "__objc_class_ref_%s", name);
1771 exp = build1 (ADDR_EXPR, string_type_node, decl);
1772 decl = build_decl (input_location,
1773 VAR_DECL, get_identifier (string), string_type_node);
1774 TREE_STATIC (decl) = 1;
1775 TREE_USED (decl) = 1;
1776 DECL_READ_P (decl) = 1;
1777 DECL_ARTIFICIAL (decl) = 1;
1778 DECL_INITIAL (decl) = error_mark_node;
944fb799 1779
d764a8e6
IS
1780 /* We must force the reference. */
1781 DECL_PRESERVE_P (decl) = 1;
1782
1783 DECL_CONTEXT (decl) = NULL_TREE;
1784 finish_var_decl (decl, exp);
1785}
1786
1787static tree
1788get_proto_encoding (tree proto)
1789{
1790 tree encoding;
1791 if (proto)
1792 {
1793 if (! METHOD_ENCODING (proto))
1794 {
1795 encoding = encode_method_prototype (proto);
1796 METHOD_ENCODING (proto) = encoding;
1797 }
1798 else
1799 encoding = METHOD_ENCODING (proto);
1800
1801 return add_objc_string (encoding, meth_var_types);
1802 }
1803 else
1804 return build_int_cst (NULL_TREE, 0);
1805}
1806
1807static void
1808build_gnu_selector_translation_table (void)
1809{
1810 tree chain, expr;
9771b263
DN
1811 vec<constructor_elt, va_gc> *inits = NULL;
1812 vec<constructor_elt, va_gc> *v ;
d764a8e6
IS
1813
1814 /* Cause the selector table (previously forward-declared)
1815 to be actually output. */
1816
1817 for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1818 {
1819 tree encoding;
1820 if (warn_selector)
1821 {
1822 /* TODO: improve on the location for the diagnostic. */
1823 location_t loc = input_location;
1824 diagnose_missing_method (TREE_VALUE (chain), loc);
1825 }
1826
1827 v = NULL;
1828 expr = build_selector (TREE_VALUE (chain));
1829 encoding = get_proto_encoding (TREE_PURPOSE (chain));
1830 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1831 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, encoding);
1832 expr = objc_build_constructor (objc_selector_template, v);
944fb799 1833
d764a8e6
IS
1834 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
1835 } /* each element in the chain */
1836
1837 /* List terminator. */
1838 v = NULL;
1839 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
1840 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
1841 expr = objc_build_constructor (objc_selector_template, v);
1842
1843 CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
1844 expr = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
1845 inits);
1846 finish_var_decl (UOBJC_SELECTOR_TABLE_decl, expr);
1847}
1848
1849/* Output references to all statically allocated objects. Return the DECL
1850 for the array built. */
1851
1852static void
1853generate_static_references (void)
1854{
1855 tree expr = NULL_TREE;
1856 tree class_name, klass, decl;
1857 tree cl_chain, in_chain, type
1858 = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
1859 int num_inst, num_class;
1860 char buf[BUFSIZE];
9771b263 1861 vec<constructor_elt, va_gc> *decls = NULL;
d764a8e6 1862
d4c433f9 1863 /* FIXME: Remove NeXT runtime code. */
d764a8e6
IS
1864 if (flag_next_runtime)
1865 gcc_unreachable ();
1866
1867 for (cl_chain = objc_static_instances, num_class = 0;
1868 cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1869 {
9771b263 1870 vec<constructor_elt, va_gc> *v = NULL;
d764a8e6
IS
1871
1872 for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1873 in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1874
1875 snprintf (buf, BUFSIZE, "_OBJC_STATIC_INSTANCES_%d", num_class);
1876 decl = start_var_decl (type, buf);
1877
1878 /* Output {class_name, ...}. */
1879 klass = TREE_VALUE (cl_chain);
1880 class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names);
1881 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
944fb799 1882 build_unary_op (input_location,
d764a8e6
IS
1883 ADDR_EXPR, class_name, 1));
1884
1885 /* Output {..., instance, ...}. */
1886 for (in_chain = TREE_PURPOSE (cl_chain);
1887 in_chain; in_chain = TREE_CHAIN (in_chain))
1888 {
1889 expr = build_unary_op (input_location,
1890 ADDR_EXPR, TREE_VALUE (in_chain), 1);
1891 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1892 }
1893
1894 /* Output {..., NULL}. */
1895 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1896
1897 expr = objc_build_constructor (TREE_TYPE (decl), v);
1898 OBJCMETA (decl, objc_meta, meta_base);
1899 finish_var_decl (decl, expr);
1900 CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE,
1901 build_unary_op (input_location,
1902 ADDR_EXPR, decl, 1));
1903 }
1904
1905 CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE, build_int_cst (NULL_TREE, 0));
1906 expr = objc_build_constructor (type, decls);
1907 static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
1908 OBJCMETA (static_instances_decl, objc_meta, meta_base);
1909 finish_var_decl (static_instances_decl, expr);
1910}
1911
1912/* Create the initial value for the `defs' field of _objc_symtab.
1913 This is a CONSTRUCTOR. */
1914
1915static tree
1916init_def_list (tree type)
1917{
1918 tree expr;
1919 struct imp_entry *impent;
1920 location_t loc;
9771b263 1921 vec<constructor_elt, va_gc> *v = NULL;
d764a8e6
IS
1922
1923 if (imp_count)
1924 for (impent = imp_list; impent; impent = impent->next)
1925 {
1926 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1927 {
1928 loc = DECL_SOURCE_LOCATION (impent->class_decl);
1929 expr = build_unary_op (loc,
1930 ADDR_EXPR, impent->class_decl, 0);
1931 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1932 }
1933 }
1934
1935 if (cat_count)
1936 for (impent = imp_list; impent; impent = impent->next)
1937 {
1938 if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1939 {
1940 loc = DECL_SOURCE_LOCATION (impent->class_decl);
1941 expr = build_unary_op (loc,
1942 ADDR_EXPR, impent->class_decl, 0);
1943 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1944 }
1945 }
1946
1947 loc = UNKNOWN_LOCATION;
1948 /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */
1949 if (static_instances_decl)
1950 expr = build_unary_op (loc, ADDR_EXPR, static_instances_decl, 0);
1951 else
1952 expr = integer_zero_node;
1953 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1954
1955 return objc_build_constructor (type, v);
1956}
1957
1958/* Take care of defining and initializing _OBJC_SYMBOLS. */
1959
1960/* Predefine the following data type:
1961
1962 struct _objc_symtab
1963 {
1964 long sel_ref_cnt;
1965 SEL *refs;
1966 short cls_def_cnt;
1967 short cat_def_cnt;
1968 void *defs[cls_def_cnt + cat_def_cnt];
1969 }; */
1970
1971static void
1972build_objc_symtab_template (void)
1973{
1974 tree fields, array_type, *chain = NULL;
1975 int index;
1976
1977 objc_symtab_template = objc_start_struct (get_identifier (UTAG_SYMTAB));
1978
1979 /* long sel_ref_cnt; */
1980 fields = add_field_decl (long_integer_type_node, "sel_ref_cnt", &chain);
1981
1982 /* SEL *refs; */
1983 add_field_decl (build_pointer_type (objc_selector_type), "refs", &chain);
1984
1985 /* short cls_def_cnt; */
1986 add_field_decl (short_integer_type_node, "cls_def_cnt", &chain);
1987
1988 /* short cat_def_cnt; */
1989 add_field_decl (short_integer_type_node, "cat_def_cnt", &chain);
1990
6d549148 1991 /* Note that padding will be added here on LP64. */
d764a8e6
IS
1992
1993 /* void *defs[imp_count + cat_count (+ 1)]; */
1994 /* NB: The index is one less than the size of the array. */
1995 index = imp_count + cat_count;
1996 array_type = build_sized_array_type (ptr_type_node, index + 1);
1997 add_field_decl (array_type, "defs", &chain);
1998
1999 objc_finish_struct (objc_symtab_template, fields);
2000}
2001/* Construct the initial value for all of _objc_symtab. */
2002
2003static tree
2004init_objc_symtab (tree type)
2005{
2006 tree field, expr, ltyp;
2007 location_t loc;
9771b263 2008 vec<constructor_elt, va_gc> *v = NULL;
d764a8e6
IS
2009
2010 loc = UNKNOWN_LOCATION;
2011
2012 /* sel_ref_cnt = { ..., 5, ... } */
2013
2014 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2015 build_int_cst (long_integer_type_node, 0));
2016
2017 /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2018
2019 ltyp = build_pointer_type (objc_selector_type);
2020 if (sel_ref_chain)
944fb799 2021 expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR,
d764a8e6
IS
2022 UOBJC_SELECTOR_TABLE_decl, 1));
2023 else
2024 expr = convert (ltyp, null_pointer_node);
2025 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2026
2027 /* cls_def_cnt = { ..., 5, ... } */
2028
944fb799 2029 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
d764a8e6
IS
2030 build_int_cst (short_integer_type_node, imp_count));
2031
2032 /* cat_def_cnt = { ..., 5, ... } */
2033
944fb799 2034 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
d764a8e6 2035 build_int_cst (short_integer_type_node, cat_count));
d4c433f9 2036
d764a8e6
IS
2037 /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2038
2039 field = TYPE_FIELDS (type);
d764a8e6
IS
2040 field = DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (field))));
2041
2042 CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init_def_list (TREE_TYPE (field)));
2043
2044 return objc_build_constructor (type, v);
2045}
2046
2047/* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2048 and initialized appropriately. */
2049
2050static void
2051generate_objc_symtab_decl (void)
2052{
2053 build_objc_symtab_template ();
2054 UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
2055 OBJCMETA (UOBJC_SYMBOLS_decl, objc_meta, meta_base);
2056 finish_var_decl (UOBJC_SYMBOLS_decl,
2057 init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
2058}
2059
2060static void
2061objc_generate_v1_gnu_metadata (void)
2062{
2063 struct imp_entry *impent;
2064 tree chain;
2065
2066 /* Process the static instances here because initialization of objc_symtab
2067 depends on them. */
2068 if (objc_static_instances)
2069 generate_static_references ();
2070
2071 objc_implementation_context =
2072 implementation_template =
2073 UOBJC_CLASS_decl =
2074 UOBJC_METACLASS_decl = NULL_TREE;
2075
2076 for (impent = imp_list; impent; impent = impent->next)
2077 {
2078 /* If -gen-decls is present, Dump the @interface of each class.
2079 TODO: Dump the classes in the order they were found, rather than in
2080 reverse order as we are doing now. */
2081 if (flag_gen_declaration)
2082 dump_interface (gen_declaration_file, impent->imp_context);
2083
2084 /* all of the following reference the string pool... */
2085 if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
2086 generate_class_structures (impent);
2087 else
2088 generate_category (impent);
2089 }
2090
2091 /* If we are using an array of selectors, we must always
2092 finish up the array decl even if no selectors were used. */
2093 build_gnu_selector_translation_table ();
2094
2095 if (protocol_chain)
2096 generate_protocols ();
2097
2098 /* Arrange for ObjC data structures to be initialized at run time. */
475b5d2a
NP
2099 /* FIXME: Have some more elegant way to determine if we need to
2100 generate objc_symtab_decl or not, instead of checking these
2101 global symbols. */
2102 if (imp_list || class_names_chain
2103 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain
2104 || prop_names_attr_chain)
2105 generate_objc_symtab_decl ();
2106
2107 if (imp_list || class_names_chain || objc_static_instances
2108 || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
2109 {
2110 /* Make sure that the meta-data are identified as being
2111 GNU-runtime. */
944fb799 2112 build_module_descriptor (OBJC_VERSION,
475b5d2a
NP
2113 build_tree_list (objc_meta, meta_base));
2114 build_module_initializer_routine ();
2115 }
d764a8e6
IS
2116
2117 /* Dump the class references. This forces the appropriate classes
2118 to be linked into the executable image, preserving unix archive
2119 semantics. This can be removed when we move to a more dynamically
2120 linked environment. */
2121
2122 for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
2123 {
2124 handle_class_ref (chain);
2125 if (TREE_PURPOSE (chain))
2126 generate_classref_translation_entry (chain);
2127 }
2128
2129 for (impent = imp_list; impent; impent = impent->next)
2130 handle_impent (impent);
2131
2132 generate_strings ();
2133}
2134
2135/* --- exceptions --- */
2136
2137static GTY(()) tree objc_eh_personality_decl;
2138
2139static tree
2140objc_eh_runtime_type (tree type)
2141{
2142 tree ident, eh_id, decl, str;
2143
2144 if (type == error_mark_node
2145 || errorcount || sorrycount)
2146 {
2147 /* Use 'ErrorMarkNode' as class name when error_mark_node is found
2148 to prevent an ICE. Note that we know that the compiler will
2149 terminate with an error and this 'ErrorMarkNode' class name will
2150 never be actually used. */
2151 ident = get_identifier ("ErrorMarkNode");
2152 goto make_err_class;
2153 }
2154
2155 if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
2156 /* We don't want to identify 'id' for GNU. Instead, build a 0
2157 entry in the exceptions table. */
944fb799 2158 return null_pointer_node;
d764a8e6
IS
2159
2160 if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
2161 {
2162#ifdef OBJCPLUS
2163 /* This routine is also called for c++ catch clauses; in which case,
2164 we use the c++ typeinfo decl. */
2165 return build_eh_type_type (type);
2166#else
2167 error ("non-objective-c type '%T' cannot be caught", type);
2168 ident = get_identifier ("ErrorMarkNode");
2169 goto make_err_class;
2170#endif
2171 }
2172 else
2173 ident = OBJC_TYPE_NAME (TREE_TYPE (type));
2174
2175make_err_class:
2176 /* If this class was already referenced, then it will be output during
2177 meta-data emission, so we don't need to do it here. */
2178 decl = get_objc_string_decl (ident, class_names);
2179 eh_id = add_objc_string (ident, class_names);
2180 if (!decl)
2181 {
2182 /* Not found ... so we need to build it - from the freshly-entered id. */
2183 decl = get_objc_string_decl (ident, class_names);
2184 str = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2185 IDENTIFIER_POINTER (ident));
2186 /* We have to finalize this var here, because this might be called after
2187 all the other metadata strings have been emitted. */
2188 finish_var_decl (decl, str);
2189 }
2190 return eh_id;
2191}
2192
2193static tree
2194objc_eh_personality (void)
2195{
2196 if (!objc_eh_personality_decl)
2197#ifndef OBJCPLUS
2198 objc_eh_personality_decl = build_personality_function ("gnu_objc");
2199#else
2200 objc_eh_personality_decl = build_personality_function ("gxx");
2201#endif
2202 return objc_eh_personality_decl;
2203}
2204
2205/* -- interfaces --- */
2206
2207static tree
2208build_throw_stmt (location_t loc, tree throw_expr, bool rethrown ATTRIBUTE_UNUSED)
2209{
2210 tree t;
9771b263
DN
2211 vec<tree, va_gc> *parms;
2212 vec_alloc (parms, 1);
d764a8e6
IS
2213 /* A throw is just a call to the runtime throw function with the
2214 object as a parameter. */
9771b263 2215 parms->quick_push (throw_expr);
d764a8e6 2216 t = build_function_call_vec (loc, objc_exception_throw_decl, parms, NULL);
9771b263 2217 vec_free (parms);
d764a8e6
IS
2218 return add_stmt (t);
2219}
2220
2221/* Build __builtin_eh_pointer. */
2222
2223static tree
2224objc_build_exc_ptr (struct objc_try_context **x ATTRIBUTE_UNUSED)
2225{
2226 tree t;
e79983f4 2227 t = builtin_decl_explicit (BUILT_IN_EH_POINTER);
d764a8e6
IS
2228 t = build_call_expr (t, 1, integer_zero_node);
2229 return fold_convert (objc_object_type, t);
2230}
2231
944fb799 2232static tree
d764a8e6
IS
2233begin_catch (struct objc_try_context **cur_try_context, tree type,
2234 tree decl, tree compound, bool ellipsis ATTRIBUTE_UNUSED)
2235{
2236 tree t;
2237 /* Record the data for the catch in the try context so that we can
2238 finalize it later. */
2239 if (ellipsis)
2240 t = build_stmt (input_location, CATCH_EXPR, NULL, compound);
2241 else
2242 t = build_stmt (input_location, CATCH_EXPR, type, compound);
2243 (*cur_try_context)->current_catch = t;
2244
2245 /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime. */
2246 t = objc_build_exc_ptr (cur_try_context);
2247 t = convert (TREE_TYPE (decl), t);
2248 return build2 (MODIFY_EXPR, void_type_node, decl, t);
2249}
2250
944fb799 2251static void
d764a8e6
IS
2252finish_catch (struct objc_try_context **cur_try_context, tree current_catch)
2253{
2254 append_to_statement_list (current_catch, &((*cur_try_context)->catch_list));
2255}
2256
944fb799 2257static tree
d764a8e6
IS
2258finish_try_stmt (struct objc_try_context **cur_try_context)
2259{
2260 struct objc_try_context *c = *cur_try_context;
2261 tree stmt = c->try_body;
2262 if (c->catch_list)
2263 stmt = build_stmt (c->try_locus, TRY_CATCH_EXPR, stmt, c->catch_list);
2264 if (c->finally_body)
2265 stmt = build_stmt (c->try_locus, TRY_FINALLY_EXPR, stmt, c->finally_body);
2266 return stmt;
2267}
2268
2269#include "gt-objc-objc-gnu-runtime-abi-01.h"