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