OSDN Git Service

* godump.c (go_format_type): Use exported Go name for anonymous
[pf3gnuchains/gcc-fork.git] / gcc / objc / objc-runtime-shared-support.c
1 /* Support routines shared by all runtimes.
2    Copyright (C) 2011 Free Software Foundation, Inc.
3    Contributed by Iain Sandoe (partially 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 "tm.h"
25 #include "tree.h"
26
27 #ifdef OBJCPLUS
28 #include "cp-tree.h"
29 #else
30 #include "c-tree.h"
31 #include "c-lang.h"
32 #endif
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 "obstack.h"
45
46 /* These are only used for encoding ivars.  */
47 extern struct obstack util_obstack;
48 extern char *util_firstobj;
49
50 /* Hooks for string decls etc.  */
51 #include "objc-runtime-hooks.h"
52
53 #include "objc-runtime-shared-support.h"
54
55 /* rt_trees identifiers - shared between NeXT implementations.  These allow
56    the FE to tag meta-data in a manner that survives LTO and can be used when
57    the  runtime requires that certain meta-data items appear in particular
58    named sections.  */
59 #include "objc-next-metadata-tags.h"
60 extern GTY(()) tree objc_rt_trees[OCTI_RT_META_MAX];
61
62 /* Rather than repeatedly looking up the identifiers, we save them here.  */
63 tree objc_rt_trees[OCTI_RT_META_MAX];
64
65 /* For building an objc struct.  These might not be used when this file
66    is compiled as part of obj-c++.  */
67
68 static bool objc_building_struct;
69 static struct c_struct_parse_info *objc_struct_info ATTRIBUTE_UNUSED;
70
71 /* Start building a struct for objc.  */
72
73 tree
74 objc_start_struct (tree name)
75 {
76   gcc_assert (!objc_building_struct);
77   objc_building_struct = true;
78   return start_struct (input_location, RECORD_TYPE, name, &objc_struct_info);
79 }
80
81 /* Finish building a struct for objc.  */
82
83 tree
84 objc_finish_struct (tree type, tree fieldlist)
85 {
86   gcc_assert (objc_building_struct);
87   objc_building_struct = false;
88   return finish_struct (input_location, type, fieldlist, NULL_TREE,
89                         objc_struct_info);
90 }
91
92 tree
93 build_sized_array_type (tree base_type, int size)
94 {
95   tree index_type = build_index_type (build_int_cst (NULL_TREE, size - 1));
96   return build_array_type (base_type, index_type);
97 }
98
99 /* Create a declaration for field NAME of a given TYPE.  */
100
101 static tree
102 create_field_decl (tree type, const char *name)
103 {
104   return build_decl (input_location,
105                      FIELD_DECL, get_identifier (name), type);
106 }
107
108 tree
109 add_field_decl (tree type, const char *name, tree **chain)
110 {
111   tree field = create_field_decl (type, name);
112
113   if (*chain != NULL)
114     **chain = field;
115   *chain = &DECL_CHAIN (field);
116
117   return field;
118 }
119
120 /* Create a global, static declaration for variable NAME of a given TYPE.  The
121    finish_var_decl() routine will need to be called on it afterwards.  */
122
123 tree
124 start_var_decl (tree type, const char *name)
125 {
126   tree var = build_decl (input_location,
127                          VAR_DECL, get_identifier (name), type);
128   TREE_STATIC (var) = 1;
129   DECL_INITIAL (var) = error_mark_node;  /* A real initializer is coming... */
130   DECL_IGNORED_P (var) = 1;
131   DECL_ARTIFICIAL (var) = 1;
132   DECL_CONTEXT (var) = NULL_TREE;
133 #ifdef OBJCPLUS
134   DECL_THIS_STATIC (var) = 1; /* squash redeclaration errors */
135 #endif
136   return var;
137 }
138
139 /* Finish off the variable declaration created by start_var_decl().  */
140
141 void
142 finish_var_decl (tree var, tree initializer)
143 {
144   finish_decl (var, input_location, initializer, NULL_TREE, NULL_TREE);
145 }
146
147 /* Just a handy wrapper for add_objc_string.  */
148
149 tree
150 build_selector (tree ident)
151 {
152   return convert (objc_selector_type, add_objc_string (ident, meth_var_names));
153 }
154
155 /* --- templates --- */
156
157 /* Set 'objc_super_template' to the data type node for 'struct _objc_super'.
158    This needs to be done just once per compilation.  */
159
160 /* struct _objc_super {
161      struct _objc_object *self;
162      struct _objc_class *super_class; 
163                 [or Class cls; for the abi v2]
164    };  */
165
166 void
167 build_super_template (void)
168 {
169   tree decls, *chain = NULL;
170
171   objc_super_template = objc_start_struct (get_identifier (UTAG_SUPER));
172
173   /* struct _objc_object *self; */
174   decls = add_field_decl (objc_object_type, "self", &chain);
175
176   /* struct _objc_class *super_class; */
177   add_field_decl (build_pointer_type (objc_class_template),
178                   "super_class", &chain);
179
180   objc_finish_struct (objc_super_template, decls);
181 }
182
183 /* To accomplish method prototyping without generating all kinds of
184    inane warnings, the definition of the dispatch table entries were
185    changed from:
186
187         struct objc_method { SEL _cmd; ...; id (*_imp)(); };
188    to:
189         struct objc_method { SEL _cmd; ...; void *_imp; };  */
190
191 tree
192 build_method_template (void)
193 {
194   tree _SLT_record;
195   tree decls, *chain = NULL;
196
197   _SLT_record = objc_start_struct (get_identifier (UTAG_METHOD));
198
199   /* SEL _cmd; */
200   decls = add_field_decl (objc_selector_type, "_cmd", &chain);
201
202   /* char *method_types; */
203   add_field_decl (string_type_node, "method_types", &chain);
204
205   /* void *_imp; */
206   add_field_decl (build_pointer_type (void_type_node), "_imp", &chain);
207
208   objc_finish_struct (_SLT_record, decls);
209
210   return _SLT_record;
211 }
212
213 tree
214 build_method_prototype_template (void)
215 {
216   tree proto_record;
217   tree decls, *chain = NULL;
218
219   proto_record = objc_start_struct (get_identifier (UTAG_METHOD_PROTOTYPE));
220
221   /* SEL _cmd; */
222   decls = add_field_decl (objc_selector_type, "_cmd", &chain);
223
224   /* char *method_types; */
225   add_field_decl (string_type_node, "method_types", &chain);
226
227   objc_finish_struct (proto_record, decls);
228
229   return proto_record;
230 }
231
232 /* struct {
233      struct _objc__method_prototype_list *method_next;
234      int method_count;
235      struct objc_method method_list[method_count];
236    };  */
237
238 tree
239 build_method_list_template (tree list_type, int size)
240 {
241   tree objc_ivar_list_record;
242   tree array_type, decls, *chain = NULL;
243
244   objc_ivar_list_record = objc_start_struct (NULL_TREE);
245
246   /* struct _objc__method_prototype_list *method_next; */
247   decls = add_field_decl (objc_method_proto_list_ptr, "method_next", &chain);
248
249   /* int method_count; */
250   add_field_decl (integer_type_node, "method_count", &chain);
251
252   /* struct objc_method method_list[]; */
253   array_type = build_sized_array_type (list_type, size);
254   add_field_decl (array_type, "method_list", &chain);
255
256   objc_finish_struct (objc_ivar_list_record, decls);
257
258   return objc_ivar_list_record;
259 }
260
261 /* struct objc_method_prototype_list {
262      int count;
263      struct objc_method_prototype {
264         SEL name;
265         char *types;
266      } list[1];
267    };  */
268
269 tree
270 build_method_prototype_list_template (tree list_type, int size)
271 {
272   tree objc_ivar_list_record;
273   tree array_type, decls, *chain = NULL;
274
275   /* Generate an unnamed struct definition.  */
276
277   objc_ivar_list_record = objc_start_struct (NULL_TREE);
278
279   /* int method_count; */
280   decls = add_field_decl (integer_type_node, "method_count", &chain);
281
282   /* struct objc_method method_list[]; */
283   array_type = build_sized_array_type (list_type, size);
284   add_field_decl (array_type, "method_list", &chain);
285
286   objc_finish_struct (objc_ivar_list_record, decls);
287
288   return objc_ivar_list_record;
289 }
290
291 /* --- names, decls entry --- */
292
293 /* For each string section we have a chain which maps identifier nodes
294    to decls for the strings.  */
295
296 static GTY(()) int meth_var_names_idx;
297 static GTY(()) int meth_var_types_idx;
298 static GTY(()) int property_name_attr_idx;
299
300 tree
301 add_objc_string (tree ident, string_section section)
302 {
303   tree *chain, decl, type;
304   char buf[BUFSIZE];
305   
306   switch (section)
307     {
308     case class_names:
309       chain = &class_names_chain;
310       snprintf (buf, BUFSIZE, "_OBJC_ClassName_%s", IDENTIFIER_POINTER (ident));
311       break;
312     case meth_var_names:
313       chain = &meth_var_names_chain;
314       snprintf (buf, BUFSIZE, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++);
315       break;
316     case meth_var_types:
317       chain = &meth_var_types_chain;
318       snprintf (buf, BUFSIZE, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++);
319       break;
320     case prop_names_attr:
321       chain = &prop_names_attr_chain;
322       snprintf (buf, BUFSIZE, "_OBJC_PropertyAttributeOrName_%d", property_name_attr_idx++);
323       break;
324     default:
325       gcc_unreachable ();
326     }
327
328   while (*chain)
329     {
330       if (TREE_VALUE (*chain) == ident)
331         return convert (string_type_node,
332                         build_unary_op (input_location,
333                                         ADDR_EXPR, TREE_PURPOSE (*chain), 1));
334
335       chain = &TREE_CHAIN (*chain);
336     }
337
338   type = build_sized_array_type (char_type_node, IDENTIFIER_LENGTH (ident) + 1);
339   /* Get a runtime-specific string decl which will be finish_var()'ed in 
340      generate_strings ().  */
341   decl = (*runtime.string_decl) (type, buf, section);
342   TREE_CONSTANT (decl) = 1;
343   *chain = tree_cons (decl, ident, NULL_TREE);
344
345   return convert (string_type_node, 
346                   build_unary_op (input_location, ADDR_EXPR, decl, 1));
347 }
348
349 /* --- shared metadata routines --- */
350
351 tree
352 build_descriptor_table_initializer (tree type, tree entries)
353 {
354   VEC(constructor_elt,gc) *inits = NULL;
355
356   do
357     {
358       VEC(constructor_elt,gc) *elts = NULL;
359
360       CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
361                               build_selector (METHOD_SEL_NAME (entries)));
362       CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE,
363                               add_objc_string (METHOD_ENCODING (entries),
364                                                meth_var_types));
365
366       CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
367                               objc_build_constructor (type, elts));
368
369       entries = DECL_CHAIN (entries);
370     }
371   while (entries);
372
373   return objc_build_constructor (build_array_type (type, 0), inits);
374 }
375
376 tree
377 build_dispatch_table_initializer (tree type, tree entries)
378 {
379   VEC(constructor_elt,gc) *inits = NULL;
380
381   do
382     {
383       VEC(constructor_elt,gc) *elems = NULL;
384       tree expr;
385
386       CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE,
387                               build_selector (METHOD_SEL_NAME (entries)));
388
389       /* Generate the method encoding if we don't have one already.  */
390       if (! METHOD_ENCODING (entries))
391         METHOD_ENCODING (entries) =
392           encode_method_prototype (entries);
393
394       CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE,
395                               add_objc_string (METHOD_ENCODING (entries),
396                                                meth_var_types));
397
398       expr = convert (ptr_type_node,
399                       build_unary_op (input_location, ADDR_EXPR,
400                                       METHOD_DEFINITION (entries), 1));
401       CONSTRUCTOR_APPEND_ELT (elems, NULL_TREE, expr);
402
403       CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
404                               objc_build_constructor (type, elems));
405
406       entries = DECL_CHAIN (entries);
407     }
408   while (entries);
409
410   return objc_build_constructor (build_array_type (type, 0), inits);
411 }
412
413 /* Used only by build_*_selector_translation_table (). */
414 void
415 diagnose_missing_method (tree meth, location_t here)
416 {
417   tree method_chain;
418   bool found = false;
419   for (method_chain = meth_var_names_chain;
420        method_chain;
421        method_chain = TREE_CHAIN (method_chain))
422     {
423       if (TREE_VALUE (method_chain) == meth)
424         {
425           found = true;
426           break;
427         }
428      }
429
430   if (!found)
431     warning_at (here, 0, "creating selector for nonexistent method %qE",
432                         meth);
433 }
434
435
436 static tree
437 init_module_descriptor (tree type, long vers)
438 {
439   tree expr, ltyp;
440   location_t loc;
441   VEC(constructor_elt,gc) *v = NULL;
442
443   /* No really useful place to point to.  */
444   loc = UNKNOWN_LOCATION;
445   
446   /* version = { 1, ... } */
447
448   expr = build_int_cst (long_integer_type_node, vers);
449   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
450
451   /* size = { ..., sizeof (struct _objc_module), ... } */
452
453   expr = convert (long_integer_type_node,
454                   size_in_bytes (objc_module_template));
455   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
456
457   /* Don't provide any file name for security reasons. */
458   /* name = { ..., "", ... } */
459
460   expr = add_objc_string (get_identifier (""), class_names);
461   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
462
463   /* symtab = { ..., _OBJC_SYMBOLS, ... } */
464
465   ltyp = build_pointer_type (xref_tag (RECORD_TYPE,
466                                        get_identifier (UTAG_SYMTAB)));  
467   if (UOBJC_SYMBOLS_decl)
468     expr = convert (ltyp, build_unary_op (loc,
469                            ADDR_EXPR, UOBJC_SYMBOLS_decl, 0));
470   else
471     expr = convert (ltyp, null_pointer_node);
472   CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, expr);
473
474   return objc_build_constructor (type, v);
475 }
476
477 /* Write out the data structures to describe Objective C classes defined.
478
479    struct _objc_module { ... } _OBJC_MODULE = { ... };   */
480
481 void
482 build_module_descriptor (long vers, tree attr)
483 {
484   tree decls, *chain = NULL;
485
486 #ifdef OBJCPLUS
487   push_lang_context (lang_name_c); /* extern "C" */
488 #endif
489
490   objc_module_template = objc_start_struct (get_identifier (UTAG_MODULE));
491
492   /* long version; */
493   decls = add_field_decl (long_integer_type_node, "version", &chain);
494
495   /* long size; */
496   add_field_decl (long_integer_type_node, "size", &chain);
497
498   /* char *name; */
499   add_field_decl (string_type_node, "name", &chain);
500
501   /* struct _objc_symtab *symtab; */
502   add_field_decl (build_pointer_type (xref_tag (RECORD_TYPE,
503                                                 get_identifier (UTAG_SYMTAB))),
504                   "symtab", &chain);
505
506   objc_finish_struct (objc_module_template, decls);
507
508   /* Create an instance of "_objc_module".  */
509   UOBJC_MODULES_decl = start_var_decl (objc_module_template,
510                                        /* FIXME - why the conditional
511                                           if the symbol is the
512                                           same.  */
513                                        flag_next_runtime ? "_OBJC_Module" :  "_OBJC_Module");
514
515   /* This is the root of the metadata for defined classes and categories, it
516      is referenced by the runtime and, therefore, needed.  */
517   DECL_PRESERVE_P (UOBJC_MODULES_decl) = 1;
518
519   /* Allow the runtime to mark meta-data such that it can be assigned to target
520      specific sections by the back-end.  */
521   if (attr)
522     DECL_ATTRIBUTES (UOBJC_MODULES_decl) = attr; 
523
524   finish_var_decl (UOBJC_MODULES_decl,
525                    init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl),
526                                            vers));
527
528 #ifdef OBJCPLUS
529   pop_lang_context ();
530 #endif
531 }
532
533 tree
534 build_ivar_list_initializer (tree type, tree field_decl)
535 {
536   VEC(constructor_elt,gc) *inits = NULL;
537
538   do
539     {
540       VEC(constructor_elt,gc) *ivar = NULL;
541       tree id;
542
543       /* Set name.  */
544       if (DECL_NAME (field_decl))
545         CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE,
546                                 add_objc_string (DECL_NAME (field_decl),
547                                                  meth_var_names));
548       else
549         /* Unnamed bit-field ivar (yuck).  */
550         CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, build_int_cst (NULL_TREE, 0));
551
552       /* Set type.  */
553       encode_field_decl (field_decl,
554                          obstack_object_size (&util_obstack),
555                          OBJC_ENCODE_DONT_INLINE_DEFS);
556
557       /* Null terminate string.  */
558       obstack_1grow (&util_obstack, 0);
559       id = add_objc_string (get_identifier (XOBFINISH (&util_obstack, char *)),
560                             meth_var_types);
561       CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, id);
562       obstack_free (&util_obstack, util_firstobj);
563
564       /* Set offset.  */
565       CONSTRUCTOR_APPEND_ELT (ivar, NULL_TREE, byte_position (field_decl));
566       CONSTRUCTOR_APPEND_ELT (inits, NULL_TREE,
567                               objc_build_constructor (type, ivar));
568       do
569         field_decl = DECL_CHAIN (field_decl);
570       while (field_decl && TREE_CODE (field_decl) != FIELD_DECL);
571     }
572   while (field_decl);
573
574   return objc_build_constructor (build_array_type (type, 0), inits);
575 }
576
577 /* struct {
578      int ivar_count;
579      struct objc_ivar ivar_list[ivar_count];
580    };  */
581
582 tree
583 build_ivar_list_template (tree list_type, int size)
584 {
585   tree objc_ivar_list_record;
586   tree array_type, decls, *chain = NULL;
587
588   objc_ivar_list_record = objc_start_struct (NULL_TREE);
589
590   /* int ivar_count; */
591   decls = add_field_decl (integer_type_node, "ivar_count", &chain);
592
593   /* struct objc_ivar ivar_list[]; */
594   array_type = build_sized_array_type (list_type, size);
595   add_field_decl (array_type, "ivar_list", &chain);
596
597   objc_finish_struct (objc_ivar_list_record, decls);
598
599   return objc_ivar_list_record;
600 }
601
602 /* struct _objc_ivar {
603      char *ivar_name;
604      char *ivar_type;
605      int ivar_offset;
606    };  */
607
608 tree
609 build_ivar_template (void)
610 {
611   tree objc_ivar_id, objc_ivar_record;
612   tree decls, *chain = NULL;
613
614   objc_ivar_id = get_identifier (UTAG_IVAR);
615   objc_ivar_record = objc_start_struct (objc_ivar_id);
616
617   /* char *ivar_name; */
618   decls = add_field_decl (string_type_node, "ivar_name", &chain);
619
620   /* char *ivar_type; */
621   add_field_decl (string_type_node, "ivar_type", &chain);
622
623   /* int ivar_offset; */
624   add_field_decl (integer_type_node, "ivar_offset", &chain);
625
626   objc_finish_struct (objc_ivar_record, decls);
627
628   return objc_ivar_record;
629 }
630
631 /* Used by NeXT ABI=0..2 */
632 void
633 build_next_selector_translation_table (void)
634 {
635   tree chain;
636   for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain))
637     {
638       tree expr;
639       tree decl = TREE_PURPOSE (chain);
640       if (warn_selector)
641         {
642           location_t loc;
643           if (decl) 
644             loc = DECL_SOURCE_LOCATION (decl);
645           else
646             loc = UNKNOWN_LOCATION;
647           diagnose_missing_method (TREE_VALUE (chain), loc);
648         }
649
650       expr = build_selector (TREE_VALUE (chain));
651
652       if (decl)
653         {
654           /* Entries of this form are used for references to methods.
655           The runtime re-writes these on start-up, but the compiler can't see 
656           that and optimizes it away unless we force it.  */
657           DECL_PRESERVE_P (decl) = 1;
658           finish_var_decl (decl, expr);
659         }
660     }
661 }
662
663 void
664 generate_protocol_references (tree plist)
665 {
666   tree lproto;
667
668   /* Forward declare protocols referenced.  */
669   for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
670     {
671       tree proto = TREE_VALUE (lproto);
672
673       if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
674           && PROTOCOL_NAME (proto))
675         {
676           if (! PROTOCOL_FORWARD_DECL (proto))
677             PROTOCOL_FORWARD_DECL (proto) = (*runtime.protocol_decl) (proto);
678
679           if (PROTOCOL_LIST (proto))
680             generate_protocol_references (PROTOCOL_LIST (proto));
681         }
682     }
683 }
684
685 /* --- new routines --- */
686
687 /* Output all strings.  */
688
689 /* FIXME: don't use global vars for all this... */
690
691 /* This emits all the meta-data string tables (and finalizes each var
692    as it goes).  */
693 void
694 generate_strings (void)
695 {
696   tree chain, string_expr;
697   tree string, decl; /* , type;*/
698
699   for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain))
700     {
701       string = TREE_VALUE (chain);
702       decl = TREE_PURPOSE (chain);
703       string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
704                                      IDENTIFIER_POINTER (string));
705       finish_var_decl (decl, string_expr);
706     }
707
708   for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain))
709     {
710       string = TREE_VALUE (chain);
711       decl = TREE_PURPOSE (chain);
712       string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
713                                      IDENTIFIER_POINTER (string));
714       finish_var_decl (decl, string_expr);
715     }
716
717   for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain))
718     {
719       string = TREE_VALUE (chain);
720       decl = TREE_PURPOSE (chain);
721       string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
722                                      IDENTIFIER_POINTER (string));
723       finish_var_decl (decl, string_expr);
724     }
725
726   for (chain = prop_names_attr_chain; chain; chain = TREE_CHAIN (chain))
727     {
728       string = TREE_VALUE (chain);
729       decl = TREE_PURPOSE (chain);
730       string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1,
731                                      IDENTIFIER_POINTER (string));
732       finish_var_decl (decl, string_expr);
733     }
734 }
735
736 #include "gt-objc-objc-runtime-shared-support.h"