gcc50: Disconnect from buildworld.
[dragonfly.git] / contrib / gcc-5.0 / gcc / objc / objc-gnu-runtime-abi-01.c
1 /* GNU Runtime ABI version 8
2    Copyright (C) 2011-2015 Free Software Foundation, Inc.
3    Contributed by Iain Sandoe (split from objc-act.c)
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along 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"
24 #include "hash-set.h"
25 #include "machmode.h"
26 #include "vec.h"
27 #include "double-int.h"
28 #include "input.h"
29 #include "alias.h"
30 #include "symtab.h"
31 #include "options.h"
32 #include "wide-int.h"
33 #include "inchash.h"
34 #include "tree.h"
35 #include "fold-const.h"
36 #include "stringpool.h"
37
38 #ifdef OBJCPLUS
39 #include "cp/cp-tree.h"
40 #else
41 #include "c/c-tree.h"
42 #include "c/c-lang.h"
43 #endif
44
45 #include "langhooks.h"
46 #include "c-family/c-objc.h"
47 #include "objc-act.h"
48
49 /* When building Objective-C++, we are not linking against the C front-end
50    and so need to replicate the C tree-construction functions in some way.  */
51 #ifdef OBJCPLUS
52 #define OBJCP_REMAP_FUNCTIONS
53 #include "objcp-decl.h"
54 #endif  /* OBJCPLUS */
55
56 #include "toplev.h"
57 #include "ggc.h"
58 #include "tree-iterator.h"
59
60 #include "objc-runtime-hooks.h"
61 #include "objc-runtime-shared-support.h"
62 #include "objc-encoding.h"
63
64 /* GNU runtime private definitions.  */
65 #define DEF_CONSTANT_STRING_CLASS_NAME "NXConstantString"
66
67 #define TAG_GETCLASS            "objc_get_class"
68 #define TAG_GETMETACLASS        "objc_get_meta_class"
69
70 #define TAG_MSGSEND             "objc_msg_lookup"
71 #define TAG_MSGSENDSUPER        "objc_msg_lookup_super"
72
73 /* GNU-specific tags.  */
74
75 #define TAG_EXECCLASS           "__objc_exec_class"
76 #define TAG_GNUINIT             "__objc_gnu_init"
77
78 /* The version identifies which language generation and runtime
79    the module (file) was compiled for, and is recorded in the
80    module descriptor.  */
81 #define OBJC_VERSION            8
82
83 #define PROTOCOL_VERSION        2
84
85 /* This macro provides a method of removing ambiguity between runtimes
86    when LTO is in use on targets supporting multiple runtimes.
87
88    For example, at present, any target that includes an implementation of
89    the NeXT runtime needs to place Objective-C meta-data into specific
90    named sections.  This should _not_ be done for the GNU runtime, and the
91    following macro is used to attach Objective-C private attributes that may
92    be used to identify the runtime for which the meta-data are intended.  */
93
94 #define OBJCMETA(DECL,VERS,KIND)                                        \
95   if (VERS)                                                             \
96     DECL_ATTRIBUTES (DECL) = build_tree_list ((VERS), (KIND));
97
98 static void gnu_runtime_01_initialize (void);
99
100 static void build_selector_template (void);
101
102 static tree gnu_runtime_abi_01_super_superclassfield_id (void);
103
104 static tree gnu_runtime_abi_01_class_decl (tree);
105 static tree gnu_runtime_abi_01_metaclass_decl (tree);
106 static tree gnu_runtime_abi_01_category_decl (tree);
107 static tree gnu_runtime_abi_01_protocol_decl (tree);
108 static tree gnu_runtime_abi_01_string_decl (tree, const char *, string_section);
109
110 static tree gnu_runtime_abi_01_get_class_reference (tree);
111 static tree gnu_runtime_abi_01_build_typed_selector_reference (location_t, tree,
112                                                                 tree);
113 static tree gnu_runtime_abi_01_get_protocol_reference (location_t, tree);
114 static tree gnu_runtime_abi_01_build_ivar_ref (location_t, tree, tree);
115 static tree gnu_runtime_abi_01_get_class_super_ref (location_t, struct imp_entry *, bool);
116 static tree gnu_runtime_abi_01_get_category_super_ref (location_t, struct imp_entry *, bool);
117
118 static tree gnu_runtime_abi_01_receiver_is_class_object (tree);
119 static void gnu_runtime_abi_01_get_arg_type_list_base (vec<tree, va_gc> **,
120                                                        tree, int, int);
121 static tree gnu_runtime_abi_01_build_objc_method_call (location_t, tree, tree,
122                                                         tree, tree, tree, int);
123
124 static bool gnu_runtime_abi_01_setup_const_string_class_decl (void);
125 static tree gnu_runtime_abi_01_build_const_string_constructor (location_t, tree,int);
126
127 static void objc_generate_v1_gnu_metadata (void);
128
129 static tree objc_eh_runtime_type (tree type);
130 static tree objc_eh_personality (void);
131 static tree objc_build_exc_ptr (struct objc_try_context **);
132 static tree build_throw_stmt (location_t, tree, bool);
133 static tree begin_catch (struct objc_try_context **, tree, tree, tree, bool);
134 static void finish_catch (struct objc_try_context **, tree);
135 static tree finish_try_stmt (struct objc_try_context **);
136
137 bool
138 objc_gnu_runtime_abi_01_init (objc_runtime_hooks *rthooks)
139 {
140   /* GNU runtime does not need the compiler to change code in order to do GC. */
141   if (flag_objc_gc)
142     {
143       warning_at (0, 0, "%<-fobjc-gc%> is ignored for %<-fgnu-runtime%>");
144       flag_objc_gc = 0;
145     }
146
147   /* Although I guess we could, we don't currently support SJLJ exceptions for the
148      GNU runtime.  */
149   if (flag_objc_sjlj_exceptions)
150     {
151       inform (UNKNOWN_LOCATION, "%<-fobjc-sjlj-exceptions%> is ignored for %<-fgnu-runtime%>");
152       flag_objc_sjlj_exceptions = 0;
153     }
154
155   /* TODO: Complain if -fobjc-abi-version=N was used.  */
156
157   /* TODO: Complain if -fobj-nilcheck was used.  */
158
159   rthooks->initialize = gnu_runtime_01_initialize;
160   rthooks->default_constant_string_class_name = DEF_CONSTANT_STRING_CLASS_NAME;
161   rthooks->tag_getclass = TAG_GETCLASS;
162   rthooks->super_superclassfield_ident = gnu_runtime_abi_01_super_superclassfield_id;
163
164   rthooks->class_decl = gnu_runtime_abi_01_class_decl;
165   rthooks->metaclass_decl = gnu_runtime_abi_01_metaclass_decl;
166   rthooks->category_decl = gnu_runtime_abi_01_category_decl;
167   rthooks->protocol_decl = gnu_runtime_abi_01_protocol_decl;
168   rthooks->string_decl = gnu_runtime_abi_01_string_decl;
169
170   rthooks->get_class_reference = gnu_runtime_abi_01_get_class_reference;
171   rthooks->build_selector_reference = gnu_runtime_abi_01_build_typed_selector_reference;
172   rthooks->get_protocol_reference = gnu_runtime_abi_01_get_protocol_reference;
173   rthooks->build_ivar_reference = gnu_runtime_abi_01_build_ivar_ref;
174   rthooks->get_class_super_ref = gnu_runtime_abi_01_get_class_super_ref;
175   rthooks->get_category_super_ref = gnu_runtime_abi_01_get_category_super_ref;
176
177   rthooks->receiver_is_class_object = gnu_runtime_abi_01_receiver_is_class_object;
178   rthooks->get_arg_type_list_base = gnu_runtime_abi_01_get_arg_type_list_base;
179   rthooks->build_objc_method_call = gnu_runtime_abi_01_build_objc_method_call;
180
181   rthooks->setup_const_string_class_decl =
182                                 gnu_runtime_abi_01_setup_const_string_class_decl;
183   rthooks->build_const_string_constructor =
184                                 gnu_runtime_abi_01_build_const_string_constructor;
185
186   rthooks->build_throw_stmt = build_throw_stmt;
187   rthooks->build_exc_ptr = objc_build_exc_ptr;
188   rthooks->begin_catch = begin_catch;
189   rthooks->finish_catch = finish_catch;
190   rthooks->finish_try_stmt = finish_try_stmt;
191
192   rthooks->generate_metadata = objc_generate_v1_gnu_metadata;
193   return true;
194 }
195
196 static void build_selector_table_decl (void);
197 static void build_class_template (void);
198 static void build_category_template (void);
199 static void build_protocol_template (void);
200
201 static GTY(()) tree objc_meta;
202 static GTY(()) tree meta_base;
203
204 static void gnu_runtime_01_initialize (void)
205 {
206   tree type, ftype, IMP_type;
207
208   /* We do not need to mark GNU ObjC metadata for different sections,
209      however, we do need to make sure that it is not mistaken for NeXT
210      metadata.  */
211   objc_meta = get_identifier ("OBJC1METG");
212   meta_base = get_identifier ("NONE");
213
214   /* Declare type of selector-objects that represent an operation name.  */
215   /* `const struct objc_selector *' */
216   type = xref_tag (RECORD_TYPE, get_identifier (TAG_SELECTOR));
217   type = build_qualified_type (type, TYPE_QUAL_CONST);
218   objc_selector_type = build_pointer_type (type);
219
220   /* typedef id (*IMP)(id, SEL, ...); */
221   ftype = build_varargs_function_type_list (objc_object_type,
222                                             objc_object_type,
223                                             objc_selector_type,
224                                             NULL_TREE);
225
226   IMP_type = build_pointer_type (ftype);
227
228   build_class_template ();
229   build_super_template ();
230   build_protocol_template ();
231   build_category_template ();
232
233   /* GNU runtime messenger entry points.  */
234   /* TREE_NOTHROW is cleared for the message-sending functions,
235      because the function that gets called can throw in Obj-C++, or
236      could itself call something that can throw even in Obj-C.  */
237
238   /* IMP objc_msg_lookup (id, SEL); */
239   type = build_function_type_list (IMP_type,
240                                    objc_object_type,
241                                    objc_selector_type,
242                                    NULL_TREE);
243
244   umsg_decl = add_builtin_function (TAG_MSGSEND,
245                                     type, 0, NOT_BUILT_IN,
246                                     NULL, NULL_TREE);
247   TREE_NOTHROW (umsg_decl) = 0;
248
249   /* IMP objc_msg_lookup_super (struct objc_super *, SEL); */
250   type = build_function_type_list (IMP_type,
251                                    objc_super_type,
252                                    objc_selector_type,
253                                    NULL_TREE);
254
255   umsg_super_decl = add_builtin_function (TAG_MSGSENDSUPER,
256                                           type, 0, NOT_BUILT_IN,
257                                           NULL, NULL_TREE);
258   TREE_NOTHROW (umsg_super_decl) = 0;
259
260   /* The following GNU runtime entry point is called to initialize
261          each module:
262
263          __objc_exec_class (void *); */
264   type = build_function_type_list (void_type_node,
265                                    ptr_type_node,
266                                    NULL_TREE);
267
268   execclass_decl = add_builtin_function (TAG_EXECCLASS,
269                                          type, 0, NOT_BUILT_IN,
270                                          NULL, NULL_TREE);
271
272   type = build_function_type_list (objc_object_type,
273                                    const_string_type_node,
274                                    NULL_TREE);
275
276   /* id objc_getClass (const char *); */
277   objc_get_class_decl
278     = add_builtin_function (TAG_GETCLASS, type, 0, NOT_BUILT_IN,
279                             NULL, NULL_TREE);
280
281   /* id objc_getMetaClass (const char *); */
282   objc_get_meta_class_decl = add_builtin_function (TAG_GETMETACLASS, type,
283                                                    0, NOT_BUILT_IN, NULL,
284                                                    NULL_TREE);
285
286   /* static SEL _OBJC_SELECTOR_TABLE[]; */
287   build_selector_table_decl ();
288
289   /* Stuff for properties.
290      The codegen relies on this being NULL for GNU.  */
291   objc_copyStruct_decl = NULL_TREE;
292
293   /* This is the type of all of the following functions
294      bjc_getPropertyStruct() and objc_setPropertyStruct().  */
295   type = build_function_type_list (void_type_node,
296                                    ptr_type_node,
297                                    const_ptr_type_node,
298                                    ptrdiff_type_node,
299                                    boolean_type_node,
300                                    boolean_type_node,
301                                    NULL_TREE);
302
303   /* Declare the following function:
304          void
305          objc_getPropertyStruct (void *destination, const void *source,
306                                  ptrdiff_t size, BOOL is_atomic, BOOL has_strong);  */
307   objc_getPropertyStruct_decl = add_builtin_function ("objc_getPropertyStruct",
308                                                           type, 0, NOT_BUILT_IN,
309                                                           NULL, NULL_TREE);
310   TREE_NOTHROW (objc_getPropertyStruct_decl) = 0;
311   /* Declare the following function:
312          void
313          objc_setPropertyStruct (void *destination, const void *source,
314                                  ptrdiff_t size, BOOL is_atomic, BOOL has_strong);  */
315   objc_setPropertyStruct_decl = add_builtin_function ("objc_setPropertyStruct",
316                                                           type, 0, NOT_BUILT_IN,
317                                                           NULL, NULL_TREE);
318   TREE_NOTHROW (objc_setPropertyStruct_decl) = 0;
319
320   using_eh_for_cleanups ();
321   lang_hooks.eh_runtime_type = objc_eh_runtime_type;
322   lang_hooks.eh_personality = objc_eh_personality;
323 }
324
325 /* --- templates --- */
326 /* struct _objc_selector {
327      SEL sel_id;
328      char *sel_type;
329    }; */
330
331 static void
332 build_selector_template (void)
333 {
334   tree decls, *chain = NULL;
335
336   objc_selector_template = objc_start_struct (get_identifier (UTAG_SELECTOR));
337
338   /* SEL sel_id; */
339   decls = add_field_decl (objc_selector_type, "sel_id", &chain);
340
341   /* char *sel_type; */
342   add_field_decl (string_type_node, "sel_type", &chain);
343
344   objc_finish_struct (objc_selector_template, decls);
345 }
346
347 /* struct _objc_class {
348      struct _objc_class *isa;
349      struct _objc_class *super_class;
350      char *name;
351      long version;
352      long info;
353      long instance_size;
354      struct _objc_ivar_list *ivars;
355      struct _objc_method_list *methods;
356      struct sarray *dtable;
357      struct _objc_class *subclass_list;
358      struct _objc_class *sibling_class;
359      struct _objc_protocol_list *protocols;
360      void *gc_object_type;
361    };  */
362
363 static void
364 build_class_template (void)
365 {
366   tree ptype, decls, *chain = NULL;
367
368   objc_class_template = objc_start_struct (get_identifier (UTAG_CLASS));
369
370   /* struct _objc_class *isa; */
371   decls = add_field_decl (build_pointer_type (objc_class_template),
372                           "isa", &chain);
373
374   /* struct _objc_class *super_class; */
375   add_field_decl (build_pointer_type (objc_class_template),
376                   "super_class", &chain);
377
378   /* char *name; */
379   add_field_decl (string_type_node, "name", &chain);
380
381   /* long version; */
382   add_field_decl (long_integer_type_node, "version", &chain);
383
384   /* long info; */
385   add_field_decl (long_integer_type_node, "info", &chain);
386
387   /* long instance_size; */
388   add_field_decl (long_integer_type_node, "instance_size", &chain);
389
390   /* struct _objc_ivar_list *ivars; */
391   add_field_decl (objc_ivar_list_ptr,"ivars", &chain);
392
393   /* struct _objc_method_list *methods; */
394   add_field_decl (objc_method_list_ptr, "methods", &chain);
395
396   /* struct sarray *dtable; */
397   ptype = build_pointer_type(xref_tag (RECORD_TYPE,
398                                            get_identifier ("sarray")));
399   add_field_decl (ptype, "dtable", &chain);
400
401   /* struct objc_class *subclass_list; */
402   ptype = build_pointer_type (objc_class_template);
403   add_field_decl (ptype, "subclass_list", &chain);
404
405   /* struct objc_class *sibling_class; */
406   ptype = build_pointer_type (objc_class_template);
407   add_field_decl (ptype, "sibling_class", &chain);
408
409   /* struct _objc_protocol **protocol_list; */
410   ptype = build_pointer_type (build_pointer_type
411                               (xref_tag (RECORD_TYPE,
412                                          get_identifier (UTAG_PROTOCOL))));
413   add_field_decl (ptype, "protocol_list", &chain);
414
415   /* void *gc_object_type; */
416   add_field_decl (build_pointer_type (void_type_node),
417                     "gc_object_type", &chain);
418
419   objc_finish_struct (objc_class_template, decls);
420 }
421
422 /* struct _objc_category {
423      char *category_name;
424      char *class_name;
425      struct _objc_method_list *instance_methods;
426      struct _objc_method_list *class_methods;
427      struct _objc_protocol_list *protocols;
428    };   */
429
430 static void
431 build_category_template (void)
432 {
433   tree ptype, decls, *chain = NULL;
434
435   objc_category_template = objc_start_struct (get_identifier (UTAG_CATEGORY));
436
437   /* char *category_name; */
438   decls = add_field_decl (string_type_node, "category_name", &chain);
439
440   /* char *class_name; */
441   add_field_decl (string_type_node, "class_name", &chain);
442
443   /* struct _objc_method_list *instance_methods; */
444   add_field_decl (objc_method_list_ptr, "instance_methods", &chain);
445
446   /* struct _objc_method_list *class_methods; */
447   add_field_decl (objc_method_list_ptr, "class_methods", &chain);
448
449   /* struct _objc_protocol **protocol_list; */
450   ptype = build_pointer_type (build_pointer_type (objc_protocol_template));
451   add_field_decl (ptype, "protocol_list", &chain);
452
453   objc_finish_struct (objc_category_template, decls);
454 }
455
456 /* struct _objc_protocol {
457      struct _objc_class *isa;
458      char *protocol_name;
459      struct _objc_protocol **protocol_list;
460      struct _objc__method_prototype_list *instance_methods;
461      struct _objc__method_prototype_list *class_methods;
462    };  */
463
464 static void
465 build_protocol_template (void)
466 {
467   tree ptype, decls, *chain = NULL;
468
469   objc_protocol_template = objc_start_struct (get_identifier (UTAG_PROTOCOL));
470
471   /* struct _objc_class *isa; */
472   ptype = build_pointer_type (xref_tag (RECORD_TYPE,
473                                         get_identifier (UTAG_CLASS)));
474   decls = add_field_decl (ptype, "isa", &chain);
475
476   /* char *protocol_name; */
477   add_field_decl (string_type_node, "protocol_name", &chain);
478
479   /* struct _objc_protocol **protocol_list; */
480   ptype = build_pointer_type (build_pointer_type (objc_protocol_template));
481   add_field_decl (ptype, "protocol_list", &chain);
482
483   /* struct _objc__method_prototype_list *instance_methods; */
484   add_field_decl (objc_method_proto_list_ptr, "instance_methods", &chain);
485
486   /* struct _objc__method_prototype_list *class_methods; */
487   add_field_decl (objc_method_proto_list_ptr, "class_methods", &chain);
488
489   objc_finish_struct (objc_protocol_template, decls);
490 }
491
492 /* --- names, decls + identifiers --- */
493
494 static void
495 build_selector_table_decl (void)
496 {
497   tree temp;
498
499   build_selector_template ();
500   temp = build_array_type (objc_selector_template, NULL_TREE);
501
502   UOBJC_SELECTOR_TABLE_decl = start_var_decl (temp, "_OBJC_SELECTOR_TABLE");
503   OBJCMETA (UOBJC_SELECTOR_TABLE_decl, objc_meta, meta_base);
504 }
505
506
507 static tree
508 gnu_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
516 static tree
517 gnu_runtime_abi_01_class_decl (tree klass)
518 {
519   tree decl;
520   char buf[BUFSIZE];
521   snprintf (buf, BUFSIZE, "_OBJC_Class_%s",
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
528 static tree
529 gnu_runtime_abi_01_metaclass_decl (tree klass)
530 {
531   tree decl;
532   char buf[BUFSIZE];
533   snprintf (buf, BUFSIZE, "_OBJC_MetaClass_%s",
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
540 static tree
541 gnu_runtime_abi_01_category_decl (tree klass)
542 {
543   tree decl;
544   char buf[BUFSIZE];
545   snprintf (buf, BUFSIZE, "_OBJC_Category_%s_on_%s",
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
553 static tree
554 gnu_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
567 static tree
568 gnu_runtime_abi_01_string_decl (tree type, const char *name,
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
578 static tree
579 gnu_runtime_abi_01_get_class_reference (tree ident)
580 {
581   tree params;
582
583   add_class_reference (ident);
584
585   params = build_tree_list (NULL_TREE, my_build_string_pointer
586                                                 (IDENTIFIER_LENGTH (ident) + 1,
587                                                  IDENTIFIER_POINTER (ident)));
588
589   return build_function_call (input_location, objc_get_class_decl, params);
590 }
591
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.  */
598
599 static void
600 gnu_runtime_abi_01_get_arg_type_list_base (vec<tree, va_gc> **argtypes,
601                                            tree meth, int context,
602                                            int superflag ATTRIBUTE_UNUSED)
603 {
604   tree receiver_type;
605
606   if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
607     receiver_type = objc_instance_type;
608   else
609     receiver_type = objc_object_type;
610
611   vec_safe_push (*argtypes, receiver_type);
612   /* Selector type - will eventually change to `int'.  */
613   vec_safe_push (*argtypes, objc_selector_type);
614 }
615
616 /* Unused for GNU runtime.  */
617 static tree
618 gnu_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
627 static tree
628 gnu_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     {
637       /* When we do a lookup for @selector () we have no idea of the
638          prototype - so match the first we find.  */
639       if (TREE_VALUE (*chain) == ident
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
649   /* TODO: Use a vec and keep this in it to (a) avoid re-creating and
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
668 static tree
669 build_objc_method_call (location_t loc, int super_flag, tree method_prototype,
670                         tree lookup_object, tree selector,
671                         tree method_params)
672 {
673   tree sender = (super_flag ? umsg_super_decl
674                             : (flag_objc_direct_dispatch ? umsg_fast_decl
675                                                          : umsg_decl));
676   tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
677   vec<tree, va_gc> *parms;
678   vec<tree, va_gc> *tv;
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);
688   tree ftype
689     = build_function_type_for_method (ret_type, method_prototype,
690                                       METHOD_REF, super_flag);
691   tree sender_cast;
692   tree method, t;
693
694   if (method_prototype && METHOD_TYPE_ATTRIBUTES (method_prototype))
695     ftype = build_type_attribute_variant (ftype,
696                                           METHOD_TYPE_ATTRIBUTES
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.  */
707   vec_alloc (parms, nparm + 2);
708   vec_alloc (tv, 2);
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.  */
712   tv->quick_push (lookup_object);
713   tv->quick_push (selector);
714   method = build_function_call_vec (loc, vNULL, sender, tv, NULL);
715   vec_free (tv);
716
717   /* Pass the appropriate object to the method.  */
718   parms->quick_push ((super_flag ? self_decl : lookup_object));
719
720   /* Pass the selector to the method.  */
721   parms->quick_push (selector);
722   /* Now append the remainder of the parms.  */
723   if (nparm)
724     for (; method_params; method_params = TREE_CHAIN (method_params))
725       parms->quick_push (TREE_VALUE (method_params));
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);
729   t = build_function_call_vec (loc, vNULL, t, parms, NULL);
730   vec_free (parms);
731   return t;
732 }
733
734 static tree
735 gnu_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 {
743   tree selector =
744         gnu_runtime_abi_01_build_typed_selector_reference (loc,
745                                                           sel_name,
746                                                           method_prototype);
747
748   return build_objc_method_call (loc, super, method_prototype, receiver,
749                                  selector, method_params);
750 }
751
752 static tree
753 gnu_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).  */
782   protocol_struct_type = xref_tag (RECORD_TYPE,
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
809 /* For ABI 8 an IVAR is just a fixed offset in the class struct.  */
810
811 static tree
812 gnu_runtime_abi_01_build_ivar_ref (location_t loc ATTRIBUTE_UNUSED,
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
821 static tree
822 gnu_runtime_abi_01_get_class_super_ref (location_t loc ATTRIBUTE_UNUSED,
823                                         struct imp_entry *imp, bool inst_meth)
824 {
825   if (inst_meth)
826     {
827       if (!ucls_super_ref)
828         ucls_super_ref =
829                 objc_build_component_ref (imp->class_decl,
830                                           get_identifier ("super_class"));
831         return ucls_super_ref;
832     }
833   else
834     {
835       if (!uucls_super_ref)
836         uucls_super_ref =
837                 objc_build_component_ref (imp->meta_decl,
838                                           get_identifier ("super_class"));
839         return uucls_super_ref;
840     }
841 }
842
843 static tree
844 gnu_runtime_abi_01_get_category_super_ref (location_t loc ATTRIBUTE_UNUSED,
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);
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
860 static bool
861 gnu_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
869 static GTY(()) int num_static_inst;
870
871 static tree
872 objc_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.
899      Postpone till end of input. */
900   DECL_DEFER_OUTPUT (decl) = 1;
901   pushdecl_top_level (decl);
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
910 static tree
911 gnu_runtime_abi_01_build_const_string_constructor (location_t loc, tree string,
912                                                    int length)
913 {
914   tree constructor, fields;
915   vec<constructor_elt, va_gc> *v = NULL;
916
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);
922   CONSTRUCTOR_APPEND_ELT (v, fields, build_unary_op (loc,
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
943 static void
944 build_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),
961                        NULL_TREE, objc_get_parm_info (0, NULL_TREE));
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
993 int
994 objc_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
1001 tree
1002 objc_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
1014 static void
1015 generate_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
1034 static void
1035 handle_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));
1048
1049         string = (char *) alloca (strlen (class_name) + 30);
1050
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));
1060
1061         string = (char *) alloca (strlen (class_name)
1062                                   + strlen (class_super_name) + 30);
1063
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
1096 tree
1097 build_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;
1102   vec<constructor_elt, va_gc> *inits = NULL;
1103
1104   /* TODO: pass the loc in or find it from args.  */
1105   loc = input_location;
1106   ttyp = build_pointer_type (xref_tag (RECORD_TYPE,
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
1133 static tree
1134 generate_protocol_list (tree i_or_p, tree klass_ctxt)
1135 {
1136   tree array_type, ptype, refs_decl, lproto, e, plist;
1137   vec<constructor_elt, va_gc> *v = NULL;
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:
1184       snprintf (buf, BUFSIZE, "_OBJC_ProtocolRefs_%s",
1185                 IDENTIFIER_POINTER (PROTOCOL_NAME (i_or_p)));
1186       break;
1187     case CLASS_INTERFACE_TYPE:
1188       snprintf (buf, BUFSIZE, "_OBJC_ClassProtocols_%s",
1189                 IDENTIFIER_POINTER (CLASS_NAME (i_or_p)));
1190       break;
1191     case CATEGORY_INTERFACE_TYPE:
1192       snprintf (buf, BUFSIZE, "_OBJC_CategoryProtocols_%s_%s",
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
1210 static tree
1211 generate_v1_meth_descriptor_table (tree chain, tree protocol, const char *prefix)
1212 {
1213   tree method_list_template, initlist, decl;
1214   int size;
1215   vec<constructor_elt, va_gc> *v = NULL;
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 ();
1223
1224   size = list_length (chain);
1225   method_list_template =
1226         build_method_prototype_list_template (objc_method_prototype_template,
1227                                               size);
1228   snprintf (buf, BUFSIZE, "%s_%s", prefix,
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));
1234   initlist =
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
1277 static void
1278 generate_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
1313       UOBJC_INSTANCE_METHODS_decl =
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
1328       UOBJC_CLASS_METHODS_decl =
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
1359 static tree
1360 generate_dispatch_table (tree chain, const char *name)
1361 {
1362   tree decl, method_list_template, initlist;
1363   vec<constructor_elt, va_gc> *v = NULL;
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);
1376   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
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.  */
1388 static tree
1389 build_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;
1395   vec<constructor_elt, va_gc> *v = NULL;
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
1429 static void
1430 generate_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;
1489      struct sarray *dtable;
1490      struct objc_class *subclass_list;
1491      struct objc_class *sibling_class;
1492      struct objc_protocol_list *protocols;
1493      void *gc_object_type;
1494    };  */
1495
1496 static tree
1497 build_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;
1503   vec<constructor_elt, va_gc> *v = NULL;
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)
1528     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1529                             build_int_cst (objc_ivar_list_ptr, 0));
1530   else
1531     {
1532       expr = convert (objc_ivar_list_ptr,
1533                       build_unary_op (input_location, ADDR_EXPR,
1534                                       ivar_list, 0));
1535       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1536     }
1537
1538   /* objc_method_list = */
1539   if (!dispatch_table)
1540     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1541                            convert (objc_method_list_ptr, null_pointer_node));
1542   else
1543     {
1544       expr = convert (objc_method_list_ptr,
1545                       build_unary_op (input_location, ADDR_EXPR,
1546                                       dispatch_table, 0));
1547       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1548     }
1549
1550   /* FIXME: Remove NeXT runtime code.  */
1551   if (flag_next_runtime)
1552     {
1553       ltyp = build_pointer_type (xref_tag (RECORD_TYPE,
1554                                            get_identifier ("objc_cache")));
1555       /* method_cache = */
1556       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, convert (ltyp, null_pointer_node));
1557     }
1558   else
1559     {
1560       /* dtable = */
1561       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1562
1563       /* subclass_list = */
1564       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1565
1566       /* sibling_class = */
1567       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1568     }
1569
1570   /* protocol_list = */
1571   ltyp = build_pointer_type (build_pointer_type (objc_protocol_template));
1572   if (! protocol_list)
1573     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (ltyp, 0));
1574   else
1575     {
1576       expr = convert (ltyp,
1577                       build_unary_op (input_location, ADDR_EXPR,
1578                                       protocol_list, 0));
1579       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1580     }
1581
1582   /* FIXME: Remove NeXT runtime code.  */
1583   if (flag_next_runtime)
1584     /* sel_id = NULL */
1585     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1586
1587   /* gc_object_type = NULL */
1588   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1589
1590   return objc_build_constructor (type, v);
1591 }
1592
1593
1594 static tree
1595 generate_ivars_list (tree chain, const char *name)
1596 {
1597   tree initlist, ivar_list_template, decl;
1598   int size;
1599   vec<constructor_elt, va_gc> *inits = NULL;
1600
1601   if (!chain)
1602     return NULL_TREE;
1603
1604   if (!objc_ivar_template)
1605     objc_ivar_template = build_ivar_template ();
1606
1607   size = ivar_list_length (chain);
1608
1609   generating_instance_variables = 1;
1610   ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
1611   initlist = build_ivar_list_initializer (objc_ivar_template, chain);
1612   generating_instance_variables = 0;
1613
1614   decl = start_var_decl (ivar_list_template, name);
1615
1616   CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, size));
1617   CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, initlist);
1618
1619   OBJCMETA (decl, objc_meta, meta_base);
1620   finish_var_decl (decl,
1621                    objc_build_constructor (TREE_TYPE (decl), inits));
1622
1623   return decl;
1624 }
1625
1626 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
1627    static struct objc_class _OBJC_CLASS_Foo={ ... };  */
1628
1629 static void
1630 generate_class_structures (struct imp_entry *impent)
1631 {
1632   tree name_expr, super_expr, root_expr, class_decl, meta_decl;
1633   tree my_root_id, my_super_id;
1634   tree cast_type, initlist, protocol_decl;
1635   tree inst_methods = NULL_TREE, class_methods = NULL_TREE;
1636   tree chain, inst_ivars = NULL_TREE, class_ivars = NULL_TREE;
1637   location_t loc;
1638   char buf[BUFSIZE];
1639   int cls_flags = 0 ;
1640
1641 /*  objc_implementation_context = impent->imp_context;
1642   implementation_template = impent->imp_template;*/
1643   class_decl = impent->class_decl;
1644   meta_decl = impent->meta_decl;
1645 /*  UOBJC_CLASS_decl = impent->class_decl;
1646   UOBJC_METACLASS_decl = impent->meta_decl;*/
1647
1648   loc = DECL_SOURCE_LOCATION (impent->class_decl);
1649
1650   my_super_id = CLASS_SUPER_NAME (impent->imp_template);
1651   if (my_super_id)
1652     {
1653       add_class_reference (my_super_id);
1654
1655       /* Compute "my_root_id" - this is required for code generation.
1656          the "isa" for all meta class structures points to the root of
1657          the inheritance hierarchy (e.g. "__Object")...  */
1658       my_root_id = my_super_id;
1659       do
1660         {
1661           tree my_root_int = lookup_interface (my_root_id);
1662
1663           if (my_root_int && CLASS_SUPER_NAME (my_root_int))
1664             my_root_id = CLASS_SUPER_NAME (my_root_int);
1665           else
1666             break;
1667         }
1668       while (1);
1669     }
1670   else
1671     /* No super class.  */
1672     my_root_id = CLASS_NAME (impent->imp_template);
1673
1674   cast_type = build_pointer_type (objc_class_template);
1675   name_expr = add_objc_string (CLASS_NAME (impent->imp_template),
1676                                class_names);
1677
1678   /* Install class `isa' and `super' pointers at runtime.  */
1679   if (my_super_id)
1680     super_expr = add_objc_string (my_super_id, class_names);
1681   else
1682     super_expr = null_pointer_node;
1683
1684   super_expr = build_c_cast (loc, cast_type, super_expr);
1685
1686   root_expr = add_objc_string (my_root_id, class_names);
1687   root_expr = build_c_cast (loc, cast_type, root_expr);
1688
1689   if (CLASS_PROTOCOL_LIST (impent->imp_template))
1690     {
1691       generate_protocol_references (CLASS_PROTOCOL_LIST (impent->imp_template));
1692       protocol_decl = generate_protocol_list (impent->imp_template,
1693                                               impent->imp_context);
1694     }
1695   else
1696     protocol_decl = NULL_TREE;
1697
1698   if (CLASS_CLS_METHODS (impent->imp_context))
1699     {
1700       snprintf (buf, BUFSIZE, "_OBJC_ClassMethods_%s",
1701                 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
1702       class_methods = generate_dispatch_table (CLASS_CLS_METHODS (impent->imp_context),
1703                                                buf);
1704     }
1705
1706   if (CLASS_SUPER_NAME (impent->imp_template) == NULL_TREE
1707       && (chain = TYPE_FIELDS (objc_class_template)))
1708     {
1709       snprintf (buf, BUFSIZE, "_OBJC_ClassIvars_%s",
1710                 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
1711       class_ivars = generate_ivars_list (chain, buf);
1712     }
1713
1714   /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
1715
1716   initlist =
1717         build_shared_structure_initializer
1718                         (TREE_TYPE (meta_decl),
1719                         root_expr, super_expr, name_expr,
1720                         convert (integer_type_node,
1721                                 TYPE_SIZE_UNIT (objc_class_template)),
1722                         CLS_META, class_methods, class_ivars,
1723                         protocol_decl);
1724
1725   finish_var_decl (meta_decl, initlist);
1726   impent->meta_decl = meta_decl;
1727
1728   /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
1729   if (CLASS_NST_METHODS (impent->imp_context))
1730     {
1731       snprintf (buf, BUFSIZE, "_OBJC_InstanceMethods_%s",
1732                 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
1733       inst_methods = generate_dispatch_table (CLASS_NST_METHODS (impent->imp_context),
1734                                               buf);
1735     }
1736
1737   if ((chain = CLASS_IVARS (impent->imp_template)))
1738     {
1739       snprintf (buf, BUFSIZE, "_OBJC_InstanceIvars_%s",
1740                 IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
1741       inst_ivars = generate_ivars_list (chain, buf);
1742     }
1743
1744   initlist =
1745         build_shared_structure_initializer
1746                 (TREE_TYPE (class_decl),
1747                 build_unary_op (loc, ADDR_EXPR, meta_decl, 0),
1748                 super_expr, name_expr,
1749                 convert (integer_type_node,
1750                          TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
1751                                         (impent->imp_template))),
1752                 CLS_FACTORY | cls_flags, inst_methods, inst_ivars,
1753                 protocol_decl);
1754
1755   finish_var_decl (class_decl, initlist);
1756   impent->class_decl = class_decl;
1757 }
1758
1759 /* --- Output GNU Metadata --- */
1760
1761 /* TODO: Make this into an array of refs.  */
1762 static void
1763 handle_class_ref (tree chain)
1764 {
1765   const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
1766   char *string = (char *) alloca (strlen (name) + 30);
1767   tree decl;
1768   tree exp;
1769
1770   sprintf (string, "__objc_class_name_%s", name);
1771
1772   /* Make a decl for this name, so we can use its address in a tree.  */
1773   decl = build_decl (input_location,
1774                      VAR_DECL, get_identifier (string), TREE_TYPE (integer_zero_node));
1775   DECL_EXTERNAL (decl) = 1;
1776   TREE_PUBLIC (decl) = 1;
1777   DECL_CONTEXT (decl) = NULL_TREE;
1778   finish_var_decl (decl, 0);
1779
1780   /* Make a decl for the address.  */
1781   sprintf (string, "__objc_class_ref_%s", name);
1782   exp = build1 (ADDR_EXPR, string_type_node, decl);
1783   decl = build_decl (input_location,
1784                      VAR_DECL, get_identifier (string), string_type_node);
1785   TREE_STATIC (decl) = 1;
1786   TREE_USED (decl) = 1;
1787   DECL_READ_P (decl) = 1;
1788   DECL_ARTIFICIAL (decl) = 1;
1789   DECL_INITIAL (decl) = error_mark_node;
1790
1791   /* We must force the reference.  */
1792   DECL_PRESERVE_P (decl) = 1;
1793
1794   DECL_CONTEXT (decl) = NULL_TREE;
1795   finish_var_decl (decl, exp);
1796 }
1797
1798 static tree
1799 get_proto_encoding (tree proto)
1800 {
1801   tree encoding;
1802   if (proto)
1803     {
1804       if (! METHOD_ENCODING (proto))
1805         {
1806           encoding = encode_method_prototype (proto);
1807           METHOD_ENCODING (proto) = encoding;
1808         }
1809       else
1810         encoding = METHOD_ENCODING (proto);
1811
1812       return add_objc_string (encoding, meth_var_types);
1813     }
1814   else
1815     return build_int_cst (NULL_TREE, 0);
1816 }
1817
1818 static void
1819 build_gnu_selector_translation_table (void)
1820 {
1821   tree chain, expr;
1822   vec<constructor_elt, va_gc> *inits = NULL;
1823   vec<constructor_elt, va_gc> *v ;
1824
1825   /* Cause the selector table (previously forward-declared)
1826      to be actually output.  */
1827
1828   for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1829     {
1830       tree encoding;
1831       if (warn_selector)
1832         {
1833           /* TODO: improve on the location for the diagnostic.  */
1834           location_t loc = input_location;
1835           diagnose_missing_method (TREE_VALUE (chain), loc);
1836         }
1837
1838       v = NULL;
1839       expr = build_selector (TREE_VALUE (chain));
1840       encoding = get_proto_encoding (TREE_PURPOSE (chain));
1841       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1842       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, encoding);
1843       expr = objc_build_constructor (objc_selector_template, v);
1844
1845       CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
1846     } /* each element in the chain */
1847
1848   /* List terminator.  */
1849   v = NULL;
1850   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
1851   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
1852   expr = objc_build_constructor (objc_selector_template, v);
1853
1854   CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
1855   expr = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
1856                                      inits);
1857   finish_var_decl (UOBJC_SELECTOR_TABLE_decl, expr);
1858 }
1859
1860 /* Output references to all statically allocated objects.  Return the DECL
1861    for the array built.  */
1862
1863 static void
1864 generate_static_references (void)
1865 {
1866   tree expr = NULL_TREE;
1867   tree class_name, klass, decl;
1868   tree cl_chain, in_chain, type
1869     = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
1870   int num_inst, num_class;
1871   char buf[BUFSIZE];
1872   vec<constructor_elt, va_gc> *decls = NULL;
1873
1874   /* FIXME: Remove NeXT runtime code.  */
1875   if (flag_next_runtime)
1876     gcc_unreachable ();
1877
1878   for (cl_chain = objc_static_instances, num_class = 0;
1879        cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1880     {
1881       vec<constructor_elt, va_gc> *v = NULL;
1882
1883       for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1884            in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1885
1886       snprintf (buf, BUFSIZE, "_OBJC_STATIC_INSTANCES_%d", num_class);
1887       decl = start_var_decl (type, buf);
1888
1889       /* Output {class_name, ...}.  */
1890       klass = TREE_VALUE (cl_chain);
1891       class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names);
1892       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1893                               build_unary_op (input_location,
1894                                               ADDR_EXPR, class_name, 1));
1895
1896       /* Output {..., instance, ...}.  */
1897       for (in_chain = TREE_PURPOSE (cl_chain);
1898            in_chain; in_chain = TREE_CHAIN (in_chain))
1899         {
1900           expr = build_unary_op (input_location,
1901                                  ADDR_EXPR, TREE_VALUE (in_chain), 1);
1902           CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1903         }
1904
1905       /* Output {..., NULL}.  */
1906       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1907
1908       expr = objc_build_constructor (TREE_TYPE (decl), v);
1909       OBJCMETA (decl, objc_meta, meta_base);
1910       finish_var_decl (decl, expr);
1911       CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE,
1912                               build_unary_op (input_location,
1913                                               ADDR_EXPR, decl, 1));
1914     }
1915
1916   CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE, build_int_cst (NULL_TREE, 0));
1917   expr = objc_build_constructor (type, decls);
1918   static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
1919   OBJCMETA (static_instances_decl, objc_meta, meta_base);
1920   finish_var_decl (static_instances_decl, expr);
1921 }
1922
1923 /* Create the initial value for the `defs' field of _objc_symtab.
1924    This is a CONSTRUCTOR.  */
1925
1926 static tree
1927 init_def_list (tree type)
1928 {
1929   tree expr;
1930   struct imp_entry *impent;
1931   location_t loc;
1932   vec<constructor_elt, va_gc> *v = NULL;
1933
1934   if (imp_count)
1935     for (impent = imp_list; impent; impent = impent->next)
1936       {
1937         if (TREE_CODE (impent->imp_context) == CLASS_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   if (cat_count)
1947     for (impent = imp_list; impent; impent = impent->next)
1948       {
1949         if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1950           {
1951             loc = DECL_SOURCE_LOCATION (impent->class_decl);
1952             expr = build_unary_op (loc,
1953                                    ADDR_EXPR, impent->class_decl, 0);
1954             CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1955           }
1956       }
1957
1958   loc = UNKNOWN_LOCATION;
1959   /* statics = { ..., _OBJC_STATIC_INSTANCES, ... }  */
1960   if (static_instances_decl)
1961     expr = build_unary_op (loc, ADDR_EXPR, static_instances_decl, 0);
1962   else
1963     expr = integer_zero_node;
1964   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1965
1966   return objc_build_constructor (type, v);
1967 }
1968
1969 /* Take care of defining and initializing _OBJC_SYMBOLS.  */
1970
1971 /* Predefine the following data type:
1972
1973    struct _objc_symtab
1974    {
1975      long sel_ref_cnt;
1976      SEL *refs;
1977      short cls_def_cnt;
1978      short cat_def_cnt;
1979      void *defs[cls_def_cnt + cat_def_cnt];
1980    }; */
1981
1982 static void
1983 build_objc_symtab_template (void)
1984 {
1985   tree fields, array_type, *chain = NULL;
1986   int index;
1987
1988   objc_symtab_template = objc_start_struct (get_identifier (UTAG_SYMTAB));
1989
1990   /* long sel_ref_cnt; */
1991   fields = add_field_decl (long_integer_type_node, "sel_ref_cnt", &chain);
1992
1993   /* SEL *refs; */
1994   add_field_decl (build_pointer_type (objc_selector_type), "refs", &chain);
1995
1996   /* short cls_def_cnt; */
1997   add_field_decl (short_integer_type_node, "cls_def_cnt", &chain);
1998
1999   /* short cat_def_cnt; */
2000   add_field_decl (short_integer_type_node, "cat_def_cnt", &chain);
2001
2002   /* Note that padding will be added here on LP64.  */
2003
2004   /* void *defs[imp_count + cat_count (+ 1)]; */
2005   /* NB: The index is one less than the size of the array.  */
2006   index = imp_count + cat_count;
2007   array_type = build_sized_array_type (ptr_type_node, index + 1);
2008   add_field_decl (array_type, "defs", &chain);
2009
2010   objc_finish_struct (objc_symtab_template, fields);
2011 }
2012 /* Construct the initial value for all of _objc_symtab.  */
2013
2014 static tree
2015 init_objc_symtab (tree type)
2016 {
2017   tree field, expr, ltyp;
2018   location_t loc;
2019   vec<constructor_elt, va_gc> *v = NULL;
2020
2021   loc = UNKNOWN_LOCATION;
2022
2023   /* sel_ref_cnt = { ..., 5, ... } */
2024
2025   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2026                           build_int_cst (long_integer_type_node, 0));
2027
2028   /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2029
2030   ltyp = build_pointer_type (objc_selector_type);
2031   if (sel_ref_chain)
2032     expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR,
2033                                           UOBJC_SELECTOR_TABLE_decl, 1));
2034   else
2035     expr = convert (ltyp, null_pointer_node);
2036   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2037
2038   /* cls_def_cnt = { ..., 5, ... } */
2039
2040   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2041                           build_int_cst (short_integer_type_node, imp_count));
2042
2043   /* cat_def_cnt = { ..., 5, ... } */
2044
2045   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2046                           build_int_cst (short_integer_type_node, cat_count));
2047
2048   /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2049
2050   field = TYPE_FIELDS (type);
2051   field = DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (field))));
2052
2053   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init_def_list (TREE_TYPE (field)));
2054
2055   return objc_build_constructor (type, v);
2056 }
2057
2058 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2059    and initialized appropriately.  */
2060
2061 static void
2062 generate_objc_symtab_decl (void)
2063 {
2064   build_objc_symtab_template ();
2065   UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
2066   OBJCMETA (UOBJC_SYMBOLS_decl, objc_meta, meta_base);
2067   finish_var_decl (UOBJC_SYMBOLS_decl,
2068                    init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
2069 }
2070
2071 static void
2072 objc_generate_v1_gnu_metadata (void)
2073 {
2074   struct imp_entry *impent;
2075   tree chain;
2076
2077   /* Process the static instances here because initialization of objc_symtab
2078      depends on them.  */
2079   if (objc_static_instances)
2080     generate_static_references ();
2081
2082   objc_implementation_context =
2083   implementation_template =
2084   UOBJC_CLASS_decl =
2085   UOBJC_METACLASS_decl = NULL_TREE;
2086
2087   for (impent = imp_list; impent; impent = impent->next)
2088     {
2089       /* If -gen-decls is present, Dump the @interface of each class.
2090          TODO: Dump the classes in the  order they were found, rather than in
2091          reverse order as we are doing now.  */
2092       if (flag_gen_declaration)
2093         dump_interface (gen_declaration_file, impent->imp_context);
2094
2095       /* all of the following reference the string pool...  */
2096       if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
2097         generate_class_structures (impent);
2098       else
2099         generate_category (impent);
2100     }
2101
2102   /* If we are using an array of selectors, we must always
2103      finish up the array decl even if no selectors were used.  */
2104   build_gnu_selector_translation_table ();
2105
2106   if (protocol_chain)
2107     generate_protocols ();
2108
2109   /* Arrange for ObjC data structures to be initialized at run time.  */
2110   /* FIXME: Have some more elegant way to determine if we need to
2111      generate objc_symtab_decl or not, instead of checking these
2112      global symbols.  */
2113   if (imp_list || class_names_chain
2114       || meth_var_names_chain || meth_var_types_chain || sel_ref_chain
2115       || prop_names_attr_chain)
2116     generate_objc_symtab_decl ();
2117
2118   if (imp_list || class_names_chain || objc_static_instances
2119       || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
2120     {
2121       /* Make sure that the meta-data are identified as being
2122          GNU-runtime.  */
2123       build_module_descriptor (OBJC_VERSION,
2124                                build_tree_list (objc_meta, meta_base));
2125       build_module_initializer_routine ();
2126     }
2127
2128   /* Dump the class references.  This forces the appropriate classes
2129      to be linked into the executable image, preserving unix archive
2130      semantics.  This can be removed when we move to a more dynamically
2131      linked environment.  */
2132
2133   for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
2134     {
2135       handle_class_ref (chain);
2136       if (TREE_PURPOSE (chain))
2137         generate_classref_translation_entry (chain);
2138     }
2139
2140   for (impent = imp_list; impent; impent = impent->next)
2141     handle_impent (impent);
2142
2143   generate_strings ();
2144 }
2145
2146 /* --- exceptions --- */
2147
2148 static GTY(()) tree objc_eh_personality_decl;
2149
2150 static tree
2151 objc_eh_runtime_type (tree type)
2152 {
2153   tree ident, eh_id, decl, str;
2154
2155   if (type == error_mark_node
2156       || errorcount || sorrycount)
2157     {
2158       /* Use 'ErrorMarkNode' as class name when error_mark_node is found
2159          to prevent an ICE.  Note that we know that the compiler will
2160          terminate with an error and this 'ErrorMarkNode' class name will
2161          never be actually used.  */
2162       ident = get_identifier ("ErrorMarkNode");
2163       goto make_err_class;
2164     }
2165
2166   if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
2167     /* We don't want to identify 'id' for GNU. Instead, build a 0
2168        entry in the exceptions table.  */
2169     return null_pointer_node;
2170
2171   if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
2172     {
2173 #ifdef OBJCPLUS
2174       /* This routine is also called for c++ catch clauses; in which case,
2175          we use the c++ typeinfo decl. */
2176       return build_eh_type_type (type);
2177 #else
2178       error ("non-objective-c type '%T' cannot be caught", type);
2179       ident = get_identifier ("ErrorMarkNode");
2180       goto make_err_class;
2181 #endif
2182     }
2183   else
2184     ident = OBJC_TYPE_NAME (TREE_TYPE (type));
2185
2186 make_err_class:
2187   /* If this class was already referenced, then it will be output during
2188      meta-data emission, so we don't need to do it here.  */
2189   decl = get_objc_string_decl (ident, class_names);
2190   eh_id = add_objc_string (ident, class_names);
2191   if (!decl)
2192     {
2193       /* Not found ... so we need to build it - from the freshly-entered id.  */
2194       decl = get_objc_string_decl (ident, class_names);
2195       str = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2196                              IDENTIFIER_POINTER (ident));
2197       /* We have to finalize this var here, because this might be called after
2198          all the other metadata strings have been emitted.  */
2199       finish_var_decl (decl, str);
2200     }
2201   return eh_id;
2202 }
2203
2204 static tree
2205 objc_eh_personality (void)
2206 {
2207   if (!objc_eh_personality_decl)
2208 #ifndef OBJCPLUS
2209     objc_eh_personality_decl = build_personality_function  ("gnu_objc");
2210 #else
2211     objc_eh_personality_decl = build_personality_function  ("gxx");
2212 #endif
2213   return objc_eh_personality_decl;
2214 }
2215
2216 /* -- interfaces --- */
2217
2218 static tree
2219 build_throw_stmt (location_t loc, tree throw_expr, bool rethrown ATTRIBUTE_UNUSED)
2220 {
2221   tree t;
2222   vec<tree, va_gc> *parms;
2223   vec_alloc (parms, 1);
2224   /* A throw is just a call to the runtime throw function with the
2225      object as a parameter.  */
2226   parms->quick_push (throw_expr);
2227   t = build_function_call_vec (loc, vNULL, objc_exception_throw_decl, parms,
2228                                NULL);
2229   vec_free (parms);
2230   return add_stmt (t);
2231 }
2232
2233 /* Build __builtin_eh_pointer.  */
2234
2235 static tree
2236 objc_build_exc_ptr (struct objc_try_context **x ATTRIBUTE_UNUSED)
2237 {
2238   tree t;
2239   t = builtin_decl_explicit (BUILT_IN_EH_POINTER);
2240   t = build_call_expr (t, 1, integer_zero_node);
2241   return fold_convert (objc_object_type, t);
2242 }
2243
2244 static tree
2245 begin_catch (struct objc_try_context **cur_try_context, tree type,
2246              tree decl, tree compound, bool ellipsis ATTRIBUTE_UNUSED)
2247 {
2248   tree t;
2249   /* Record the data for the catch in the try context so that we can
2250      finalize it later.  */
2251   if (ellipsis)
2252     t = build_stmt (input_location, CATCH_EXPR, NULL, compound);
2253   else
2254     t = build_stmt (input_location, CATCH_EXPR, type, compound);
2255   (*cur_try_context)->current_catch = t;
2256
2257   /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime.  */
2258   t = objc_build_exc_ptr (cur_try_context);
2259   t = convert (TREE_TYPE (decl), t);
2260   return build2 (MODIFY_EXPR, void_type_node, decl, t);
2261 }
2262
2263 static void
2264 finish_catch (struct objc_try_context **cur_try_context, tree current_catch)
2265 {
2266   append_to_statement_list (current_catch, &((*cur_try_context)->catch_list));
2267 }
2268
2269 static tree
2270 finish_try_stmt (struct objc_try_context **cur_try_context)
2271 {
2272   struct objc_try_context *c = *cur_try_context;
2273   tree stmt = c->try_body;
2274   if (c->catch_list)
2275     stmt = build_stmt (c->try_locus, TRY_CATCH_EXPR, stmt, c->catch_list);
2276   if (c->finally_body)
2277     stmt = build_stmt (c->try_locus, TRY_FINALLY_EXPR, stmt, c->finally_body);
2278   return stmt;
2279 }
2280
2281 #include "gt-objc-objc-gnu-runtime-abi-01.h"