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