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

Last change on this file since 64 was 48, checked in by gb, 16 years ago

Don't print confusing warnings about anonymous builtin vector types.

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