1 /* GNU Runtime ABI version 8
2    Copyright (C) 2011 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-tree.h"
28 #else
29 #include "c-tree.h"
30 #include "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,gc) **, tree,
108 						       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   /* FIXME: Do we need this assemble_external() ? */
578   /* assemble_external (objc_get_class_decl);*/
579   return build_function_call (input_location, objc_get_class_decl, params);
580 }
581 
582 /* Used by build_function_type_for_method.  Append the types for
583    receiver & _cmd at the start of a method argument list to ARGTYPES.
584    CONTEXT is either METHOD_DEF or METHOD_REF, saying whether we are
585    trying to define a method or call one.  SUPERFLAG says this is for a
586    send to super.  METH may be NULL, in the case that there is no
587    prototype.  */
588 
589 static void
590 gnu_runtime_abi_01_get_arg_type_list_base (VEC(tree,gc) **argtypes, tree meth,
591 					   int context,
592 					   int superflag ATTRIBUTE_UNUSED)
593 {
594   tree receiver_type;
595 
596   if (context == METHOD_DEF && TREE_CODE (meth) == INSTANCE_METHOD_DECL)
597     receiver_type = objc_instance_type;
598   else
599     receiver_type = objc_object_type;
600 
601   VEC_safe_push (tree, gc, *argtypes, receiver_type);
602   /* Selector type - will eventually change to `int'.  */
603   VEC_safe_push (tree, gc, *argtypes, objc_selector_type);
604 }
605 
606 /* Unused for GNU runtime.  */
607 static tree
608 gnu_runtime_abi_01_receiver_is_class_object (tree a ATTRIBUTE_UNUSED)
609 {
610   return NULL_TREE;
611 }
612 
613 /* sel_ref_chain is a list whose "value" fields will be instances of
614    identifier_node that represent the selector.  LOC is the location of
615    the @selector.  */
616 
617 static tree
618 gnu_runtime_abi_01_build_typed_selector_reference (location_t loc, tree ident,
619 						   tree prototype)
620 {
621   tree *chain = &sel_ref_chain;
622   tree expr;
623   int index = 0;
624 
625   while (*chain)
626     {
627       /* When we do a lookup for @selector () we have no idea of the
628          prototype - so match the first we find.  */
629       if (TREE_VALUE (*chain) == ident
630           && (!prototype || TREE_PURPOSE (*chain) == prototype))
631 	goto return_at_index;
632 
633       index++;
634       chain = &TREE_CHAIN (*chain);
635     }
636 
637   *chain = tree_cons (prototype, ident, NULL_TREE);
638 
639   /* TODO: Use a vec and keep this in it to (a) avoid re-creating and
640      (b) provide better diagnostics for the first time an undefined
641      selector is used.  */
642  return_at_index:
643   expr = build_unary_op (loc, ADDR_EXPR,
644 			 build_array_ref (loc, UOBJC_SELECTOR_TABLE_decl,
645 					  build_int_cst (NULL_TREE, index)),
646 			 1);
647   return convert (objc_selector_type, expr);
648 }
649 
650 /* Build a tree expression to send OBJECT the operation SELECTOR,
651    looking up the method on object LOOKUP_OBJECT (often same as OBJECT),
652    assuming the method has prototype METHOD_PROTOTYPE.
653    (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.)
654    LOC is the location of the expression to build.
655    Use METHOD_PARAMS as list of args to pass to the method.
656    If SUPER_FLAG is nonzero, we look up the superclass's method.  */
657 
658 static tree
659 build_objc_method_call (location_t loc, int super_flag, tree method_prototype,
660 			tree lookup_object, tree selector,
661 			tree method_params)
662 {
663   tree sender = (super_flag ? umsg_super_decl
664 			    : (flag_objc_direct_dispatch ? umsg_fast_decl
665 							 : umsg_decl));
666   tree rcv_p = (super_flag ? objc_super_type : objc_object_type);
667   VEC(tree, gc) *parms;
668   VEC(tree, gc) *tv;
669   unsigned nparm = (method_params ? list_length (method_params) : 0);
670 
671   /* If a prototype for the method to be called exists, then cast
672      the sender's return type and arguments to match that of the method.
673      Otherwise, leave sender as is.  */
674   tree ret_type
675     = (method_prototype
676        ? TREE_VALUE (TREE_TYPE (method_prototype))
677        : objc_object_type);
678   tree ftype
679     = build_function_type_for_method (ret_type, method_prototype,
680 				      METHOD_REF, super_flag);
681   tree sender_cast;
682   tree method, t;
683 
684   if (method_prototype && METHOD_TYPE_ATTRIBUTES (method_prototype))
685     ftype = build_type_attribute_variant (ftype,
686 					  METHOD_TYPE_ATTRIBUTES
687 					  (method_prototype));
688 
689   sender_cast = build_pointer_type (ftype);
690 
691   lookup_object = build_c_cast (loc, rcv_p, lookup_object);
692 
693   /* Use SAVE_EXPR to avoid evaluating the receiver twice.  */
694   lookup_object = save_expr (lookup_object);
695 
696   /* Param list + 2 slots for object and selector.  */
697   parms = VEC_alloc (tree, gc, nparm + 2);
698   tv = VEC_alloc (tree, gc, 2);
699 
700   /* First, call the lookup function to get a pointer to the method,
701      then cast the pointer, then call it with the method arguments.  */
702   VEC_quick_push (tree, tv, lookup_object);
703   VEC_quick_push (tree, tv, selector);
704   method = build_function_call_vec (loc, sender, tv, NULL);
705   VEC_free (tree, gc, tv);
706 
707   /* Pass the appropriate object to the method.  */
708   VEC_quick_push (tree, parms, (super_flag ? self_decl : lookup_object));
709 
710   /* Pass the selector to the method.  */
711   VEC_quick_push (tree, parms, selector);
712   /* Now append the remainder of the parms.  */
713   if (nparm)
714     for (; method_params; method_params = TREE_CHAIN (method_params))
715       VEC_quick_push (tree, parms, TREE_VALUE (method_params));
716 
717   /* Build an obj_type_ref, with the correct cast for the method call.  */
718   t = build3 (OBJ_TYPE_REF, sender_cast, method, lookup_object, size_zero_node);
719   t = build_function_call_vec (loc, t, parms, NULL);
720   VEC_free (tree, gc, parms);
721   return t;
722 }
723 
724 static tree
725 gnu_runtime_abi_01_build_objc_method_call (location_t loc,
726 					   tree method_prototype,
727 					   tree receiver,
728 					   tree rtype ATTRIBUTE_UNUSED,
729 					   tree sel_name,
730 					   tree method_params,
731 					   int super ATTRIBUTE_UNUSED)
732 {
733   tree selector =
734 	gnu_runtime_abi_01_build_typed_selector_reference (loc,
735 							  sel_name,
736 							  method_prototype);
737 
738   return build_objc_method_call (loc, super, method_prototype, receiver,
739 				 selector, method_params);
740 }
741 
742 static tree
743 gnu_runtime_abi_01_get_protocol_reference (location_t loc, tree p)
744 {
745   tree expr, protocol_struct_type, *chain;
746   if (!PROTOCOL_FORWARD_DECL (p))
747     PROTOCOL_FORWARD_DECL (p) = gnu_runtime_abi_01_protocol_decl (p);
748 
749   expr = build_unary_op (loc, ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0);
750 
751   /* ??? Ideally we'd build the reference with objc_protocol_type directly,
752      if we have it, rather than converting it here.  */
753   expr = convert (objc_protocol_type, expr);
754 
755   /* The @protocol() expression is being compiled into a pointer to a
756      statically allocated instance of the Protocol class.  To become
757      usable at runtime, the 'isa' pointer of the instance need to be
758      fixed up at runtime by the runtime library, to point to the
759      actual 'Protocol' class.  */
760 
761   /* For the GNU runtime, put the static Protocol instance in the list
762      of statically allocated instances, so that we make sure that its
763      'isa' pointer is fixed up at runtime by the GNU runtime library
764      to point to the Protocol class (at runtime, when loading the
765      module, the GNU runtime library loops on the statically allocated
766      instances (as found in the defs field in objc_symtab) and fixups
767      all the 'isa' pointers of those objects).  */
768 
769   /* This type is a struct containing the fields of a Protocol
770      object.  (Cfr. objc_protocol_type instead is the type of a pointer
771      to such a struct).  */
772   protocol_struct_type = xref_tag (RECORD_TYPE,
773 				   get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
774 
775   /* Look for the list of Protocol statically allocated instances
776      to fixup at runtime.  Create a new list to hold Protocol
777      statically allocated instances, if the list is not found.  At
778      present there is only another list, holding NSConstantString
779      static instances to be fixed up at runtime.  */
780 
781   for (chain = &objc_static_instances;
782 	*chain && TREE_VALUE (*chain) != protocol_struct_type;
783 	chain = &TREE_CHAIN (*chain));
784 
785   if (!*chain)
786     {
787        *chain = tree_cons (NULL_TREE, protocol_struct_type, NULL_TREE);
788        add_objc_string (OBJC_TYPE_NAME (protocol_struct_type),
789                           class_names);
790     }
791 
792   /* Add this statically allocated instance to the Protocol list.  */
793   TREE_PURPOSE (*chain) = tree_cons (NULL_TREE,
794 				     PROTOCOL_FORWARD_DECL (p),
795 				     TREE_PURPOSE (*chain));
796   return expr;
797 }
798 
799 /* For ABI 8 an IVAR is just a fixed offset in the class struct.  */
800 
801 static tree
802 gnu_runtime_abi_01_build_ivar_ref (location_t loc ATTRIBUTE_UNUSED,
803 				   tree base, tree id)
804 {
805   return objc_build_component_ref (base, id);
806 }
807 
808 /* We build super class references as we need them (but keep them once
809    built for the sake of efficiency).  */
810 
811 static tree
812 gnu_runtime_abi_01_get_class_super_ref (location_t loc ATTRIBUTE_UNUSED,
813 					struct imp_entry *imp, bool inst_meth)
814 {
815   if (inst_meth)
816     {
817       if (!ucls_super_ref)
818 	ucls_super_ref =
819 		objc_build_component_ref (imp->class_decl,
820 					  get_identifier ("super_class"));
821 	return ucls_super_ref;
822     }
823   else
824     {
825       if (!uucls_super_ref)
826 	uucls_super_ref =
827 		objc_build_component_ref (imp->meta_decl,
828 					  get_identifier ("super_class"));
829 	return uucls_super_ref;
830     }
831 }
832 
833 static tree
834 gnu_runtime_abi_01_get_category_super_ref (location_t loc ATTRIBUTE_UNUSED,
835 					   struct imp_entry *imp, bool inst_meth)
836 {
837   tree super_name = CLASS_SUPER_NAME (imp->imp_template);
838   tree super_class;
839 
840   add_class_reference (super_name);
841   super_class = (inst_meth ? objc_get_class_decl : objc_get_meta_class_decl);
842   /* FIXME: Do we need this assemble_external() ? */
843   /* assemble_external (super_class);*/
844   super_name = my_build_string_pointer (IDENTIFIER_LENGTH (super_name) + 1,
845 					IDENTIFIER_POINTER (super_name));
846   /* super_class = get_{meta_}class("CLASS_SUPER_NAME");  */
847   return build_function_call (input_location,
848 			      super_class,
849 			      build_tree_list (NULL_TREE, super_name));
850 }
851 
852 static bool
853 gnu_runtime_abi_01_setup_const_string_class_decl (void)
854 {
855   /* Do nothing, and create no error.  */
856   return true;
857 }
858 
859 /* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR.  */
860 
861 static GTY(()) int num_static_inst;
862 
863 static tree
864 objc_add_static_instance (tree constructor, tree class_decl)
865 {
866   tree *chain, decl;
867   char buf[BUFSIZE];
868 
869   /* Find the list of static instances for the CLASS_DECL.  Create one if
870      not found.  */
871   for (chain = &objc_static_instances;
872        *chain && TREE_VALUE (*chain) != class_decl;
873        chain = &TREE_CHAIN (*chain));
874   if (!*chain)
875     {
876       *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE);
877       add_objc_string (OBJC_TYPE_NAME (class_decl), class_names);
878     }
879 
880   snprintf (buf, BUFSIZE, "_OBJC_INSTANCE_%d", num_static_inst++);
881   decl = build_decl (input_location,
882 		     VAR_DECL, get_identifier (buf), class_decl);
883   TREE_STATIC (decl) = 1;
884   DECL_ARTIFICIAL (decl) = 1;
885   TREE_USED (decl) = 1;
886   DECL_INITIAL (decl) = constructor;
887   DECL_CONTEXT (decl) = NULL;
888   OBJCMETA (decl, objc_meta, meta_base);
889 
890   /* We may be writing something else just now.
891      Postpone till end of input. */
892   DECL_DEFER_OUTPUT (decl) = 1;
893   pushdecl_top_level (decl);
894   rest_of_decl_compilation (decl, 1, 0);
895 
896   /* Add the DECL to the head of this CLASS' list.  */
897   TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain));
898 
899   return decl;
900 }
901 
902 static tree
903 gnu_runtime_abi_01_build_const_string_constructor (location_t loc, tree string,
904 						   int length)
905 {
906   tree constructor, fields;
907   VEC(constructor_elt,gc) *v = NULL;
908 
909   /* GNU:    (NXConstantString *) & ((__builtin_ObjCString) { NULL, string, length })  */
910   fields = TYPE_FIELDS (internal_const_str_type);
911   CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, 0));
912 
913   fields = DECL_CHAIN (fields);
914   CONSTRUCTOR_APPEND_ELT (v, fields, build_unary_op (loc,
915 						     ADDR_EXPR, string, 1));
916 
917   fields = DECL_CHAIN (fields);
918   CONSTRUCTOR_APPEND_ELT (v, fields, build_int_cst (NULL_TREE, length));
919   constructor = objc_build_constructor (internal_const_str_type, v);
920 
921   constructor = objc_add_static_instance (constructor, constant_string_type);
922   return constructor;
923 }
924 
925 /* --- metadata - module initializer --- */
926 
927 /* The GNU runtime requires us to provide a static initializer function
928    for each module:
929 
930    static void __objc_gnu_init (void) {
931      __objc_exec_class (&L_OBJC_MODULES);
932    }  */
933 
934 
935 static void
936 build_module_initializer_routine (void)
937 {
938   tree body;
939 
940 #ifdef OBJCPLUS
941   push_lang_context (lang_name_c); /* extern "C" */
942 #endif
943 
944   objc_push_parm (build_decl (input_location,
945 			      PARM_DECL, NULL_TREE, void_type_node));
946 #ifdef OBJCPLUS
947   objc_start_function (get_identifier (TAG_GNUINIT),
948 		       build_function_type_list (void_type_node, NULL_TREE),
949 		       NULL_TREE, NULL_TREE);
950 #else
951   objc_start_function (get_identifier (TAG_GNUINIT),
952 		       build_function_type_list (void_type_node, NULL_TREE),
953 		       NULL_TREE, objc_get_parm_info (0, NULL_TREE));
954 #endif
955   body = c_begin_compound_stmt (true);
956   add_stmt (build_function_call
957 	    (input_location,
958 	     execclass_decl,
959 	     build_tree_list
960 	     (NULL_TREE,
961 	      build_unary_op (input_location, ADDR_EXPR,
962 			      UOBJC_MODULES_decl, 0))));
963   add_stmt (c_end_compound_stmt (input_location, body, true));
964 
965   TREE_PUBLIC (current_function_decl) = 0;
966 
967 #ifndef OBJCPLUS
968   /* For Objective-C++, we will need to call __objc_gnu_init
969      from objc_generate_static_init_call() below.  */
970   DECL_STATIC_CONSTRUCTOR (current_function_decl) = 1;
971 #endif
972 
973   GNU_INIT_decl = current_function_decl;
974   finish_function ();
975 
976 #ifdef OBJCPLUS
977     pop_lang_context ();
978 #endif
979 }
980 
981 #ifdef OBJCPLUS
982 /* Return 1 if the __objc_gnu_init function has been synthesized and needs
983    to be called by the module initializer routine.  */
984 
985 int
986 objc_static_init_needed_p (void)
987 {
988   return (GNU_INIT_decl != NULL_TREE);
989 }
990 
991 /* Generate a call to the __objc_gnu_init initializer function.  */
992 
993 tree
994 objc_generate_static_init_call (tree ctors ATTRIBUTE_UNUSED)
995 {
996   add_stmt (build_stmt (input_location, EXPR_STMT,
997 			build_function_call (input_location,
998 					     GNU_INIT_decl, NULL_TREE)));
999 
1000   return ctors;
1001 }
1002 #endif /* OBJCPLUS */
1003 
1004 /* --- Output GNU Meta-data --- */
1005 
1006 static void
1007 generate_classref_translation_entry (tree chain)
1008 {
1009   tree expr, decl, type;
1010 
1011   decl = TREE_PURPOSE (chain);
1012   type = TREE_TYPE (decl);
1013 
1014   expr = add_objc_string (TREE_VALUE (chain), class_names);
1015   expr = convert (type, expr); /* cast! */
1016 
1017   /* This is a class reference.  It is re-written by the runtime,
1018      but will be optimized away unless we force it.  */
1019   DECL_PRESERVE_P (decl) = 1;
1020   OBJCMETA (decl, objc_meta, meta_base);
1021   finish_var_decl (decl, expr);
1022   return;
1023 }
1024 
1025 
1026 static void
1027 handle_impent (struct imp_entry *impent)
1028 {
1029   char *string;
1030 
1031 /*  objc_implementation_context = impent->imp_context;
1032   implementation_template = impent->imp_template;*/
1033 
1034   switch (TREE_CODE (impent->imp_context))
1035     {
1036     case CLASS_IMPLEMENTATION_TYPE:
1037       {
1038 	const char *const class_name =
1039 	  IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
1040 
1041 	string = (char *) alloca (strlen (class_name) + 30);
1042 
1043 	sprintf (string, "__objc_class_name_%s", class_name);
1044 	break;
1045       }
1046     case CATEGORY_IMPLEMENTATION_TYPE:
1047       {
1048 	const char *const class_name =
1049 	  IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context));
1050 	const char *const class_super_name =
1051 	  IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context));
1052 
1053 	string = (char *) alloca (strlen (class_name)
1054 				  + strlen (class_super_name) + 30);
1055 
1056 	/* Do the same for categories.  Even though no references to
1057 	   these symbols are generated automatically by the compiler,
1058 	   it gives you a handle to pull them into an archive by
1059 	   hand.  */
1060 	sprintf (string, "*__objc_category_name_%s_%s", class_name, class_super_name);
1061 	break;
1062       }
1063     default:
1064       return;
1065     }
1066 
1067     {
1068       tree decl, init;
1069 
1070       init = integer_zero_node;
1071       decl = build_decl (input_location,
1072 			 VAR_DECL, get_identifier (string), TREE_TYPE (init));
1073       TREE_PUBLIC (decl) = 1;
1074       TREE_READONLY (decl) = 1;
1075       TREE_USED (decl) = 1;
1076       TREE_CONSTANT (decl) = 1;
1077       DECL_CONTEXT (decl) = NULL_TREE;
1078       DECL_ARTIFICIAL (decl) = 1;
1079       TREE_STATIC (decl) = 1;
1080       DECL_INITIAL (decl) = error_mark_node; /* A real initializer is coming... */
1081       /* We must force the reference.  */
1082       DECL_PRESERVE_P (decl) = 1;
1083 
1084       finish_var_decl(decl, init) ;
1085     }
1086 }
1087 
1088 tree
1089 build_protocol_initializer (tree type, tree protocol_name, tree protocol_list,
1090 			    tree inst_methods, tree class_methods)
1091 {
1092   tree expr, ttyp;
1093   location_t loc;
1094   VEC(constructor_elt,gc) *inits = NULL;
1095 
1096   /* TODO: pass the loc in or find it from args.  */
1097   loc = input_location;
1098   ttyp = build_pointer_type (xref_tag (RECORD_TYPE,
1099 				       get_identifier (UTAG_CLASS)));
1100   /* Filling the "isa" in with a version allows the runtime system to
1101      detect this ...   */
1102   expr = build_int_cst (ttyp, PROTOCOL_VERSION);
1103 
1104   CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
1105 
1106   CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_name);
1107   CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, protocol_list);
1108 
1109   ttyp = objc_method_proto_list_ptr;
1110   if (inst_methods)
1111     expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, inst_methods, 0));
1112   else
1113     expr = convert (ttyp, null_pointer_node);
1114   CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
1115 
1116   if (class_methods)
1117     expr = convert (ttyp, build_unary_op (loc, ADDR_EXPR, class_methods, 0));
1118   else
1119     expr = convert (ttyp, null_pointer_node);
1120   CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
1121 
1122   return objc_build_constructor (type, inits);
1123 }
1124 
1125 static tree
1126 generate_protocol_list (tree i_or_p, tree klass_ctxt)
1127 {
1128   tree array_type, ptype, refs_decl, lproto, e, plist;
1129   VEC(constructor_elt,gc) *v = NULL;
1130   char buf[BUFSIZE];
1131   int size = 0;
1132 
1133   switch (TREE_CODE (i_or_p))
1134     {
1135     case CLASS_INTERFACE_TYPE:
1136     case CATEGORY_INTERFACE_TYPE:
1137       plist = CLASS_PROTOCOL_LIST (i_or_p);
1138       break;
1139     case PROTOCOL_INTERFACE_TYPE:
1140       plist = PROTOCOL_LIST (i_or_p);
1141       break;
1142     default:
1143       gcc_unreachable ();
1144     }
1145 
1146   /* Compute size.  */
1147   for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
1148     if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE
1149 	&& PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto)))
1150       size++;
1151 
1152   /* Build initializer.  */
1153   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1154   e = build_int_cst (build_pointer_type (objc_protocol_template), size);
1155   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
1156 
1157   for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
1158     {
1159       tree pval = TREE_VALUE (lproto);
1160 
1161       if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE
1162 	  && PROTOCOL_FORWARD_DECL (pval))
1163 	{
1164 	  tree fwref = PROTOCOL_FORWARD_DECL (pval);
1165 	  location_t loc = DECL_SOURCE_LOCATION (fwref) ;
1166 	  e = build_unary_op (loc, ADDR_EXPR, fwref, 0);
1167           CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, e);
1168 	}
1169     }
1170 
1171   /* static struct objc_protocol *refs[n]; */
1172 
1173   switch (TREE_CODE (i_or_p))
1174     {
1175     case PROTOCOL_INTERFACE_TYPE:
1176       snprintf (buf, BUFSIZE, "_OBJC_ProtocolRefs_%s",
1177 		IDENTIFIER_POINTER (PROTOCOL_NAME (i_or_p)));
1178       break;
1179     case CLASS_INTERFACE_TYPE:
1180       snprintf (buf, BUFSIZE, "_OBJC_ClassProtocols_%s",
1181 		IDENTIFIER_POINTER (CLASS_NAME (i_or_p)));
1182       break;
1183     case CATEGORY_INTERFACE_TYPE:
1184       snprintf (buf, BUFSIZE, "_OBJC_CategoryProtocols_%s_%s",
1185 		IDENTIFIER_POINTER (CLASS_NAME (klass_ctxt)),
1186 		IDENTIFIER_POINTER (CLASS_SUPER_NAME (klass_ctxt)));
1187       break;
1188     default:
1189       gcc_unreachable ();
1190     }
1191 
1192   ptype = build_pointer_type (objc_protocol_template);
1193   array_type = build_sized_array_type (ptype, size + 3);
1194   refs_decl = start_var_decl (array_type, buf);
1195   OBJCMETA (refs_decl, objc_meta, meta_base);
1196   finish_var_decl (refs_decl,
1197                    objc_build_constructor (TREE_TYPE (refs_decl), v));
1198 
1199   return refs_decl;
1200 }
1201 
1202 static tree
1203 generate_v1_meth_descriptor_table (tree chain, tree protocol, const char *prefix)
1204 {
1205   tree method_list_template, initlist, decl;
1206   int size;
1207   VEC(constructor_elt,gc) *v = NULL;
1208   char buf[BUFSIZE];
1209 
1210   if (!chain || !prefix)
1211     return NULL_TREE;
1212 
1213   if (!objc_method_prototype_template)
1214     objc_method_prototype_template = build_method_prototype_template ();
1215 
1216   size = list_length (chain);
1217   method_list_template =
1218 	build_method_prototype_list_template (objc_method_prototype_template,
1219 					      size);
1220   snprintf (buf, BUFSIZE, "%s_%s", prefix,
1221 	    IDENTIFIER_POINTER (PROTOCOL_NAME (protocol)));
1222 
1223   decl = start_var_decl (method_list_template, buf);
1224 
1225   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, size));
1226   initlist =
1227 	build_descriptor_table_initializer (objc_method_prototype_template,
1228 					    chain);
1229   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, initlist);
1230   OBJCMETA (decl, objc_meta, meta_base);
1231   finish_var_decl (decl, objc_build_constructor (method_list_template, v));
1232   return decl;
1233 }
1234 
1235 /* For each protocol which was referenced either from a @protocol()
1236    expression, or because a class/category implements it (then a
1237    pointer to the protocol is stored in the struct describing the
1238    class/category), we create a statically allocated instance of the
1239    Protocol class.  The code is written in such a way as to generate
1240    as few Protocol objects as possible; we generate a unique Protocol
1241    instance for each protocol, and we don't generate a Protocol
1242    instance if the protocol is never referenced (either from a
1243    @protocol() or from a class/category implementation).  These
1244    statically allocated objects can be referred to via the static
1245    (that is, private to this module) symbols _OBJC_PROTOCOL_n.
1246 
1247    The statically allocated Protocol objects that we generate here
1248    need to be fixed up at runtime in order to be used: the 'isa'
1249    pointer of the objects need to be set up to point to the 'Protocol'
1250    class, as known at runtime.
1251 
1252    The GNU runtime fixes up all protocols before user code from the module
1253    is executed; it requires pointers to those symbols
1254    to be put in the objc_symtab (which is then passed as argument to
1255    the function __objc_exec_class() which the compiler sets up to be
1256    executed automatically when the module is loaded); setup of those
1257    Protocol objects happen in two ways in the GNU runtime: all
1258    Protocol objects referred to by a class or category implementation
1259    are fixed up when the class/category is loaded; all Protocol
1260    objects referred to by a @protocol() expression are added by the
1261    compiler to the list of statically allocated instances to fixup
1262    (the same list holding the statically allocated constant string
1263    objects).  Because, as explained above, the compiler generates as
1264    few Protocol objects as possible, some Protocol object might end up
1265    being referenced multiple times when compiled with the GNU runtime,
1266    and end up being fixed up multiple times at runtime initialization.
1267    But that doesn't hurt, it's just a little inefficient.  */
1268 
1269 static void
1270 generate_protocols (void)
1271 {
1272   tree p, encoding;
1273   tree decl;
1274   tree initlist, protocol_name_expr, refs_decl, refs_expr;
1275 
1276   /* If a protocol was directly referenced, pull in indirect references.  */
1277   for (p = protocol_chain; p; p = TREE_CHAIN (p))
1278     if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p))
1279       generate_protocol_references (PROTOCOL_LIST (p));
1280 
1281   for (p = protocol_chain; p; p = TREE_CHAIN (p))
1282     {
1283       tree nst_methods = PROTOCOL_NST_METHODS (p);
1284       tree cls_methods = PROTOCOL_CLS_METHODS (p);
1285 
1286       /* If protocol wasn't referenced, don't generate any code.  */
1287       decl = PROTOCOL_FORWARD_DECL (p);
1288 
1289       if (!decl)
1290 	continue;
1291 
1292       /* Make sure we link in the Protocol class.  */
1293       add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME));
1294 
1295       while (nst_methods)
1296 	{
1297 	  if (! METHOD_ENCODING (nst_methods))
1298 	    {
1299 	      encoding = encode_method_prototype (nst_methods);
1300 	      METHOD_ENCODING (nst_methods) = encoding;
1301 	    }
1302 	  nst_methods = DECL_CHAIN (nst_methods);
1303 	}
1304 
1305       UOBJC_INSTANCE_METHODS_decl =
1306 	generate_v1_meth_descriptor_table (PROTOCOL_NST_METHODS (p), p,
1307 					   "_OBJC_PROTOCOL_INSTANCE_METHODS");
1308 
1309       while (cls_methods)
1310 	{
1311 	  if (! METHOD_ENCODING (cls_methods))
1312 	    {
1313 	      encoding = encode_method_prototype (cls_methods);
1314 	      METHOD_ENCODING (cls_methods) = encoding;
1315 	    }
1316 
1317 	  cls_methods = DECL_CHAIN (cls_methods);
1318 	}
1319 
1320       UOBJC_CLASS_METHODS_decl =
1321 	generate_v1_meth_descriptor_table (PROTOCOL_CLS_METHODS (p), p,
1322 					   "_OBJC_PROTOCOL_CLASS_METHODS");
1323 /*      generate_method_descriptors (p);*/
1324 
1325       if (PROTOCOL_LIST (p))
1326 	refs_decl = generate_protocol_list (p, NULL_TREE);
1327       else
1328 	refs_decl = 0;
1329 
1330       /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */
1331       protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names);
1332 
1333       if (refs_decl)
1334 	refs_expr = convert (build_pointer_type (build_pointer_type
1335 						 (objc_protocol_template)),
1336 			     build_unary_op (input_location,
1337 					     ADDR_EXPR, refs_decl, 0));
1338       else
1339 	refs_expr = build_int_cst (NULL_TREE, 0);
1340 
1341       /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set
1342 	 by generate_method_descriptors, which is called above.  */
1343       initlist = build_protocol_initializer (TREE_TYPE (decl),
1344 					     protocol_name_expr, refs_expr,
1345 					     UOBJC_INSTANCE_METHODS_decl,
1346 					     UOBJC_CLASS_METHODS_decl);
1347       finish_var_decl (decl, initlist);
1348     }
1349 }
1350 
1351 static tree
1352 generate_dispatch_table (tree chain, const char *name)
1353 {
1354   tree decl, method_list_template, initlist;
1355   VEC(constructor_elt,gc) *v = NULL;
1356   int size = list_length (chain);
1357 
1358   if (!objc_method_template)
1359     objc_method_template = build_method_template ();
1360 
1361   method_list_template = build_method_list_template (objc_method_template,
1362 						     size);
1363   initlist = build_dispatch_table_initializer (objc_method_template, chain);
1364 
1365   decl = start_var_decl (method_list_template, name);
1366 
1367   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
1368   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1369 			  build_int_cst (integer_type_node, size));
1370   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, initlist);
1371 
1372   OBJCMETA (decl, objc_meta, meta_base);
1373   finish_var_decl (decl,
1374 		   objc_build_constructor (TREE_TYPE (decl), v));
1375 
1376   return decl;
1377 }
1378 
1379 /* Init a category.  */
1380 static tree
1381 build_category_initializer (tree type, tree cat_name, tree class_name,
1382 			    tree inst_methods, tree class_methods,
1383 			    tree protocol_list)
1384 {
1385   tree expr, ltyp;
1386   location_t loc;
1387   VEC(constructor_elt,gc) *v = NULL;
1388 
1389   /* TODO: pass the loc in or find it from args.  */
1390   /* TODO: pass the loc in or find it from args.  */
1391   loc = UNKNOWN_LOCATION;
1392   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, cat_name);
1393   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, class_name);
1394 
1395   ltyp = objc_method_list_ptr;
1396   if (inst_methods)
1397     expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, inst_methods, 0));
1398   else
1399     expr = convert (ltyp, null_pointer_node);
1400   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1401 
1402   if (class_methods)
1403     expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, class_methods, 0));
1404   else
1405     expr = convert (ltyp, null_pointer_node);
1406   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1407 
1408   /* protocol_list = */
1409   ltyp = build_pointer_type (build_pointer_type (objc_protocol_template));
1410   if (protocol_list)
1411     expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR, protocol_list, 0));
1412   else
1413     expr = convert (ltyp, null_pointer_node);
1414   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1415 
1416   return objc_build_constructor (type, v);
1417 }
1418 
1419 /* static struct objc_category _OBJC_CATEGORY_<name> = { ... };  */
1420 
1421 static void
1422 generate_category (struct imp_entry *impent)
1423 {
1424   tree initlist, cat_name_expr, class_name_expr;
1425   tree protocol_decl, category, cat_decl;
1426   tree inst_methods = NULL_TREE, class_methods = NULL_TREE;
1427   tree cat = impent->imp_context;
1428   char buf[BUFSIZE];
1429 
1430   cat_decl = impent->class_decl;
1431 
1432   add_class_reference (CLASS_NAME (cat));
1433   cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names);
1434 
1435   class_name_expr = add_objc_string (CLASS_NAME (cat), class_names);
1436 
1437   category = lookup_category (impent->imp_template, CLASS_SUPER_NAME (cat));
1438 
1439   if (category && CLASS_PROTOCOL_LIST (category))
1440     {
1441       generate_protocol_references (CLASS_PROTOCOL_LIST (category));
1442       protocol_decl = generate_protocol_list (category, cat);
1443     }
1444   else
1445     protocol_decl = 0;
1446 
1447   if (CLASS_NST_METHODS (cat))
1448     {
1449       snprintf (buf, BUFSIZE, "_OBJC_CategoryInstanceMethods_%s_%s",
1450 		IDENTIFIER_POINTER (CLASS_NAME (cat)),
1451 		IDENTIFIER_POINTER (CLASS_SUPER_NAME (cat)));
1452       inst_methods = generate_dispatch_table (CLASS_NST_METHODS (cat), buf);
1453     }
1454 
1455   if (CLASS_CLS_METHODS (cat))
1456     {
1457       snprintf (buf, BUFSIZE, "_OBJC_CategoryClassMethods_%s_%s",
1458 		IDENTIFIER_POINTER (CLASS_NAME (cat)),
1459 		IDENTIFIER_POINTER (CLASS_SUPER_NAME (cat)));
1460       class_methods = generate_dispatch_table (CLASS_CLS_METHODS (cat), buf);
1461     }
1462 
1463   initlist = build_category_initializer (TREE_TYPE (cat_decl),
1464 					 cat_name_expr, class_name_expr,
1465 					 inst_methods, class_methods,
1466 					 protocol_decl);
1467   /* Finish and initialize the forward decl.  */
1468   finish_var_decl (cat_decl, initlist);
1469   impent->class_decl = cat_decl;
1470 }
1471 
1472 /* struct _objc_class {
1473      struct objc_class *isa;
1474      struct objc_class *super_class;
1475      char *name;
1476      long version;
1477      long info;
1478      long instance_size;
1479      struct objc_ivar_list *ivars;
1480      struct objc_method_list *methods;
1481      struct sarray *dtable;
1482      struct objc_class *subclass_list;
1483      struct objc_class *sibling_class;
1484      struct objc_protocol_list *protocols;
1485      void *gc_object_type;
1486    };  */
1487 
1488 static tree
1489 build_shared_structure_initializer (tree type, tree isa, tree super,
1490 				    tree name, tree size, int status,
1491 				    tree dispatch_table, tree ivar_list,
1492 				    tree protocol_list)
1493 {
1494   tree expr, ltyp;
1495   VEC(constructor_elt,gc) *v = NULL;
1496 
1497   /* isa = */
1498   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, isa);
1499 
1500   /* super_class = */
1501   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, super);
1502 
1503   /* name = */
1504   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, default_conversion (name));
1505 
1506   /* version = */
1507   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1508                           build_int_cst (long_integer_type_node, 0));
1509 
1510   /* info = */
1511   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1512                           build_int_cst (long_integer_type_node, status));
1513 
1514   /* instance_size = */
1515   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1516                           convert (long_integer_type_node, size));
1517 
1518   /* objc_ivar_list = */
1519   if (!ivar_list)
1520     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1521 			    build_int_cst (objc_ivar_list_ptr, 0));
1522   else
1523     {
1524       expr = convert (objc_ivar_list_ptr,
1525 		      build_unary_op (input_location, ADDR_EXPR,
1526 				      ivar_list, 0));
1527       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1528     }
1529 
1530   /* objc_method_list = */
1531   if (!dispatch_table)
1532     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1533 			   convert (objc_method_list_ptr, null_pointer_node));
1534   else
1535     {
1536       expr = convert (objc_method_list_ptr,
1537 		      build_unary_op (input_location, ADDR_EXPR,
1538 				      dispatch_table, 0));
1539       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1540     }
1541 
1542   /* FIXME: Remove NeXT runtime code.  */
1543   if (flag_next_runtime)
1544     {
1545       ltyp = build_pointer_type (xref_tag (RECORD_TYPE,
1546 					   get_identifier ("objc_cache")));
1547       /* method_cache = */
1548       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, convert (ltyp, null_pointer_node));
1549     }
1550   else
1551     {
1552       /* dtable = */
1553       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1554 
1555       /* subclass_list = */
1556       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1557 
1558       /* sibling_class = */
1559       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1560     }
1561 
1562   /* protocol_list = */
1563   ltyp = build_pointer_type (build_pointer_type (objc_protocol_template));
1564   if (! protocol_list)
1565     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (ltyp, 0));
1566   else
1567     {
1568       expr = convert (ltyp,
1569 		      build_unary_op (input_location, ADDR_EXPR,
1570 				      protocol_list, 0));
1571       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1572     }
1573 
1574   /* FIXME: Remove NeXT runtime code.  */
1575   if (flag_next_runtime)
1576     /* sel_id = NULL */
1577     CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1578 
1579   /* gc_object_type = NULL */
1580   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1581 
1582   return objc_build_constructor (type, v);
1583 }
1584 
1585 
1586 static tree
1587 generate_ivars_list (tree chain, const char *name)
1588 {
1589   tree initlist, ivar_list_template, decl;
1590   int size;
1591   VEC(constructor_elt,gc) *inits = NULL;
1592 
1593   if (!chain)
1594     return NULL_TREE;
1595 
1596   if (!objc_ivar_template)
1597     objc_ivar_template = build_ivar_template ();
1598 
1599   size = ivar_list_length (chain);
1600 
1601   generating_instance_variables = 1;
1602   ivar_list_template = build_ivar_list_template (objc_ivar_template, size);
1603   initlist = build_ivar_list_initializer (objc_ivar_template, chain);
1604   generating_instance_variables = 0;
1605 
1606   decl = start_var_decl (ivar_list_template, name);
1607 
1608   CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, build_int_cst (NULL_TREE, size));
1609   CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, initlist);
1610 
1611   OBJCMETA (decl, objc_meta, meta_base);
1612   finish_var_decl (decl,
1613 		   objc_build_constructor (TREE_TYPE (decl), inits));
1614 
1615   return decl;
1616 }
1617 
1618 /* static struct objc_class _OBJC_METACLASS_Foo={ ... };
1619    static struct objc_class _OBJC_CLASS_Foo={ ... };  */
1620 
1621 static void
1622 generate_class_structures (struct imp_entry *impent)
1623 {
1624   tree name_expr, super_expr, root_expr, class_decl, meta_decl;
1625   tree my_root_id, my_super_id;
1626   tree cast_type, initlist, protocol_decl;
1627   tree inst_methods = NULL_TREE, class_methods = NULL_TREE;
1628   tree chain, inst_ivars = NULL_TREE, class_ivars = NULL_TREE;
1629   location_t loc;
1630   char buf[BUFSIZE];
1631   int cls_flags = 0 ;
1632 
1633 /*  objc_implementation_context = impent->imp_context;
1634   implementation_template = impent->imp_template;*/
1635   class_decl = impent->class_decl;
1636   meta_decl = impent->meta_decl;
1637 /*  UOBJC_CLASS_decl = impent->class_decl;
1638   UOBJC_METACLASS_decl = impent->meta_decl;*/
1639 
1640   loc = DECL_SOURCE_LOCATION (impent->class_decl);
1641 
1642   my_super_id = CLASS_SUPER_NAME (impent->imp_template);
1643   if (my_super_id)
1644     {
1645       add_class_reference (my_super_id);
1646 
1647       /* Compute "my_root_id" - this is required for code generation.
1648          the "isa" for all meta class structures points to the root of
1649          the inheritance hierarchy (e.g. "__Object")...  */
1650       my_root_id = my_super_id;
1651       do
1652 	{
1653 	  tree my_root_int = lookup_interface (my_root_id);
1654 
1655 	  if (my_root_int && CLASS_SUPER_NAME (my_root_int))
1656 	    my_root_id = CLASS_SUPER_NAME (my_root_int);
1657 	  else
1658 	    break;
1659 	}
1660       while (1);
1661     }
1662   else
1663     /* No super class.  */
1664     my_root_id = CLASS_NAME (impent->imp_template);
1665 
1666   cast_type = build_pointer_type (objc_class_template);
1667   name_expr = add_objc_string (CLASS_NAME (impent->imp_template),
1668 			       class_names);
1669 
1670   /* Install class `isa' and `super' pointers at runtime.  */
1671   if (my_super_id)
1672     super_expr = add_objc_string (my_super_id, class_names);
1673   else
1674     super_expr = null_pointer_node;
1675 
1676   super_expr = build_c_cast (loc, cast_type, super_expr);
1677 
1678   root_expr = add_objc_string (my_root_id, class_names);
1679   root_expr = build_c_cast (loc, cast_type, root_expr);
1680 
1681   if (CLASS_PROTOCOL_LIST (impent->imp_template))
1682     {
1683       generate_protocol_references (CLASS_PROTOCOL_LIST (impent->imp_template));
1684       protocol_decl = generate_protocol_list (impent->imp_template,
1685 					      impent->imp_context);
1686     }
1687   else
1688     protocol_decl = NULL_TREE;
1689 
1690   if (CLASS_CLS_METHODS (impent->imp_context))
1691     {
1692       snprintf (buf, BUFSIZE, "_OBJC_ClassMethods_%s",
1693 		IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
1694       class_methods = generate_dispatch_table (CLASS_CLS_METHODS (impent->imp_context),
1695 					       buf);
1696     }
1697 
1698   if (CLASS_SUPER_NAME (impent->imp_template) == NULL_TREE
1699       && (chain = TYPE_FIELDS (objc_class_template)))
1700     {
1701       snprintf (buf, BUFSIZE, "_OBJC_ClassIvars_%s",
1702 		IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
1703       class_ivars = generate_ivars_list (chain, buf);
1704     }
1705 
1706   /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */
1707 
1708   initlist =
1709 	build_shared_structure_initializer
1710 			(TREE_TYPE (meta_decl),
1711 			root_expr, super_expr, name_expr,
1712 			convert (integer_type_node,
1713 				TYPE_SIZE_UNIT (objc_class_template)),
1714 			CLS_META, class_methods, class_ivars,
1715 			protocol_decl);
1716 
1717   finish_var_decl (meta_decl, initlist);
1718   impent->meta_decl = meta_decl;
1719 
1720   /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */
1721   if (CLASS_NST_METHODS (impent->imp_context))
1722     {
1723       snprintf (buf, BUFSIZE, "_OBJC_InstanceMethods_%s",
1724 		IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
1725       inst_methods = generate_dispatch_table (CLASS_NST_METHODS (impent->imp_context),
1726 					      buf);
1727     }
1728 
1729   if ((chain = CLASS_IVARS (impent->imp_template)))
1730     {
1731       snprintf (buf, BUFSIZE, "_OBJC_InstanceIvars_%s",
1732 		IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)));
1733       inst_ivars = generate_ivars_list (chain, buf);
1734     }
1735 
1736   initlist =
1737 	build_shared_structure_initializer
1738 		(TREE_TYPE (class_decl),
1739 		build_unary_op (loc, ADDR_EXPR, meta_decl, 0),
1740 		super_expr, name_expr,
1741 		convert (integer_type_node,
1742 			 TYPE_SIZE_UNIT (CLASS_STATIC_TEMPLATE
1743 					(impent->imp_template))),
1744 		CLS_FACTORY | cls_flags, inst_methods, inst_ivars,
1745 		protocol_decl);
1746 
1747   finish_var_decl (class_decl, initlist);
1748   impent->class_decl = class_decl;
1749 }
1750 
1751 /* --- Output GNU Metadata --- */
1752 
1753 /* TODO: Make this into an array of refs.  */
1754 static void
1755 handle_class_ref (tree chain)
1756 {
1757   const char *name = IDENTIFIER_POINTER (TREE_VALUE (chain));
1758   char *string = (char *) alloca (strlen (name) + 30);
1759   tree decl;
1760   tree exp;
1761 
1762   sprintf (string, "__objc_class_name_%s", name);
1763 
1764   /* Make a decl for this name, so we can use its address in a tree.  */
1765   decl = build_decl (input_location,
1766 		     VAR_DECL, get_identifier (string), TREE_TYPE (integer_zero_node));
1767   DECL_EXTERNAL (decl) = 1;
1768   TREE_PUBLIC (decl) = 1;
1769   DECL_CONTEXT (decl) = NULL_TREE;
1770   finish_var_decl (decl, 0);
1771 
1772   /* Make a decl for the address.  */
1773   sprintf (string, "__objc_class_ref_%s", name);
1774   exp = build1 (ADDR_EXPR, string_type_node, decl);
1775   decl = build_decl (input_location,
1776 		     VAR_DECL, get_identifier (string), string_type_node);
1777   TREE_STATIC (decl) = 1;
1778   TREE_USED (decl) = 1;
1779   DECL_READ_P (decl) = 1;
1780   DECL_ARTIFICIAL (decl) = 1;
1781   DECL_INITIAL (decl) = error_mark_node;
1782 
1783   /* We must force the reference.  */
1784   DECL_PRESERVE_P (decl) = 1;
1785 
1786   DECL_CONTEXT (decl) = NULL_TREE;
1787   finish_var_decl (decl, exp);
1788 }
1789 
1790 static tree
1791 get_proto_encoding (tree proto)
1792 {
1793   tree encoding;
1794   if (proto)
1795     {
1796       if (! METHOD_ENCODING (proto))
1797 	{
1798 	  encoding = encode_method_prototype (proto);
1799 	  METHOD_ENCODING (proto) = encoding;
1800 	}
1801       else
1802 	encoding = METHOD_ENCODING (proto);
1803 
1804       return add_objc_string (encoding, meth_var_types);
1805     }
1806   else
1807     return build_int_cst (NULL_TREE, 0);
1808 }
1809 
1810 static void
1811 build_gnu_selector_translation_table (void)
1812 {
1813   tree chain, expr;
1814   VEC(constructor_elt,gc) *inits = NULL;
1815   VEC(constructor_elt,gc) *v ;
1816 
1817   /* Cause the selector table (previously forward-declared)
1818      to be actually output.  */
1819 
1820   for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
1821     {
1822       tree encoding;
1823       if (warn_selector)
1824 	{
1825 	  /* TODO: improve on the location for the diagnostic.  */
1826 	  location_t loc = input_location;
1827 	  diagnose_missing_method (TREE_VALUE (chain), loc);
1828 	}
1829 
1830       v = NULL;
1831       expr = build_selector (TREE_VALUE (chain));
1832       encoding = get_proto_encoding (TREE_PURPOSE (chain));
1833       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1834       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, encoding);
1835       expr = objc_build_constructor (objc_selector_template, v);
1836 
1837       CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
1838     } /* each element in the chain */
1839 
1840   /* List terminator.  */
1841   v = NULL;
1842   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
1843   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, integer_zero_node);
1844   expr = objc_build_constructor (objc_selector_template, v);
1845 
1846   CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE, expr);
1847   expr = objc_build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl),
1848 				     inits);
1849   finish_var_decl (UOBJC_SELECTOR_TABLE_decl, expr);
1850 }
1851 
1852 /* Output references to all statically allocated objects.  Return the DECL
1853    for the array built.  */
1854 
1855 static void
1856 generate_static_references (void)
1857 {
1858   tree expr = NULL_TREE;
1859   tree class_name, klass, decl;
1860   tree cl_chain, in_chain, type
1861     = build_array_type (build_pointer_type (void_type_node), NULL_TREE);
1862   int num_inst, num_class;
1863   char buf[BUFSIZE];
1864   VEC(constructor_elt,gc) *decls = NULL;
1865 
1866   /* FIXME: Remove NeXT runtime code.  */
1867   if (flag_next_runtime)
1868     gcc_unreachable ();
1869 
1870   for (cl_chain = objc_static_instances, num_class = 0;
1871        cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++)
1872     {
1873       VEC(constructor_elt,gc) *v = NULL;
1874 
1875       for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain);
1876 	   in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain));
1877 
1878       snprintf (buf, BUFSIZE, "_OBJC_STATIC_INSTANCES_%d", num_class);
1879       decl = start_var_decl (type, buf);
1880 
1881       /* Output {class_name, ...}.  */
1882       klass = TREE_VALUE (cl_chain);
1883       class_name = get_objc_string_decl (OBJC_TYPE_NAME (klass), class_names);
1884       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
1885 			      build_unary_op (input_location,
1886 					      ADDR_EXPR, class_name, 1));
1887 
1888       /* Output {..., instance, ...}.  */
1889       for (in_chain = TREE_PURPOSE (cl_chain);
1890 	   in_chain; in_chain = TREE_CHAIN (in_chain))
1891 	{
1892 	  expr = build_unary_op (input_location,
1893 				 ADDR_EXPR, TREE_VALUE (in_chain), 1);
1894 	  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1895 	}
1896 
1897       /* Output {..., NULL}.  */
1898       CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, build_int_cst (NULL_TREE, 0));
1899 
1900       expr = objc_build_constructor (TREE_TYPE (decl), v);
1901       OBJCMETA (decl, objc_meta, meta_base);
1902       finish_var_decl (decl, expr);
1903       CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE,
1904 			      build_unary_op (input_location,
1905 					      ADDR_EXPR, decl, 1));
1906     }
1907 
1908   CONSTRUCTOR_APPEND_ELT (decls, NULL_TREE, build_int_cst (NULL_TREE, 0));
1909   expr = objc_build_constructor (type, decls);
1910   static_instances_decl = start_var_decl (type, "_OBJC_STATIC_INSTANCES");
1911   OBJCMETA (static_instances_decl, objc_meta, meta_base);
1912   finish_var_decl (static_instances_decl, expr);
1913 }
1914 
1915 /* Create the initial value for the `defs' field of _objc_symtab.
1916    This is a CONSTRUCTOR.  */
1917 
1918 static tree
1919 init_def_list (tree type)
1920 {
1921   tree expr;
1922   struct imp_entry *impent;
1923   location_t loc;
1924   VEC(constructor_elt,gc) *v = NULL;
1925 
1926   if (imp_count)
1927     for (impent = imp_list; impent; impent = impent->next)
1928       {
1929 	if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
1930 	  {
1931 	    loc = DECL_SOURCE_LOCATION (impent->class_decl);
1932 	    expr = build_unary_op (loc,
1933 				   ADDR_EXPR, impent->class_decl, 0);
1934 	    CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1935 	  }
1936       }
1937 
1938   if (cat_count)
1939     for (impent = imp_list; impent; impent = impent->next)
1940       {
1941 	if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE)
1942 	  {
1943 	    loc = DECL_SOURCE_LOCATION (impent->class_decl);
1944 	    expr = build_unary_op (loc,
1945 				   ADDR_EXPR, impent->class_decl, 0);
1946 	    CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1947 	  }
1948       }
1949 
1950   loc = UNKNOWN_LOCATION;
1951   /* statics = { ..., _OBJC_STATIC_INSTANCES, ... }  */
1952   if (static_instances_decl)
1953     expr = build_unary_op (loc, ADDR_EXPR, static_instances_decl, 0);
1954   else
1955     expr = integer_zero_node;
1956   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
1957 
1958   return objc_build_constructor (type, v);
1959 }
1960 
1961 /* Take care of defining and initializing _OBJC_SYMBOLS.  */
1962 
1963 /* Predefine the following data type:
1964 
1965    struct _objc_symtab
1966    {
1967      long sel_ref_cnt;
1968      SEL *refs;
1969      short cls_def_cnt;
1970      short cat_def_cnt;
1971      void *defs[cls_def_cnt + cat_def_cnt];
1972    }; */
1973 
1974 static void
1975 build_objc_symtab_template (void)
1976 {
1977   tree fields, array_type, *chain = NULL;
1978   int index;
1979 
1980   objc_symtab_template = objc_start_struct (get_identifier (UTAG_SYMTAB));
1981 
1982   /* long sel_ref_cnt; */
1983   fields = add_field_decl (long_integer_type_node, "sel_ref_cnt", &chain);
1984 
1985   /* SEL *refs; */
1986   add_field_decl (build_pointer_type (objc_selector_type), "refs", &chain);
1987 
1988   /* short cls_def_cnt; */
1989   add_field_decl (short_integer_type_node, "cls_def_cnt", &chain);
1990 
1991   /* short cat_def_cnt; */
1992   add_field_decl (short_integer_type_node, "cat_def_cnt", &chain);
1993 
1994   /* Note that padding will be added here on LP64.  */
1995 
1996   /* void *defs[imp_count + cat_count (+ 1)]; */
1997   /* NB: The index is one less than the size of the array.  */
1998   index = imp_count + cat_count;
1999   array_type = build_sized_array_type (ptr_type_node, index + 1);
2000   add_field_decl (array_type, "defs", &chain);
2001 
2002   objc_finish_struct (objc_symtab_template, fields);
2003 }
2004 /* Construct the initial value for all of _objc_symtab.  */
2005 
2006 static tree
2007 init_objc_symtab (tree type)
2008 {
2009   tree field, expr, ltyp;
2010   location_t loc;
2011   VEC(constructor_elt,gc) *v = NULL;
2012 
2013   loc = UNKNOWN_LOCATION;
2014 
2015   /* sel_ref_cnt = { ..., 5, ... } */
2016 
2017   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2018 			  build_int_cst (long_integer_type_node, 0));
2019 
2020   /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */
2021 
2022   ltyp = build_pointer_type (objc_selector_type);
2023   if (sel_ref_chain)
2024     expr = convert (ltyp, build_unary_op (loc, ADDR_EXPR,
2025 					  UOBJC_SELECTOR_TABLE_decl, 1));
2026   else
2027     expr = convert (ltyp, null_pointer_node);
2028   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
2029 
2030   /* cls_def_cnt = { ..., 5, ... } */
2031 
2032   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2033 			  build_int_cst (short_integer_type_node, imp_count));
2034 
2035   /* cat_def_cnt = { ..., 5, ... } */
2036 
2037   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE,
2038 			  build_int_cst (short_integer_type_node, cat_count));
2039 
2040   /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */
2041 
2042   field = TYPE_FIELDS (type);
2043   field = DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (DECL_CHAIN (field))));
2044 
2045   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init_def_list (TREE_TYPE (field)));
2046 
2047   return objc_build_constructor (type, v);
2048 }
2049 
2050 /* Create the declaration of _OBJC_SYMBOLS, with type `struct _objc_symtab'
2051    and initialized appropriately.  */
2052 
2053 static void
2054 generate_objc_symtab_decl (void)
2055 {
2056   build_objc_symtab_template ();
2057   UOBJC_SYMBOLS_decl = start_var_decl (objc_symtab_template, "_OBJC_SYMBOLS");
2058   OBJCMETA (UOBJC_SYMBOLS_decl, objc_meta, meta_base);
2059   finish_var_decl (UOBJC_SYMBOLS_decl,
2060 		   init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)));
2061 }
2062 
2063 static void
2064 objc_generate_v1_gnu_metadata (void)
2065 {
2066   struct imp_entry *impent;
2067   tree chain;
2068 
2069   /* Process the static instances here because initialization of objc_symtab
2070      depends on them.  */
2071   if (objc_static_instances)
2072     generate_static_references ();
2073 
2074   objc_implementation_context =
2075   implementation_template =
2076   UOBJC_CLASS_decl =
2077   UOBJC_METACLASS_decl = NULL_TREE;
2078 
2079   for (impent = imp_list; impent; impent = impent->next)
2080     {
2081       /* If -gen-decls is present, Dump the @interface of each class.
2082 	 TODO: Dump the classes in the  order they were found, rather than in
2083 	 reverse order as we are doing now.  */
2084       if (flag_gen_declaration)
2085 	dump_interface (gen_declaration_file, impent->imp_context);
2086 
2087       /* all of the following reference the string pool...  */
2088       if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE)
2089 	generate_class_structures (impent);
2090       else
2091 	generate_category (impent);
2092     }
2093 
2094   /* If we are using an array of selectors, we must always
2095      finish up the array decl even if no selectors were used.  */
2096   build_gnu_selector_translation_table ();
2097 
2098   if (protocol_chain)
2099     generate_protocols ();
2100 
2101   /* Arrange for ObjC data structures to be initialized at run time.  */
2102   /* FIXME: Have some more elegant way to determine if we need to
2103      generate objc_symtab_decl or not, instead of checking these
2104      global symbols.  */
2105   if (imp_list || class_names_chain
2106       || meth_var_names_chain || meth_var_types_chain || sel_ref_chain
2107       || prop_names_attr_chain)
2108     generate_objc_symtab_decl ();
2109 
2110   if (imp_list || class_names_chain || objc_static_instances
2111       || meth_var_names_chain || meth_var_types_chain || sel_ref_chain)
2112     {
2113       /* Make sure that the meta-data are identified as being
2114 	 GNU-runtime.  */
2115       build_module_descriptor (OBJC_VERSION,
2116 			       build_tree_list (objc_meta, meta_base));
2117       build_module_initializer_routine ();
2118     }
2119 
2120   /* Dump the class references.  This forces the appropriate classes
2121      to be linked into the executable image, preserving unix archive
2122      semantics.  This can be removed when we move to a more dynamically
2123      linked environment.  */
2124 
2125   for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain))
2126     {
2127       handle_class_ref (chain);
2128       if (TREE_PURPOSE (chain))
2129 	generate_classref_translation_entry (chain);
2130     }
2131 
2132   for (impent = imp_list; impent; impent = impent->next)
2133     handle_impent (impent);
2134 
2135   generate_strings ();
2136 }
2137 
2138 /* --- exceptions --- */
2139 
2140 static GTY(()) tree objc_eh_personality_decl;
2141 
2142 static tree
2143 objc_eh_runtime_type (tree type)
2144 {
2145   tree ident, eh_id, decl, str;
2146 
2147   if (type == error_mark_node
2148       || errorcount || sorrycount)
2149     {
2150       /* Use 'ErrorMarkNode' as class name when error_mark_node is found
2151 	 to prevent an ICE.  Note that we know that the compiler will
2152 	 terminate with an error and this 'ErrorMarkNode' class name will
2153 	 never be actually used.  */
2154       ident = get_identifier ("ErrorMarkNode");
2155       goto make_err_class;
2156     }
2157 
2158   if (POINTER_TYPE_P (type) && objc_is_object_id (TREE_TYPE (type)))
2159     /* We don't want to identify 'id' for GNU. Instead, build a 0
2160        entry in the exceptions table.  */
2161     return null_pointer_node;
2162 
2163   if (!POINTER_TYPE_P (type) || !TYPED_OBJECT (TREE_TYPE (type)))
2164     {
2165 #ifdef OBJCPLUS
2166       /* This routine is also called for c++ catch clauses; in which case,
2167 	 we use the c++ typeinfo decl. */
2168       return build_eh_type_type (type);
2169 #else
2170       error ("non-objective-c type '%T' cannot be caught", type);
2171       ident = get_identifier ("ErrorMarkNode");
2172       goto make_err_class;
2173 #endif
2174     }
2175   else
2176     ident = OBJC_TYPE_NAME (TREE_TYPE (type));
2177 
2178 make_err_class:
2179   /* If this class was already referenced, then it will be output during
2180      meta-data emission, so we don't need to do it here.  */
2181   decl = get_objc_string_decl (ident, class_names);
2182   eh_id = add_objc_string (ident, class_names);
2183   if (!decl)
2184     {
2185       /* Not found ... so we need to build it - from the freshly-entered id.  */
2186       decl = get_objc_string_decl (ident, class_names);
2187       str = my_build_string (IDENTIFIER_LENGTH (ident) + 1,
2188 			     IDENTIFIER_POINTER (ident));
2189       /* We have to finalize this var here, because this might be called after
2190 	 all the other metadata strings have been emitted.  */
2191       finish_var_decl (decl, str);
2192     }
2193   return eh_id;
2194 }
2195 
2196 static tree
2197 objc_eh_personality (void)
2198 {
2199   if (!objc_eh_personality_decl)
2200 #ifndef OBJCPLUS
2201     objc_eh_personality_decl = build_personality_function  ("gnu_objc");
2202 #else
2203     objc_eh_personality_decl = build_personality_function  ("gxx");
2204 #endif
2205   return objc_eh_personality_decl;
2206 }
2207 
2208 /* -- interfaces --- */
2209 
2210 static tree
2211 build_throw_stmt (location_t loc, tree throw_expr, bool rethrown ATTRIBUTE_UNUSED)
2212 {
2213   tree t;
2214   VEC(tree, gc) *parms = VEC_alloc (tree, gc, 1);
2215   /* A throw is just a call to the runtime throw function with the
2216      object as a parameter.  */
2217   VEC_quick_push (tree, parms, throw_expr);
2218   t = build_function_call_vec (loc, objc_exception_throw_decl, parms, NULL);
2219   VEC_free (tree, gc, parms);
2220   return add_stmt (t);
2221 }
2222 
2223 /* Build __builtin_eh_pointer.  */
2224 
2225 static tree
2226 objc_build_exc_ptr (struct objc_try_context **x ATTRIBUTE_UNUSED)
2227 {
2228   tree t;
2229   t = builtin_decl_explicit (BUILT_IN_EH_POINTER);
2230   t = build_call_expr (t, 1, integer_zero_node);
2231   return fold_convert (objc_object_type, t);
2232 }
2233 
2234 static tree
2235 begin_catch (struct objc_try_context **cur_try_context, tree type,
2236 	     tree decl, tree compound, bool ellipsis ATTRIBUTE_UNUSED)
2237 {
2238   tree t;
2239   /* Record the data for the catch in the try context so that we can
2240      finalize it later.  */
2241   if (ellipsis)
2242     t = build_stmt (input_location, CATCH_EXPR, NULL, compound);
2243   else
2244     t = build_stmt (input_location, CATCH_EXPR, type, compound);
2245   (*cur_try_context)->current_catch = t;
2246 
2247   /* Initialize the decl from the EXC_PTR_EXPR we get from the runtime.  */
2248   t = objc_build_exc_ptr (cur_try_context);
2249   t = convert (TREE_TYPE (decl), t);
2250   return build2 (MODIFY_EXPR, void_type_node, decl, t);
2251 }
2252 
2253 static void
2254 finish_catch (struct objc_try_context **cur_try_context, tree current_catch)
2255 {
2256   append_to_statement_list (current_catch, &((*cur_try_context)->catch_list));
2257 }
2258 
2259 static tree
2260 finish_try_stmt (struct objc_try_context **cur_try_context)
2261 {
2262   struct objc_try_context *c = *cur_try_context;
2263   tree stmt = c->try_body;
2264   if (c->catch_list)
2265     stmt = build_stmt (c->try_locus, TRY_CATCH_EXPR, stmt, c->catch_list);
2266   if (c->finally_body)
2267     stmt = build_stmt (c->try_locus, TRY_FINALLY_EXPR, stmt, c->finally_body);
2268   return stmt;
2269 }
2270 
2271 #include "gt-objc-objc-gnu-runtime-abi-01.h"
2272