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