source: trunk/ffigen4/source/ffi.c@ 43

Last change on this file since 43 was 33, checked in by gb, 19 years ago

Maybe synthesize vector types.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 30.8 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 {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_field_list (tree field, int public_only)
663{
664 int indentp = 0;
665 ffi_indent ();
666 fprintf (ffifile, "(");
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
687 {
688 tree type = TREE_TYPE (field);
689 int bit_position = int_bit_position (field);
690 tree size = TYPE_SIZE (type);
691 int type_size = (size
692 ? tree_low_cst (size, 1)
693 : 0); /* flex array */
694 fprintf (ffifile, "(\"%s\" (field ", ffi_decl_name (field));
695 emit_ffi_type_reference (type);
696 fprintf (ffifile, " %d %d))", bit_position >> 3, type_size >> 3);
697 }
698 if (indentp)
699 ffi_unindent (1);
700 }
701 }
702 fprintf (ffifile, ")");
703 ffi_unindent (1);
704}
705
706static void
707ffi_emit_type (struct ffi_typeinfo *info, tree type)
708{
709 char *source_file = (char*) (info->source_file ? info->source_file : "");
710 int line_number = info->source_line;
711 /* tree field; */
712
713 switch (info->status)
714 {
715 case FFI_TYPE_STRUCT:
716 fprintf (ffifile, "(struct (\"%s\" %d)", source_file, line_number);
717 ffi_indent ();
718 fprintf (ffifile, "\"%s\"", info->name);
719 ffi_unindent (1);
720 ffi_emit_field_list (TYPE_FIELDS (type), 0);
721 fprintf (ffifile, ")\n");
722 break;
723
724 case FFI_TYPE_UNION:
725 fprintf (ffifile, "(union (\"%s\" %d)", source_file, line_number);
726 ffi_indent ();
727 fprintf (ffifile, "\"%s\"", info->name);
728 ffi_unindent (1);
729 ffi_emit_field_list (TYPE_FIELDS (type), 0);
730 fprintf (ffifile, ")\n");
731 break;
732
733 case FFI_TYPE_ENUM:
734 fprintf (ffifile, "(enum (\"%s\" %d)", source_file, line_number);
735 ffi_indent ();
736 fprintf (ffifile, "\"%s\"", info->name);
737 ffi_unindent (1);
738 ffi_emit_enum_values (TYPE_VALUES (type));
739 fprintf (ffifile, ")\n");
740 ffi_emit_enum_idents (TYPE_VALUES (type));
741 break;
742
743 default:
744 fprintf (stderr, "Unknown type!\n");
745 debug_tree (type);
746 abort ();
747 }
748}
749
750static void
751ffi_define_type (tree decl, enum ffi_typestatus status)
752{
753 tree type = TREE_TYPE(decl);
754 struct ffi_typeinfo *info = find_ffi_type_info (type);
755
756 /* fprintf (stderr, "Defining this type\n");
757 debug_tree (type);
758 */
759 switch (status)
760 {
761 case FFI_TYPE_PRIMITIVE:
762 info->name = ffi_primitive_type_name (decl);
763 info->source_file = NULL;
764 info->source_line = 0;
765 break;
766 case FFI_TYPE_TYPEDEF:
767 info->name = (char *) xstrdup(IDENTIFIER_POINTER (DECL_NAME (decl)));
768 info->source_file = (char *) xstrdup (DECL_SOURCE_FILE (decl));
769 info->source_line = DECL_SOURCE_LINE (decl);
770 ffi_emit_type_decl (info, decl);
771 break;
772 default:
773 fprintf (stderr, "Ignoring this type\n");
774 debug_tree (type);
775 abort ();
776 }
777 info = find_ffi_type_info (type); /* Might have moved. */
778 info->status = status;
779}
780
781static void
782ffi_define_builtin_type (tree type)
783{
784 tree name;
785
786 if (type && TYPE_P (type))
787 switch (TREE_CODE (type))
788 {
789 case INTEGER_TYPE:
790 case REAL_TYPE:
791 case COMPLEX_TYPE:
792 case VOID_TYPE:
793 case CHAR_TYPE:
794 case BOOLEAN_TYPE:
795 case VECTOR_TYPE:
796 name = TYPE_NAME (type);
797 if (name)
798 ffi_define_type (name, FFI_TYPE_PRIMITIVE);
799 else {
800 fprintf(stderr, "Unnamed builtin vector type:\n");
801 debug_tree(type);
802 }
803 break;
804 case POINTER_TYPE:
805 case ARRAY_TYPE:
806 ffi_create_type_info (type);
807 break;
808 default:
809 fprintf (stderr, "\nSkippped this type.\n");
810 debug_tree(type);
811 break;
812 }
813}
814
815
816
817
818static void
819ffi_define_variable (tree decl)
820{
821 tree type = TREE_TYPE (decl);
822
823 ffi_herald (decl, "var");
824 ffi_indent ();
825 fprintf (ffifile, "\"%s\"", IDENTIFIER_POINTER (DECL_NAME (decl)));
826 ffi_unindent (1);
827 ffi_indent ();
828 emit_ffi_type_reference (type);
829 if (DECL_EXTERNAL (decl))
830 fprintf (ffifile, " (extern))\n");
831 else
832 fprintf (ffifile, " (static))\n");
833 ffi_unindent (1);
834}
835
836static void
837ffi_define_function (tree decl)
838{
839 tree type = TREE_TYPE (decl);
840
841 ffi_herald (decl, "function");
842 ffi_indent ();
843 fprintf (ffifile, "\"%s\"", IDENTIFIER_POINTER (DECL_NAME (decl)));
844 ffi_unindent (1);
845 ffi_indent ();
846 emit_ffi_type_reference (TYPE_MAIN_VARIANT(type));
847 if (DECL_EXTERNAL (decl))
848 fprintf (ffifile, " (extern))\n");
849 else
850 fprintf (ffifile, " (static))\n");
851 ffi_unindent (1);
852}
853
854
855
856/*
857 Stolen/copied from 'objc_method_parm_type' in objc-act.c
858*/
859static tree
860ffi_objc_method_parm_type (tree type)
861{
862 type = TREE_VALUE (TREE_TYPE (type));
863 if (TREE_CODE (type) == TYPE_DECL)
864 type = TREE_TYPE (type);
865#if 0
866 return TYPE_MAIN_VARIANT (type);
867#else
868 return type;
869#endif
870}
871
872
873static void
874ffi_define_objc_class (tree node)
875{
876 const char *super_name = NULL;
877 tree
878 pl = CLASS_PROTOCOL_LIST (node),
879 p;
880
881 if (CLASS_SUPER_NAME (node))
882 super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (node));
883
884
885 ffi_herald (node, "objc-class");
886 ffi_indent ();
887 fprintf (ffifile, "\"%s\"", IDENTIFIER_POINTER (CLASS_NAME (node)));
888 ffi_unindent (1);
889 ffi_indent ();
890 fprintf (ffifile, "(");
891 if (super_name)
892 fprintf (ffifile, "\"%s\")", super_name);
893 else
894 fprintf (ffifile, "void)");
895 ffi_unindent (1);
896 ffi_indent ();
897 fprintf (ffifile, "(");
898 for (pl = CLASS_PROTOCOL_LIST (node); pl; pl = TREE_CHAIN (pl))
899 {
900 p = TREE_VALUE (pl);
901 fprintf(ffifile, "\"%s\"", IDENTIFIER_POINTER (PROTOCOL_NAME (p)));
902 if (TREE_CHAIN (pl))
903 fprintf (ffifile, " ");
904 }
905 fprintf (ffifile, ")");
906 ffi_unindent (1);
907 ffi_emit_field_list (CLASS_IVARS (node), 1);
908 fprintf (ffifile, ")\n");
909}
910
911static void
912ffi_define_objc_method (const char *method_kind, tree m, tree c, const char *category_name)
913{
914 tree param;
915 int i;
916
917 ffi_herald(m, method_kind);
918 ffi_indent ();
919 fprintf (ffifile, "\"%s\"", IDENTIFIER_POINTER (CLASS_NAME (c)));
920 ffi_unindent(1);
921 ffi_indent ();
922 if (category_name)
923 fprintf (ffifile, "(\"%s\")", category_name);
924 else
925 fprintf (ffifile, "()");
926 ffi_unindent (1);
927 ffi_indent ();
928 fprintf (ffifile, "\"%s\"", IDENTIFIER_POINTER (METHOD_SEL_NAME (m)));
929 ffi_unindent (1);
930 ffi_indent ();
931 fprintf (ffifile, "(");
932 for (i = 0, param = METHOD_SEL_ARGS (m);
933 param;
934 i++, param = TREE_CHAIN (param)) {
935 if (i > 0) {
936 fprintf (ffifile, " ");
937 }
938 emit_ffi_type_reference (ffi_objc_method_parm_type (param));
939 }
940 if (METHOD_ADD_ARGS (m))
941 if (TREE_PUBLIC (METHOD_ADD_ARGS (m)))
942 {
943 if (i)
944 fprintf (ffifile, " ");
945 fprintf (ffifile, "(void ())");
946 }
947 fprintf (ffifile, ")");
948 ffi_unindent (1);
949 ffi_indent ();
950 emit_ffi_type_reference (ffi_objc_method_parm_type (m));
951 ffi_unindent (1);
952 fprintf (ffifile, ")\n");
953}
954
955
956static void
957ffi_define_objc_class_method (tree m, tree c, const char *category_name)
958{
959 ffi_define_objc_method ("objc-class-method", m, c, category_name);
960}
961
962static void
963ffi_define_objc_instance_method (tree m, tree c, const char *category_name)
964{
965 ffi_define_objc_method ("objc-instance-method", m, c, category_name);
966}
967
968void
969ffi_rest_of_objc_class_compilation (tree node)
970{
971 tree n;
972 char *category_name = NULL;
973
974 ffi_define_objc_class (node);
975
976 for (n = CLASS_CLS_METHODS (node); n; n = TREE_CHAIN (n))
977 ffi_define_objc_class_method (n, node, category_name);
978 for (n = CLASS_NST_METHODS (node); n; n = TREE_CHAIN (n))
979 ffi_define_objc_instance_method (n, node, category_name);
980}
981
982void
983ffi_rest_of_objc_category_compilation (tree category)
984{
985 tree n;
986 const char *category_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (category));
987
988 for (n = CLASS_CLS_METHODS (category); n; n = TREE_CHAIN (n))
989 ffi_define_objc_class_method (n, category, category_name);
990 for (n = CLASS_NST_METHODS (category); n; n = TREE_CHAIN (n))
991 ffi_define_objc_instance_method (n, category, category_name);
992}
993
994void
995ffi_rest_of_objc_protocol_compilation (tree p)
996{
997 tree n;
998 char *category_name;
999
1000 for (n = PROTOCOL_CLS_METHODS (p); n; n = TREE_CHAIN (n))
1001 ffi_define_objc_method ("objc-protocol-class-method",
1002 n,
1003 p,
1004 category_name);
1005 for (n = PROTOCOL_NST_METHODS (p); n; n = TREE_CHAIN (n))
1006 ffi_define_objc_method ("objc-protocol-instance-method",
1007 n,
1008 p,
1009 category_name);
1010}
1011
1012void
1013ffi_rest_of_decl_compilation (tree decl,
1014 int top_level ATTRIBUTE_UNUSED,
1015 int at_end ATTRIBUTE_UNUSED)
1016{
1017 /* tree type = TREE_TYPE (decl); */
1018
1019 if ((! ffi_initialized) || errorcount)
1020 return;
1021
1022
1023 if (TREE_CODE (decl) == ERROR_MARK)
1024 return;
1025
1026#if 0
1027 fprintf(stderr, "ffi_rest_of_decl_compilation:\n");
1028 debug_tree(decl);
1029 fprintf(stderr, "\n");
1030#endif
1031
1032
1033 switch (TREE_CODE (decl))
1034 {
1035 case TYPE_DECL:
1036 break;
1037
1038 case FUNCTION_DECL:
1039 ffi_define_function (decl);
1040 break;
1041
1042 case VAR_DECL:
1043 if (DECL_SOURCE_LINE (decl))
1044 ffi_define_variable (decl);
1045 break;
1046
1047 case PARM_DECL:
1048 case RESULT_DECL:
1049 fprintf(stderr, " ??? Parm or Result \n");
1050 debug_tree (decl);
1051 abort ();
1052 break;
1053
1054 case CONST_DECL:
1055 fprintf(stderr, " --- Maybe an enum ?\n");
1056 debug_tree (decl);
1057 abort ();
1058 break;
1059
1060 default:
1061 fprintf(stderr, " ??? Unknown \n");
1062 debug_tree (decl);
1063 abort ();
1064 break;
1065 }
1066}
1067
1068void
1069ffi_rest_of_type_compilation (tree type, int top_level ATTRIBUTE_UNUSED)
1070{
1071 if ((! ffi_initialized) || errorcount)
1072 return;
1073
1074 if (TREE_CODE (type) == ERROR_MARK)
1075 return;
1076
1077 ffi_emit_type (ffi_create_type_info (type), type);
1078}
1079
1080static int
1081is_whitespace (char c)
1082{
1083 switch (c)
1084 {
1085 case ' ': case '\n': case '\t': case '\f': case '\r':
1086 return 1;
1087 default:
1088 return 0;
1089 }
1090}
1091
1092/*
1093 Emit the macro name (possibly including a parenthesized arglist).
1094 Surround whatever's emitted here with double quotes.
1095 Return a pointer to the first character of the (possibly empty) definition.
1096*/
1097static const char *
1098ffi_emit_macro_name (const char *p)
1099{
1100 int in_arglist = 0;
1101 char c;
1102
1103 putc ('\"', ffifile);
1104 while ((c = *p) != 0)
1105 {
1106 switch (c)
1107 {
1108 case '(':
1109 in_arglist = 1;
1110 /* Fall down */
1111 case ',':
1112 putc (' ', ffifile);
1113 putc (c, ffifile);
1114 putc (' ', ffifile);
1115 break;
1116
1117 case ')':
1118 putc (' ', ffifile);
1119 putc (c, ffifile);
1120 putc ('\"', ffifile);
1121
1122 while (is_whitespace (*++p));
1123 return p;
1124
1125 default:
1126 if (is_whitespace (c) && !in_arglist)
1127 {
1128 putc ('\"', ffifile);
1129 while (is_whitespace (*++p));
1130 return p;
1131 }
1132 putc (c, ffifile);
1133 }
1134 ++p;
1135 }
1136 putc ('\"', ffifile);
1137 return p;
1138}
1139
1140static void
1141ffi_emit_macro_expansion (char *p)
1142{
1143 char c;
1144 char *q = p + strlen (p);
1145
1146 while ((q > p) && is_whitespace (q[-1])) q--;
1147 *q = '\0';
1148
1149 fprintf (ffifile, " \"");
1150
1151 while ((c = *p++) != '\0')
1152 {
1153 if (c == '\"')
1154 fputc ('\\', ffifile);
1155 fputc (c, ffifile);
1156 }
1157 fputc ('\"', ffifile);
1158}
1159
1160static void
1161ffi_debug_define (unsigned lineno, const char *macro)
1162{
1163 if (ffifile) {
1164 fprintf (ffifile, "(macro (\"%s\" %d) ", ffi_current_source_file, lineno);
1165 ffi_emit_macro_expansion ((char*)ffi_emit_macro_name (macro));
1166 fprintf (ffifile, ")\n");
1167 }
1168}
1169
1170static void
1171ffi_debug_undef (unsigned lineno ATTRIBUTE_UNUSED, const char *buffer)
1172{
1173 fprintf (ffifile, "(undef-macro \"%s\")\n", buffer);
1174}
1175
1176static void
1177ffi_debug_type_decl (tree decl, int local)
1178{
1179 tree type;
1180
1181 if (errorcount)
1182 return;
1183
1184 if ((! local) && ffi_initialized) {
1185 switch (TREE_CODE (decl))
1186 {
1187 case TYPE_DECL:
1188 type = TREE_TYPE (decl);
1189 if (DECL_NAME (decl))
1190 ffi_define_type (decl, FFI_TYPE_TYPEDEF);
1191 else
1192 {
1193 if (TREE_CODE (type) != ERROR_MARK)
1194 ffi_emit_type (ffi_create_type_info (type), type);
1195 }
1196 break;
1197
1198 default:
1199 fprintf (stderr, "Huh?");
1200 debug_tree (decl);
1201 abort ();
1202 }
1203 }
1204}
1205
1206
1207static struct gcc_debug_hooks ffi_debug_hooks;
1208
1209void
1210ffi_early_init (void)
1211{
1212 ffi_typevec_len = 100;
1213 ffi_typevec = xmalloc (ffi_typevec_len * sizeof ffi_typevec[0]);
1214 memset ((char *) ffi_typevec, 0, ffi_typevec_len * sizeof ffi_typevec[0]);
1215 /* Override debug hooks for macros. We don't emit assembly, so this
1216 shouldn't cause problems. */
1217 memcpy (&ffi_debug_hooks, &do_nothing_debug_hooks, sizeof ffi_debug_hooks);
1218 ffi_debug_hooks.start_source_file = ffi_debug_start_source_file;
1219 ffi_debug_hooks.end_source_file = ffi_debug_end_source_file;
1220 ffi_debug_hooks.define = ffi_debug_define;
1221 ffi_debug_hooks.undef = ffi_debug_undef;
1222 ffi_debug_hooks.type_decl = ffi_debug_type_decl;
1223 debug_hooks = &ffi_debug_hooks;
1224}
1225
1226void
1227ffi_init (FILE *ffi_file, char *input_file_name)
1228{
1229 int i;
1230
1231 ffifile = ffi_file ? ffi_file : stderr;
1232 ffi_current_source_file = (char *) xstrdup (input_file_name);
1233 ffi_primary_source_file = ffi_current_source_file;
1234
1235 for (i = 0; i < itk_none; i++)
1236 {
1237 ffi_define_builtin_type (integer_types[i]);
1238 }
1239 for (i = 0; i < TI_MAX; i++)
1240 {
1241 ffi_define_builtin_type (global_trees[i]);
1242 }
1243
1244
1245 ffi_initialized = 1;
1246}
1247
Note: See TracBrowser for help on using the repository browser.