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