source: tags/start/source/ffi.c@ 29

Last change on this file since 29 was 2, checked in by gb, 20 years ago

Initial revision

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