source: branches/ffigen-x-cocotron/ffigen4/source/ffi.c@ 75

Last change on this file since 75 was 63, checked in by gb, 15 years ago

New.

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