xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/objc/objc-gnu-runtime-abi-01.c (revision 95b39c65ca575fb40c6bb7083e0eb7ec28eabef1)
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"
2269