source: branches/ffigen-apple-gcc-5646/ffigen4/source/ffi.c@ 72

Last change on this file since 72 was 69, checked in by gb, 14 years ago

Check in working copy changes.

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