source: branches/ffigen-apple-gcc-6465/ffigen4/source/ffi.c@ 65

Last change on this file since 65 was 55, checked in by gb, 16 years ago

New.

File size: 31.2 KB
Line 
1/* ffi.c - generate .ffi file from .h file
2 Copyright (C) 2001, 2005-2007 Clozure Associates.
3 Copyright (C) 2004, Helmut Eller
4
5This file is part of GNU CC (or, more accurately, part of a work
6derived from GNU CC.)
7
8GNU CC is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2, or (at your option)
11any later version.
12
13GNU CC is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with GNU CC; see the file COPYING. If not, write to
20the Free Software Foundation, 59 Temple Place - Suite 330,
21Boston, MA 02111-1307, USA. */
22
23#include "config.h"
24#include "system.h"
25#include "coretypes.h"
26#include "tm.h"
27#include "tree.h"
28#include "c-tree.h"
29#include "c-common.h"
30#include "ggc.h"
31#include "flags.h"
32#include "debug.h"
33#include "diagnostic.h" /* for errorcount */
34#include "objc/objc-act.h"
35#include "ffi-version.h"
36
37/* Prototypes */
38
39void ffi_rest_of_decl_compilation (tree, int, int);
40void ffi_rest_of_type_compilation (tree, int);
41void ffi_early_init (void);
42void ffi_init (FILE *_file, char *);
43void ffi_rest_of_objc_class_compilation (tree);
44void ffi_rest_of_objc_category_compilation (tree);
45void print_ffi_version(FILE *, char *);
46
47void
48print_ffi_version(FILE *out, char *indent)
49{
50 fprintf (out, "%s%sFFIGEN version %s\n", indent, *indent != 0 ? " " : "", ffi_version);
51}
52
53FILE *ffifile;
54
55int ffi_initialized = 0;
56
57struct ffi_input_file {
58 char *pathname;
59 struct ffi_input_file *prev;
60};
61
62struct ffi_input_file *current_ffi_input_file = NULL;
63char *ffi_current_source_file;
64char *ffi_primary_source_file;
65
66static int ffi_indent_count = 1;
67
68static void
69ffi_debug_start_source_file (unsigned int line ATTRIBUTE_UNUSED,
70 const char *file)
71{
72 struct ffi_input_file *savef = xmalloc (sizeof *savef);
73 ffi_indent_count = 1;
74 savef->pathname = ffi_current_source_file;
75 savef->prev = current_ffi_input_file;
76 current_ffi_input_file = savef;
77 ffi_current_source_file = (char *) xstrdup (file);
78}
79
80static void
81ffi_debug_end_source_file (unsigned lineno ATTRIBUTE_UNUSED)
82{
83 struct ffi_input_file *currf = current_ffi_input_file;
84 current_ffi_input_file = currf->prev;
85 free (ffi_current_source_file);
86 ffi_current_source_file = currf->pathname;
87 free (currf);
88}
89
90static void
91ffi_indent (void)
92{
93 int i;
94
95 fprintf (ffifile, "\n");
96
97 for (i = 0; i < ffi_indent_count; i++) {
98 fprintf (ffifile, " ");
99 }
100 ffi_indent_count++;
101}
102
103static void
104ffi_unindent (int n)
105{
106 ffi_indent_count -= n;
107}
108
109enum ffi_typestatus {FFI_TYPE_UNDEFINED = 0,
110 FFI_TYPE_PRIMITIVE,
111 FFI_TYPE_TYPEDEF,
112 FFI_TYPE_STRUCT,
113 FFI_TYPE_UNION,
114 FFI_TYPE_ENUM,
115 FFI_TYPE_POINTER,
116 FFI_TYPE_FUNCTION,
117 FFI_TYPE_ARRAY,
118 FFI_TYPE_FIELD};
119
120static void ffi_define_type (tree decl, enum ffi_typestatus status);
121
122
123struct ffi_typeinfo {
124 enum ffi_typestatus status;
125 int type_number;
126 tree type;
127 const char *name;
128 char *source_file;
129 unsigned source_line;
130 int ref_type_number; /* For pointer & array types, at least */
131 int array_size;
132 int first_field;
133};
134
135struct ffi_typeinfo *ffi_typevec;
136
137int ffi_typevec_len = 0;
138int next_ffi_type_number = 1;
139
140typedef struct {
141 const char *gcc_name;
142 const char *ffi_name;
143} ffi_primitive_name_map;
144
145static ffi_primitive_name_map ffi_primitive_names[] =
146{
147 {"int", "int"},
148 {"char", "char"},
149 {"float", "float"},
150 {"double", "double"},
151 {"long double", "long-double"},
152 {"void", "void"},
153 {"long int", "long"},
154 {"unsigned int", "unsigned"},
155 {"long unsigned int", "unsigned-long"},
156 {"long long int", "long-long"},
157 {"long long unsigned int", "unsigned-long-long"},
158 {"short int", "short"},
159 {"short unsigned int", "unsigned-short"},
160 {"signed char", "signed-char"},
161 {"unsigned char", "unsigned-char"},
162 {"complex int", "complex-int"},
163 {"complex float", "complex-float"},
164 {"complex double", "complex-double"},
165 {"complex long double", "complex-long-double"},
166 {"__vector unsigned char", "__vector-unsigned-char"},
167 {"__vector signed char", "__vector-signed-char"},
168 {"__vector bool char", "__vector-bool-char"},
169 {"__vector unsigned short", "__vector-unsigned-short"},
170 {"__vector signed short", "__vector-signed-short"},
171 {"__vector bool short", "__vector-bool-short"},
172 {"__vector unsigned long", "__vector-unsigned-long"},
173 {"__vector signed long", "__vector-signed-long"},
174 {"__vector bool long", "__vector-bool-long"},
175 {"__vector float", "__vector-short-float"},
176 {"__vector pixel", "__vector-pixel"},
177 {"__vector", "__vector"},
178 {"_Bool", "unsigned"},
179 {"__int128_t", "long-long-long"},
180 {"__uint128_t", "unsigned-long-long-long"},
181 {NULL, NULL}
182};
183
184/* Return the Lisp'y name for the type GCC_NAME */
185static char *
186to_primitive_type_name (char* gcc_name)
187{
188 ffi_primitive_name_map *map = ffi_primitive_names;
189 for (; map->gcc_name; ++map)
190 if (!strcmp (map->gcc_name, gcc_name))
191 return (char*)map->ffi_name;
192 fprintf (stderr, "Bug: couldn't find primitive name for %s\n", gcc_name);
193 abort ();
194}
195
196static char *
197ffi_primitive_type_name (tree decl)
198{
199 char *gcc_name = (char*)IDENTIFIER_POINTER (DECL_NAME (decl));
200 return to_primitive_type_name (gcc_name);
201}
202
203static struct ffi_typeinfo *
204find_ffi_type_info (tree type)
205{
206 int index = TYPE_SYMTAB_ADDRESS (type);
207 struct ffi_typeinfo * info;
208
209 if (index == 0)
210 {
211 index = next_ffi_type_number++;
212 TYPE_SYMTAB_ADDRESS (type) = index;
213
214 if (next_ffi_type_number == ffi_typevec_len)
215 {
216 ffi_typevec
217 = (struct ffi_typeinfo *) xrealloc (ffi_typevec,
218 ffi_typevec_len * 2 *
219 sizeof ffi_typevec[0]);
220 memset ((char *) (ffi_typevec + ffi_typevec_len), 0,
221 ffi_typevec_len * sizeof ffi_typevec[0]);
222 ffi_typevec_len *= 2;
223 }
224 }
225
226 info = ffi_typevec + index;
227 info->type_number = index;
228 info->type = type;
229 return info;
230}
231
232
233/*
234 'type' may be an unnamed scalar type. Why does it even exist ?
235*/
236static struct ffi_typeinfo *
237ffi_maybe_synthesize_integer_type (tree type, struct ffi_typeinfo *info)
238{
239 if (TREE_CODE (type) == INTEGER_TYPE)
240 {
241
242 int is_unsigned = TYPE_UNSIGNED (type);
243 HOST_WIDE_INT nbytes = int_size_in_bytes (type);
244
245 switch (nbytes)
246 {
247 case 1:
248 info->name = is_unsigned ? "unsigned-char" : "signed-char";
249 info->status = FFI_TYPE_PRIMITIVE;
250 break;
251 case 2:
252 info->name = is_unsigned ? "unsigned-short" : "short";
253 info->status = FFI_TYPE_PRIMITIVE;
254 break;
255 case 4:
256 info->name = is_unsigned ? "unsigned" : "int";
257 info->status = FFI_TYPE_PRIMITIVE;
258 break;
259 case 8:
260 info->name = is_unsigned ? "unsigned-long-long" : "long-long";
261 info->status = FFI_TYPE_PRIMITIVE;
262 break;
263 case 16:
264 info->name = is_unsigned ? "unsigned-long-long-long" : "long-long-long";
265 info->status = FFI_TYPE_PRIMITIVE;
266 break;
267 }
268 }
269 return info;
270}
271
272static struct ffi_typeinfo *
273ffi_maybe_synthesize_vector_type (tree type, struct ffi_typeinfo *info)
274{
275 if (TREE_CODE (type) == VECTOR_TYPE)
276 {
277
278 HOST_WIDE_INT nbytes = int_size_in_bytes (type);
279
280 switch (nbytes)
281 {
282 case 16:
283 info->name = "vec128";
284 info->status = FFI_TYPE_PRIMITIVE;
285 break;
286 case 8:
287 info->name = "vec64";
288 info->status = FFI_TYPE_PRIMITIVE;
289 break;
290 default:
291 break;
292 }
293 }
294 return info;
295}
296
297
298
299static struct ffi_typeinfo *
300ffi_create_type_info (tree type)
301{
302 struct ffi_typeinfo *info;
303 tree lookup_type = type;
304
305 if (TYPE_READONLY (type) || TYPE_VOLATILE (type))
306 lookup_type = TYPE_MAIN_VARIANT (type);
307
308 info = find_ffi_type_info (lookup_type);
309
310 if (info->status != FFI_TYPE_UNDEFINED)
311 return info;
312
313 switch (TREE_CODE (type))
314 {
315
316 case POINTER_TYPE:
317 case REFERENCE_TYPE:
318 {
319 tree pointer_target_type = TREE_TYPE (type);
320 struct ffi_typeinfo *pointer_type_info;
321
322 info->status = FFI_TYPE_POINTER;
323 pointer_type_info = ffi_create_type_info (pointer_target_type);
324
325 /* 'info' might have moved */
326 info = find_ffi_type_info (type);
327 info->ref_type_number = pointer_type_info->type_number;
328 }
329 break;
330
331 case FUNCTION_TYPE:
332 {
333 tree arg_type;
334 info->status = FFI_TYPE_FUNCTION;
335 ffi_create_type_info (TREE_TYPE (type));
336 for (arg_type = TYPE_ARG_TYPES (type); arg_type; arg_type = TREE_CHAIN (arg_type))
337 {
338 ffi_create_type_info (TREE_VALUE (arg_type));
339 }
340 info = find_ffi_type_info (type);
341 }
342 break;
343
344 case ARRAY_TYPE:
345 {
346 tree array_element_type = TREE_TYPE (type);
347 struct ffi_typeinfo *element_type_info;
348 int array_size_in_bits = 0, element_size_in_bits, array_size_in_elements;
349
350 info->status = FFI_TYPE_ARRAY;
351 element_type_info = ffi_create_type_info (array_element_type);
352 info = find_ffi_type_info (type);
353 info->ref_type_number = element_type_info->type_number;
354 element_size_in_bits = TREE_INT_CST_LOW ( TYPE_SIZE (array_element_type));
355 if (TYPE_SIZE (type))
356 array_size_in_bits = TREE_INT_CST_LOW ( TYPE_SIZE (type));
357 array_size_in_elements = array_size_in_bits / element_size_in_bits;
358 if (array_size_in_bits % element_size_in_bits)
359 {
360 fprintf (stderr, "screw : array size not integral\n");
361 abort ();
362 }
363 info->array_size = array_size_in_elements;
364 }
365 break;
366
367 case RECORD_TYPE:
368 case UNION_TYPE:
369 case ENUMERAL_TYPE:
370 {
371 tree field;
372 tree name = TYPE_NAME (type);
373 if (name)
374 {
375 if (TREE_CODE (name) == IDENTIFIER_NODE)
376 info->name = (char *) xstrdup (IDENTIFIER_POINTER (name));
377 else if (TREE_CODE (name) == TYPE_DECL
378 && DECL_NAME (name))
379 info->name = (char *) xstrdup (IDENTIFIER_POINTER (DECL_NAME (name)));
380 }
381 if (! info->name)
382 {
383 char buf[2048];
384 sprintf(buf, "%d_%s", info->type_number, ffi_primary_source_file);
385 info->name = (char *) xstrdup (buf);
386 }
387 if (TREE_CODE (type) == ENUMERAL_TYPE)
388 {
389 info->status = FFI_TYPE_ENUM;
390 break;
391 }
392
393 info->status = (TREE_CODE (type) == RECORD_TYPE) ? FFI_TYPE_STRUCT : FFI_TYPE_UNION;
394
395 for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
396 {
397 ffi_create_type_info (TREE_TYPE (field));
398 }
399 info = find_ffi_type_info (type);
400 }
401 break;
402 case VOID_TYPE:
403 ffi_define_type (TYPE_NAME (type), FFI_TYPE_PRIMITIVE);
404 info = ffi_create_type_info (type);
405 break;
406 case INTEGER_TYPE:
407 case VECTOR_TYPE:
408 if (TREE_CODE (type) == INTEGER_TYPE)
409 info = ffi_maybe_synthesize_integer_type (type, info);
410 else
411 info = ffi_maybe_synthesize_vector_type (type, info);
412 if (info->status != FFI_TYPE_UNDEFINED)
413 return info;
414 /* else fall through */
415 default:
416 fprintf (stderr, "Need to create info for type:\n");
417 debug_tree (type);
418 abort ();
419 }
420 return info;
421}
422
423static void
424emit_ffi_type_reference (tree target_type)
425{
426 struct ffi_typeinfo *info;
427 tree lookup_type = target_type;
428
429 if (TYPE_READONLY (target_type) || TYPE_VOLATILE (target_type))
430 lookup_type = TYPE_MAIN_VARIANT (target_type);
431
432 info = ffi_create_type_info (lookup_type);
433
434 switch (info->status)
435 {
436 case FFI_TYPE_PRIMITIVE:
437 fprintf (ffifile, "(%s ())", info->name); /* No quotes around primitive name. */
438 return;
439
440 case FFI_TYPE_TYPEDEF:
441 fprintf (ffifile, "(typedef \"%s\")", info->name);
442 return;
443
444 case FFI_TYPE_FUNCTION:
445 {
446 tree arg, arg_type;
447 /* struct ffi_typeinfo *arg_type_info; */
448 /*
449 It seems like functions that take a fixed number of arguments
450 have a "void" argument after the fixed arguments, while those
451 that take an indefinite number don't.
452 That's perfectly sane, but the opposite of what LCC does.
453 So, if there's a "void" argument at the end of the arglist,
454 don't emit it; if there wasn't, emit one.
455 Sheesh.
456 */
457 int had_void_arg = 0, args_emitted = 0;
458 fprintf (ffifile, "(function");
459 ffi_indent ();
460 fprintf (ffifile, "(");
461 for (arg = TYPE_ARG_TYPES (target_type); arg ; arg = TREE_CHAIN (arg))
462 {
463 if (args_emitted)
464 fprintf (ffifile, " ");
465 arg_type = TREE_VALUE (arg);
466 if (TREE_CODE (arg_type) != VOID_TYPE) {
467 emit_ffi_type_reference (arg_type);
468 args_emitted = 1;
469 }
470 else
471 {
472 had_void_arg = 1;
473 break;
474 }
475 }
476 if (! had_void_arg) {
477 if (args_emitted)
478 fprintf (ffifile, " ");
479 fprintf (ffifile, "(void ())");
480 }
481 fprintf (ffifile, ")");
482 ffi_unindent (1);
483 ffi_indent ();
484 arg_type = TREE_TYPE (target_type);
485 emit_ffi_type_reference (arg_type);
486 ffi_unindent (1);
487 fprintf (ffifile, ")");
488 }
489 break;
490
491 case FFI_TYPE_POINTER:
492 {
493 tree pointer_target = TREE_TYPE (target_type);
494
495 fprintf (ffifile, "(pointer ");
496 emit_ffi_type_reference (pointer_target);
497 fprintf (ffifile, ")");
498 return;
499 }
500
501 case FFI_TYPE_STRUCT:
502 fprintf (ffifile, "(struct-ref \"%s\")", info->name);
503 break;
504
505 case FFI_TYPE_UNION:
506 fprintf (ffifile, "(union-ref \"%s\")", info->name);
507 break;
508
509 case FFI_TYPE_ENUM:
510 fprintf (ffifile, "(enum-ref \"%s\")", info->name);
511 break;
512
513 case FFI_TYPE_ARRAY:
514 {
515 tree element_type = TREE_TYPE (target_type);
516
517 fprintf (ffifile, "(array %d ", info->array_size);
518 emit_ffi_type_reference (element_type);
519 fprintf (ffifile, ")");
520 }
521 break;
522
523 default:
524 fprintf (stderr, "need to emit reference to this type\n");
525 debug_tree (target_type);
526 abort ();
527 }
528}
529
530static void
531ffi_emit_type_decl (struct ffi_typeinfo *info, tree decl)
532{
533 /* struct ffi_typeinfo *target_info; */
534 tree target;
535
536 if (TREE_ASM_WRITTEN (decl))
537 return;
538
539 TREE_ASM_WRITTEN (decl) = 1;
540 fprintf (ffifile, "(type (\"%s\" %d)", info->source_file, info->source_line);
541 ffi_indent ();
542 fprintf (ffifile, "\"%s\"", info->name);
543 ffi_unindent (1);
544 target = DECL_ORIGINAL_TYPE (decl);
545 if (target == NULL)
546 target = TREE_TYPE (decl);
547 ffi_indent ();
548 emit_ffi_type_reference (target);
549 ffi_unindent (1);
550 fprintf (ffifile, ")\n");
551}
552
553static char *
554ffi_decl_name (tree decl)
555{
556 return (char*) (DECL_NAME (decl)
557 ? IDENTIFIER_POINTER (DECL_NAME (decl))
558 : "");
559}
560
561static void
562ffi_emit_integer_constant (tree val)
563{
564 if (TREE_CODE (val) != INTEGER_CST)
565 {
566 fprintf (stderr, "Expected integer_cst, got:\n");
567 debug_tree (val);
568 abort ();
569 }
570 if (TREE_INT_CST_HIGH (val) == 0)
571 fprintf (ffifile, HOST_WIDE_INT_PRINT_UNSIGNED, TREE_INT_CST_LOW (val));
572 else if (TREE_INT_CST_HIGH (val) == -1
573 && TREE_INT_CST_LOW (val) != 0)
574 {
575 fprintf (ffifile, "-");
576 fprintf (ffifile, HOST_WIDE_INT_PRINT_UNSIGNED,
577 -TREE_INT_CST_LOW (val));
578 }
579 else
580 fprintf (ffifile, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
581 TREE_INT_CST_HIGH (val), TREE_INT_CST_LOW (val));
582}
583
584static void
585ffi_emit_enum_values (tree val)
586{
587 fprintf (ffifile, "(");
588 while (val)
589 {
590 fprintf (ffifile, "(\"%s\" ", IDENTIFIER_POINTER (TREE_PURPOSE (val)));
591 ffi_emit_integer_constant (TREE_VALUE (val));
592 fprintf (ffifile, ")");
593 val = TREE_CHAIN (val);
594 }
595 fprintf (ffifile, ")");
596}
597
598static void
599ffi_herald (tree decl, const char *prefix)
600{
601 const char *source_file = "";
602 int line = 0;
603
604 if (DECL_P (decl))
605 {
606 source_file = DECL_SOURCE_FILE (decl);
607 line = DECL_SOURCE_LINE (decl);
608 }
609
610 if (source_file == NULL)
611 source_file = "";
612
613 fprintf (ffifile, "(%s (\"%s\" %d)", prefix, source_file, line);
614}
615
616static void
617ffi_emit_enum_idents (tree val)
618{
619 while (val)
620 {
621 fprintf (ffifile, "(enum-ident (\"\" 0)");
622 ffi_indent ();
623 fprintf (ffifile, "\"%s\" ", IDENTIFIER_POINTER (TREE_PURPOSE (val)));
624 ffi_emit_integer_constant (TREE_VALUE (val));
625 ffi_unindent (1);
626 fprintf(ffifile, ")\n");
627 val = TREE_CHAIN (val);
628 }
629}
630
631/*
632 It's hard to know exactly how to translate bit-fields.
633 LCC only allows bit-fields to be of type "int" or "unsigned" (and
634 doesn't even allow aliases to these types to be used.)
635 LCC-FFIGEN therefore generates something like:
636
637 ("x" (bit-field ("<type>" ()) <start-byte> <size-in-bytes> <a> <b> <c> <d>))
638
639 where :
640 <type> is one of int, unsigned
641 <start-byte, size-in-bytes> refer to a properly-aligned fullword that
642 "contains" the bit-field
643 <a> is what lcc calls the "fieldleft" of the bit-field
644 <b> is what lcc calls the "fieldright" of the bit-field
645 <c> is the width of the bit-field
646 <d> is a mask: (1- (ash 1 <c>))
647
648 Hmm. That doesn't have too much to do with the information that GCC
649 provides, but we could probably fake it. It seems silly to discard
650 the information that GCC -does- provide, so let's instead generate:
651
652 ("x" (bitfield ("<type>" ()) <start-bit> <size-in-bits>))
653
654 where <start-bit> is the field position starting in bits, of
655 the bit closest to the beginning of the structure.
656
657 Note that a GCC FIELD_DECL node X denotes a bit-field iff
658 DECL_BIT_FIELD (X) is true and DECL_SIZE (X) is non-null.
659*/
660
661static void
662ffi_emit_fields (tree field, int public_only, int indentp)
663{
664 for (; field; field = TREE_CHAIN (field), indentp = 1)
665 {
666 if (!public_only || (!TREE_PRIVATE (field)))
667 {
668 /*
669 fprintf (stderr, "\nEmit field:\n");
670 debug_tree (field);
671 */
672 if (indentp)
673 ffi_indent ();
674 if (DECL_BIT_FIELD (field))
675 {
676 tree type = DECL_BIT_FIELD_TYPE (field);
677 int bit_position = int_bit_position (field);
678 int size_in_bits = tree_low_cst (DECL_SIZE (field), 1);
679 fprintf (ffifile, "(\"%s\" (bitfield ", ffi_decl_name (field));
680 emit_ffi_type_reference (type);
681 fprintf (ffifile, " %d %d))", bit_position, size_in_bits);
682 }
683 else if (!DECL_NAME(field) && DECL_ARTIFICIAL (field))
684 {
685 tree type = TREE_TYPE (field);
686 if (TREE_CODE (type) != RECORD_TYPE)
687 {
688 debug_tree(field);
689 abort ();
690 }
691 ffi_emit_fields(TYPE_FIELDS (type), public_only, indentp);
692 }
693 else
694 {
695 tree type = TREE_TYPE (field);
696 int bit_position = int_bit_position (field);
697 tree size = TYPE_SIZE (type);
698 int type_size = (size
699 ? tree_low_cst (size, 1)
700 : 0); /* flex array */
701 fprintf (ffifile, "(\"%s\" (field ", ffi_decl_name (field));
702 emit_ffi_type_reference (type);
703 fprintf (ffifile, " %d %d))", bit_position >> 3, type_size >> 3);
704 }
705 if (indentp)
706 ffi_unindent (1);
707 }
708 }
709}
710
711static void
712ffi_emit_field_list (tree field, int public_only)
713{
714 ffi_indent ();
715 fprintf (ffifile, "(");
716 ffi_emit_fields(field, public_only, 0);
717 fprintf (ffifile, ")");
718 ffi_unindent (1);
719}
720
721static void
722ffi_emit_type (struct ffi_typeinfo *info, tree type)
723{
724 char *source_file = (char*) (info->source_file ? info->source_file : "");
725 int line_number = info->source_line;
726 /* tree field; */
727
728 switch (info->status)
729 {
730 case FFI_TYPE_STRUCT:
731 fprintf (ffifile, "(struct (\"%s\" %d)", source_file, line_number);
732 ffi_indent ();
733 fprintf (ffifile, "\"%s\"", info->name);
734 ffi_unindent (1);
735 ffi_emit_field_list (TYPE_FIELDS (type), 0);
736 fprintf (ffifile, ")\n");
737 break;
738
739 case FFI_TYPE_UNION:
740 fprintf (ffifile, "(union (\"%s\" %d)", source_file, line_number);
741 ffi_indent ();
742 fprintf (ffifile, "\"%s\"", info->name);
743 ffi_unindent (1);
744 ffi_emit_field_list (TYPE_FIELDS (type), 0);
745 fprintf (ffifile, ")\n");
746 break;
747
748 case FFI_TYPE_ENUM:
749 fprintf (ffifile, "(enum (\"%s\" %d)", source_file, line_number);
750 ffi_indent ();
751 fprintf (ffifile, "\"%s\"", info->name);
752 ffi_unindent (1);
753 ffi_emit_enum_values (TYPE_VALUES (type));
754 fprintf (ffifile, ")\n");
755 ffi_emit_enum_idents (TYPE_VALUES (type));
756 break;
757
758 default:
759 fprintf (stderr, "Unknown type!\n");
760 debug_tree (type);
761 abort ();
762 }
763}
764
765static void
766ffi_define_type (tree decl, enum ffi_typestatus status)
767{
768 tree type = TREE_TYPE(decl);
769 struct ffi_typeinfo *info = find_ffi_type_info (type);
770
771 /* fprintf (stderr, "Defining this type\n");
772 debug_tree (type);
773 */
774 switch (status)
775 {
776 case FFI_TYPE_PRIMITIVE:
777 info->name = ffi_primitive_type_name (decl);
778 info->source_file = NULL;
779 info->source_line = 0;
780 break;
781 case FFI_TYPE_TYPEDEF:
782 info->name = (char *) xstrdup(IDENTIFIER_POINTER (DECL_NAME (decl)));
783 info->source_file = (char *) xstrdup (DECL_SOURCE_FILE (decl));
784 info->source_line = DECL_SOURCE_LINE (decl);
785 ffi_emit_type_decl (info, decl);
786 break;
787 default:
788 fprintf (stderr, "Ignoring this type\n");
789 debug_tree (type);
790 abort ();
791 }
792 info = find_ffi_type_info (type); /* Might have moved. */
793 info->status = status;
794}
795
796static void
797ffi_define_builtin_type (tree type)
798{
799 tree name;
800
801 if (type && TYPE_P (type))
802 switch (TREE_CODE (type))
803 {
804 case INTEGER_TYPE:
805 case REAL_TYPE:
806 case COMPLEX_TYPE:
807 case VOID_TYPE:
808 case CHAR_TYPE:
809 case BOOLEAN_TYPE:
810 case VECTOR_TYPE:
811 name = TYPE_NAME (type);
812 if (name)
813 ffi_define_type (name, FFI_TYPE_PRIMITIVE);
814#if 0
815 else {
816 fprintf(stderr, "Unnamed builtin vector type:\n");
817 debug_tree(type);
818 }
819#endif
820 break;
821 case POINTER_TYPE:
822 case ARRAY_TYPE:
823 ffi_create_type_info (type);
824 break;
825 default:
826 fprintf (stderr, "\nSkippped this type.\n");
827 debug_tree(type);
828 break;
829 }
830}
831
832
833
834
835static void
836ffi_define_variable (tree decl)
837{
838 tree type = TREE_TYPE (decl);
839
840 ffi_herald (decl, "var");
841 ffi_indent ();
842 fprintf (ffifile, "\"%s\"", IDENTIFIER_POINTER (DECL_NAME (decl)));
843 ffi_unindent (1);
844 ffi_indent ();
845 emit_ffi_type_reference (type);
846 if (DECL_EXTERNAL (decl))
847 fprintf (ffifile, " (extern))\n");
848 else
849 fprintf (ffifile, " (static))\n");
850 ffi_unindent (1);
851}
852
853static void
854ffi_define_function (tree decl)
855{
856 tree type = TREE_TYPE (decl);
857
858 ffi_herald (decl, "function");
859 ffi_indent ();
860 fprintf (ffifile, "\"%s\"", IDENTIFIER_POINTER (DECL_NAME (decl)));
861 ffi_unindent (1);
862 ffi_indent ();
863 emit_ffi_type_reference (TYPE_MAIN_VARIANT(type));
864 if (DECL_EXTERNAL (decl))
865 fprintf (ffifile, " (extern))\n");
866 else
867 fprintf (ffifile, " (static))\n");
868 ffi_unindent (1);
869}
870
871
872
873/*
874 Stolen/copied from 'objc_method_parm_type' in objc-act.c
875*/
876static tree
877ffi_objc_method_parm_type (tree type)
878{
879 type = TREE_VALUE (TREE_TYPE (type));
880 if (TREE_CODE (type) == TYPE_DECL)
881 type = TREE_TYPE (type);
882#if 0
883 return TYPE_MAIN_VARIANT (type);
884#else
885 return type;
886#endif
887}
888
889
890static void
891ffi_define_objc_class (tree node)
892{
893 const char *super_name = NULL;
894 tree
895 pl = CLASS_PROTOCOL_LIST (node),
896 p;
897
898 if (CLASS_SUPER_NAME (node))
899 super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (node));
900
901
902 ffi_herald (node, "objc-class");
903 ffi_indent ();
904 fprintf (ffifile, "\"%s\"", IDENTIFIER_POINTER (CLASS_NAME (node)));
905 ffi_unindent (1);
906 ffi_indent ();
907 fprintf (ffifile, "(");
908 if (super_name)
909 fprintf (ffifile, "\"%s\")", super_name);
910 else
911 fprintf (ffifile, "void)");
912 ffi_unindent (1);
913 ffi_indent ();
914 fprintf (ffifile, "(");
915 for (pl = CLASS_PROTOCOL_LIST (node); pl; pl = TREE_CHAIN (pl))
916 {
917 p = TREE_VALUE (pl);
918 fprintf(ffifile, "\"%s\"", IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
919 if (TREE_CHAIN (pl))
920 fprintf (ffifile, " ");
921 }
922 fprintf (ffifile, ")");
923 ffi_unindent (1);
924 ffi_emit_field_list (CLASS_IVARS (node), 1);
925 fprintf (ffifile, ")\n");
926}
927
928static void
929ffi_define_objc_method (const char *method_kind, tree m, tree c, const char *category_name)
930{
931 tree param;
932 int i;
933
934 ffi_herald(m, method_kind);
935 ffi_indent ();
936 fprintf (ffifile, "\"%s\"", IDENTIFIER_POINTER (CLASS_NAME (c)));
937 ffi_unindent(1);
938 ffi_indent ();
939 if (category_name)
940 fprintf (ffifile, "(\"%s\")", category_name);
941 else
942 fprintf (ffifile, "()");
943 ffi_unindent (1);
944 ffi_indent ();
945 fprintf (ffifile, "\"%s\"", IDENTIFIER_POINTER (METHOD_SEL_NAME (m)));
946 ffi_unindent (1);
947 ffi_indent ();
948 fprintf (ffifile, "(");
949 for (i = 0, param = METHOD_SEL_ARGS (m);
950 param;
951 i++, param = TREE_CHAIN (param)) {
952 if (i > 0) {
953 fprintf (ffifile, " ");
954 }
955 emit_ffi_type_reference (ffi_objc_method_parm_type (param));
956 }
957 if (METHOD_ADD_ARGS (m))
958 if (TREE_PUBLIC (METHOD_ADD_ARGS (m)))
959 {
960 if (i)
961 fprintf (ffifile, " ");
962 fprintf (ffifile, "(void ())");
963 }
964 fprintf (ffifile, ")");
965 ffi_unindent (1);
966 ffi_indent ();
967 emit_ffi_type_reference (ffi_objc_method_parm_type (m));
968 ffi_unindent (1);
969 fprintf (ffifile, ")\n");
970}
971
972
973static void
974ffi_define_objc_class_method (tree m, tree c, const char *category_name)
975{
976 ffi_define_objc_method ("objc-class-method", m, c, category_name);
977}
978
979static void
980ffi_define_objc_instance_method (tree m, tree c, const char *category_name)
981{
982 ffi_define_objc_method ("objc-instance-method", m, c, category_name);
983}
984
985void
986ffi_rest_of_objc_class_compilation (tree node)
987{
988 tree n;
989 char *category_name = NULL;
990
991 ffi_define_objc_class (node);
992
993 for (n = CLASS_CLS_METHODS (node); n; n = TREE_CHAIN (n))
994 ffi_define_objc_class_method (n, node, category_name);
995 for (n = CLASS_NST_METHODS (node); n; n = TREE_CHAIN (n))
996 ffi_define_objc_instance_method (n, node, category_name);
997}
998
999void
1000ffi_rest_of_objc_category_compilation (tree category)
1001{
1002 tree n;
1003 const char *category_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (category));
1004
1005 for (n = CLASS_CLS_METHODS (category); n; n = TREE_CHAIN (n))
1006 ffi_define_objc_class_method (n, category, category_name);
1007 for (n = CLASS_NST_METHODS (category); n; n = TREE_CHAIN (n))
1008 ffi_define_objc_instance_method (n, category, category_name);
1009}
1010
1011void
1012ffi_rest_of_objc_protocol_compilation (tree p)
1013{
1014 tree n;
1015 char *category_name = NULL; /* ??? */
1016
1017 for (n = PROTOCOL_CLS_METHODS (p); n; n = TREE_CHAIN (n))
1018 ffi_define_objc_method ("objc-protocol-class-method",
1019 n,
1020 p,
1021 category_name);
1022 for (n = PROTOCOL_NST_METHODS (p); n; n = TREE_CHAIN (n))
1023 ffi_define_objc_method ("objc-protocol-instance-method",
1024 n,
1025 p,
1026 category_name);
1027}
1028
1029void
1030ffi_rest_of_decl_compilation (tree decl,
1031 int top_level ATTRIBUTE_UNUSED,
1032 int at_end ATTRIBUTE_UNUSED)
1033{
1034 /* tree type = TREE_TYPE (decl); */
1035
1036 if ((! ffi_initialized) || errorcount)
1037 return;
1038
1039
1040 if (TREE_CODE (decl) == ERROR_MARK)
1041 return;
1042
1043#if 0
1044 fprintf(stderr, "ffi_rest_of_decl_compilation:\n");
1045 debug_tree(decl);
1046 fprintf(stderr, "\n");
1047#endif
1048
1049
1050 switch (TREE_CODE (decl))
1051 {
1052 case TYPE_DECL:
1053 break;
1054
1055 case FUNCTION_DECL:
1056 ffi_define_function (decl);
1057 break;
1058
1059 case VAR_DECL:
1060 if (DECL_SOURCE_LINE (decl))
1061 ffi_define_variable (decl);
1062 break;
1063
1064 case PARM_DECL:
1065 case RESULT_DECL:
1066 fprintf(stderr, " ??? Parm or Result \n");
1067 debug_tree (decl);
1068 abort ();
1069 break;
1070
1071 case CONST_DECL:
1072 fprintf(stderr, " --- Maybe an enum ?\n");
1073 debug_tree (decl);
1074 abort ();
1075 break;
1076
1077 default:
1078 fprintf(stderr, " ??? Unknown \n");
1079 debug_tree (decl);
1080 abort ();
1081 break;
1082 }
1083}
1084
1085void
1086ffi_rest_of_type_compilation (tree type, int top_level ATTRIBUTE_UNUSED)
1087{
1088 if ((! ffi_initialized) || errorcount)
1089 return;
1090
1091 if (TREE_CODE (type) == ERROR_MARK)
1092 return;
1093
1094 ffi_emit_type (ffi_create_type_info (type), type);
1095}
1096
1097static int
1098is_whitespace (char c)
1099{
1100 switch (c)
1101 {
1102 case ' ': case '\n': case '\t': case '\f': case '\r':
1103 return 1;
1104 default:
1105 return 0;
1106 }
1107}
1108
1109/*
1110 Emit the macro name (possibly including a parenthesized arglist).
1111 Surround whatever's emitted here with double quotes.
1112 Return a pointer to the first character of the (possibly empty) definition.
1113*/
1114static const char *
1115ffi_emit_macro_name (const char *p)
1116{
1117 int in_arglist = 0;
1118 char c;
1119
1120 putc ('\"', ffifile);
1121 while ((c = *p) != 0)
1122 {
1123 switch (c)
1124 {
1125 case '(':
1126 in_arglist = 1;
1127 /* Fall down */
1128 case ',':
1129 putc (' ', ffifile);
1130 putc (c, ffifile);
1131 putc (' ', ffifile);
1132 break;
1133
1134 case ')':
1135 putc (' ', ffifile);
1136 putc (c, ffifile);
1137 putc ('\"', ffifile);
1138
1139 while (is_whitespace (*++p));
1140 return p;
1141
1142 default:
1143 if (is_whitespace (c) && !in_arglist)
1144 {
1145 putc ('\"', ffifile);
1146 while (is_whitespace (*++p));
1147 return p;
1148 }
1149 putc (c, ffifile);
1150 }
1151 ++p;
1152 }
1153 putc ('\"', ffifile);
1154 return p;
1155}
1156
1157static void
1158ffi_emit_macro_expansion (char *p)
1159{
1160 char c;
1161 char *q = p + strlen (p);
1162
1163 while ((q > p) && is_whitespace (q[-1])) q--;
1164 *q = '\0';
1165
1166 fprintf (ffifile, " \"");
1167
1168 while ((c = *p++) != '\0')
1169 {
1170 if (c == '\"')
1171 fputc ('\\', ffifile);
1172 fputc (c, ffifile);
1173 }
1174 fputc ('\"', ffifile);
1175}
1176
1177static void
1178ffi_debug_define (unsigned lineno, const char *macro)
1179{
1180 if (ffifile) {
1181 fprintf (ffifile, "(macro (\"%s\" %d) ", ffi_current_source_file, lineno);
1182 ffi_emit_macro_expansion ((char*)ffi_emit_macro_name (macro));
1183 fprintf (ffifile, ")\n");
1184 }
1185}
1186
1187static void
1188ffi_debug_undef (unsigned lineno ATTRIBUTE_UNUSED, const char *buffer)
1189{
1190 fprintf (ffifile, "(undef-macro \"%s\")\n", buffer);
1191}
1192
1193static void
1194ffi_debug_type_decl (tree decl, int local)
1195{
1196 tree type;
1197
1198 if (errorcount)
1199 return;
1200
1201 if ((! local) && ffi_initialized) {
1202 switch (TREE_CODE (decl))
1203 {
1204 case TYPE_DECL:
1205 type = TREE_TYPE (decl);
1206 if (DECL_NAME (decl))
1207 ffi_define_type (decl, FFI_TYPE_TYPEDEF);
1208 else
1209 {
1210 if (TREE_CODE (type) != ERROR_MARK)
1211 ffi_emit_type (ffi_create_type_info (type), type);
1212 }
1213 break;
1214
1215 default:
1216 fprintf (stderr, "Huh?");
1217 debug_tree (decl);
1218 abort ();
1219 }
1220 }
1221}
1222
1223
1224static struct gcc_debug_hooks ffi_debug_hooks;
1225
1226void
1227ffi_early_init (void)
1228{
1229 ffi_typevec_len = 100;
1230 ffi_typevec = xmalloc (ffi_typevec_len * sizeof ffi_typevec[0]);
1231 memset ((char *) ffi_typevec, 0, ffi_typevec_len * sizeof ffi_typevec[0]);
1232 /* Override debug hooks for macros. We don't emit assembly, so this
1233 shouldn't cause problems. */
1234 memcpy (&ffi_debug_hooks, &do_nothing_debug_hooks, sizeof ffi_debug_hooks);
1235 ffi_debug_hooks.start_source_file = ffi_debug_start_source_file;
1236 ffi_debug_hooks.end_source_file = ffi_debug_end_source_file;
1237 ffi_debug_hooks.define = ffi_debug_define;
1238 ffi_debug_hooks.undef = ffi_debug_undef;
1239 ffi_debug_hooks.type_decl = ffi_debug_type_decl;
1240 debug_hooks = &ffi_debug_hooks;
1241}
1242
1243void
1244ffi_init (FILE *ffi_file, char *input_file_name)
1245{
1246 int i;
1247
1248 ffifile = ffi_file ? ffi_file : stderr;
1249 ffi_current_source_file = (char *) xstrdup (input_file_name);
1250 ffi_primary_source_file = ffi_current_source_file;
1251
1252 for (i = 0; i < itk_none; i++)
1253 {
1254 ffi_define_builtin_type (integer_types[i]);
1255 }
1256 for (i = 0; i < TI_MAX; i++)
1257 {
1258 ffi_define_builtin_type (global_trees[i]);
1259 }
1260
1261
1262 ffi_initialized = 1;
1263}
1264
Note: See TracBrowser for help on using the repository browser.