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