comparison gcc/godump.c @ 16:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents 561a7518be6b
children 84e7813d76e9
comparison
equal deleted inserted replaced
15:561a7518be6b 16:04ced10e8804
1 /* Output Go language descriptions of types. 1 /* Output Go language descriptions of types.
2 Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc. 2 Copyright (C) 2008-2017 Free Software Foundation, Inc.
3 Written by Ian Lance Taylor <iant@google.com>. 3 Written by Ian Lance Taylor <iant@google.com>.
4 4
5 This file is part of GCC. 5 This file is part of GCC.
6 6
7 GCC is free software; you can redistribute it and/or modify it under 7 GCC is free software; you can redistribute it and/or modify it under
28 are all hidden in Go. */ 28 are all hidden in Go. */
29 29
30 #include "config.h" 30 #include "config.h"
31 #include "system.h" 31 #include "system.h"
32 #include "coretypes.h" 32 #include "coretypes.h"
33 #include "tree.h"
33 #include "diagnostic-core.h" 34 #include "diagnostic-core.h"
34 #include "tree.h"
35 #include "ggc.h"
36 #include "pointer-set.h"
37 #include "obstack.h"
38 #include "debug.h" 35 #include "debug.h"
36 #include "stor-layout.h"
39 37
40 /* We dump this information from the debug hooks. This gives us a 38 /* We dump this information from the debug hooks. This gives us a
41 stable and maintainable API to hook into. In order to work 39 stable and maintainable API to hook into. In order to work
42 correctly when -g is used, we build our own hooks structure which 40 correctly when -g is used, we build our own hooks structure which
43 wraps the hooks we need to change. */ 41 wraps the hooks we need to change. */
54 52
55 static FILE *go_dump_file; 53 static FILE *go_dump_file;
56 54
57 /* A queue of decls to output. */ 55 /* A queue of decls to output. */
58 56
59 static GTY(()) VEC(tree,gc) *queue; 57 static GTY(()) vec<tree, va_gc> *queue;
60 58
61 /* A hash table of macros we have seen. */ 59 /* A hash table of macros we have seen. */
62 60
63 static htab_t macro_hash; 61 static htab_t macro_hash;
64 62
65 /* For the hash tables. */ 63 /* The type of a value in macro_hash. */
64
65 struct macro_hash_value
66 {
67 /* The name stored in the hash table. */
68 char *name;
69 /* The value of the macro. */
70 char *value;
71 };
72
73 /* Returns the number of units necessary to represent an integer with the given
74 PRECISION (in bits). */
75
76 static inline unsigned int
77 precision_to_units (unsigned int precision)
78 {
79 return (precision + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
80 }
81
82 /* Calculate the hash value for an entry in the macro hash table. */
83
84 static hashval_t
85 macro_hash_hashval (const void *val)
86 {
87 const struct macro_hash_value *mhval = (const struct macro_hash_value *) val;
88 return htab_hash_string (mhval->name);
89 }
90
91 /* Compare values in the macro hash table for equality. */
92
93 static int
94 macro_hash_eq (const void *v1, const void *v2)
95 {
96 const struct macro_hash_value *mhv1 = (const struct macro_hash_value *) v1;
97 const struct macro_hash_value *mhv2 = (const struct macro_hash_value *) v2;
98 return strcmp (mhv1->name, mhv2->name) == 0;
99 }
100
101 /* Free values deleted from the macro hash table. */
102
103 static void
104 macro_hash_del (void *v)
105 {
106 struct macro_hash_value *mhv = (struct macro_hash_value *) v;
107 XDELETEVEC (mhv->name);
108 XDELETEVEC (mhv->value);
109 XDELETE (mhv);
110 }
111
112 /* For the string hash tables. */
66 113
67 static int 114 static int
68 string_hash_eq (const void *y1, const void *y2) 115 string_hash_eq (const void *y1, const void *y2)
69 { 116 {
70 return strcmp ((const char *) y1, (const char *) y2) == 0; 117 return strcmp ((const char *) y1, (const char *) y2) == 0;
75 static void 122 static void
76 go_define (unsigned int lineno, const char *buffer) 123 go_define (unsigned int lineno, const char *buffer)
77 { 124 {
78 const char *p; 125 const char *p;
79 const char *name_end; 126 const char *name_end;
127 size_t out_len;
80 char *out_buffer; 128 char *out_buffer;
81 char *q; 129 char *q;
82 bool saw_operand; 130 bool saw_operand;
83 bool need_operand; 131 bool need_operand;
132 struct macro_hash_value *mhval;
84 char *copy; 133 char *copy;
85 hashval_t hashval; 134 hashval_t hashval;
86 void **slot; 135 void **slot;
87 136
88 real_debug_hooks->define (lineno, buffer); 137 real_debug_hooks->define (lineno, buffer);
103 152
104 copy = XNEWVEC (char, name_end - buffer + 1); 153 copy = XNEWVEC (char, name_end - buffer + 1);
105 memcpy (copy, buffer, name_end - buffer); 154 memcpy (copy, buffer, name_end - buffer);
106 copy[name_end - buffer] = '\0'; 155 copy[name_end - buffer] = '\0';
107 156
157 mhval = XNEW (struct macro_hash_value);
158 mhval->name = copy;
159 mhval->value = NULL;
160
108 hashval = htab_hash_string (copy); 161 hashval = htab_hash_string (copy);
109 slot = htab_find_slot_with_hash (macro_hash, copy, hashval, NO_INSERT); 162 slot = htab_find_slot_with_hash (macro_hash, mhval, hashval, NO_INSERT);
110 if (slot != NULL)
111 {
112 XDELETEVEC (copy);
113 return;
114 }
115 163
116 /* For simplicity, we force all names to be hidden by adding an 164 /* For simplicity, we force all names to be hidden by adding an
117 initial underscore, and let the user undo this as needed. */ 165 initial underscore, and let the user undo this as needed. */
118 out_buffer = XNEWVEC (char, strlen (p) * 2 + 1); 166 out_len = strlen (p) * 2 + 1;
167 out_buffer = XNEWVEC (char, out_len);
119 q = out_buffer; 168 q = out_buffer;
120 saw_operand = false; 169 saw_operand = false;
121 need_operand = false; 170 need_operand = false;
122 while (*p != '\0') 171 while (*p != '\0')
123 { 172 {
139 worry about UTF-8 identifiers, but they are not a 188 worry about UTF-8 identifiers, but they are not a
140 problem for practical uses of -fdump-go-spec so we 189 problem for practical uses of -fdump-go-spec so we
141 don't worry about them. */ 190 don't worry about them. */
142 const char *start; 191 const char *start;
143 char *n; 192 char *n;
193 struct macro_hash_value idval;
144 194
145 if (saw_operand) 195 if (saw_operand)
146 goto unknown; 196 goto unknown;
147 197
148 start = p; 198 start = p;
149 while (ISALNUM (*p) || *p == '_') 199 while (ISALNUM (*p) || *p == '_')
150 ++p; 200 ++p;
151 n = XALLOCAVEC (char, p - start + 1); 201 n = XALLOCAVEC (char, p - start + 1);
152 memcpy (n, start, p - start); 202 memcpy (n, start, p - start);
153 n[p - start] = '\0'; 203 n[p - start] = '\0';
154 slot = htab_find_slot (macro_hash, n, NO_INSERT); 204 idval.name = n;
155 if (slot == NULL || *slot == NULL) 205 idval.value = NULL;
206 if (htab_find (macro_hash, &idval) == NULL)
156 { 207 {
157 /* This is a reference to a name which was not defined 208 /* This is a reference to a name which was not defined
158 as a macro. */ 209 as a macro. */
159 goto unknown; 210 goto unknown;
160 } 211 }
298 break; 349 break;
299 350
300 case '"': 351 case '"':
301 case '\'': 352 case '\'':
302 { 353 {
303 char quote = *p; 354 char quote;
355 int count;
356
357 if (saw_operand)
358 goto unknown;
359 quote = *p;
304 *q++ = *p++; 360 *q++ = *p++;
361 count = 0;
305 while (*p != quote) 362 while (*p != quote)
306 { 363 {
307 int c; 364 int c;
308 365
309 if (*p == '\0') 366 if (*p == '\0')
310 goto unknown; 367 goto unknown;
368
369 ++count;
311 370
312 if (*p != '\\') 371 if (*p != '\\')
313 { 372 {
314 *q++ = *p++; 373 *q++ = *p++;
315 continue; 374 continue;
352 411
353 default: 412 default:
354 goto unknown; 413 goto unknown;
355 } 414 }
356 } 415 }
416
357 *q++ = *p++; 417 *q++ = *p++;
418
419 if (quote == '\'' && count != 1)
420 goto unknown;
421
422 saw_operand = true;
423 need_operand = false;
424
358 break; 425 break;
359 } 426 }
360 427
361 default: 428 default:
362 goto unknown; 429 goto unknown;
364 } 431 }
365 432
366 if (need_operand) 433 if (need_operand)
367 goto unknown; 434 goto unknown;
368 435
436 gcc_assert ((size_t) (q - out_buffer) < out_len);
369 *q = '\0'; 437 *q = '\0';
370 438
371 slot = htab_find_slot_with_hash (macro_hash, copy, hashval, INSERT); 439 mhval->value = out_buffer;
372 *slot = copy; 440
373 441 if (slot == NULL)
374 fprintf (go_dump_file, "const _%s = %s\n", copy, out_buffer); 442 {
375 443 slot = htab_find_slot_with_hash (macro_hash, mhval, hashval, INSERT);
376 XDELETEVEC (out_buffer); 444 gcc_assert (slot != NULL && *slot == NULL);
445 }
446 else
447 {
448 if (*slot != NULL)
449 macro_hash_del (*slot);
450 }
451
452 *slot = mhval;
453
377 return; 454 return;
378 455
379 unknown: 456 unknown:
380 fprintf (go_dump_file, "// unknowndefine %s\n", buffer); 457 fprintf (go_dump_file, "// unknowndefine %s\n", buffer);
458 if (slot != NULL)
459 htab_clear_slot (macro_hash, slot);
381 XDELETEVEC (out_buffer); 460 XDELETEVEC (out_buffer);
382 XDELETEVEC (copy); 461 XDELETEVEC (copy);
383 } 462 }
384 463
385 /* A macro undef. */ 464 /* A macro undef. */
386 465
387 static void 466 static void
388 go_undef (unsigned int lineno, const char *buffer) 467 go_undef (unsigned int lineno, const char *buffer)
389 { 468 {
469 struct macro_hash_value mhval;
390 void **slot; 470 void **slot;
391 471
392 real_debug_hooks->undef (lineno, buffer); 472 real_debug_hooks->undef (lineno, buffer);
393 473
394 slot = htab_find_slot (macro_hash, buffer, NO_INSERT); 474 mhval.name = CONST_CAST (char *, buffer);
395 if (slot == NULL) 475 mhval.value = NULL;
396 return; 476 slot = htab_find_slot (macro_hash, &mhval, NO_INSERT);
397 fprintf (go_dump_file, "// undef _%s\n", buffer); 477 if (slot != NULL)
398 /* We don't delete the slot from the hash table because that will 478 htab_clear_slot (macro_hash, slot);
399 cause a duplicate const definition. */
400 } 479 }
401 480
402 /* A function or variable decl. */ 481 /* A function or variable decl. */
403 482
404 static void 483 static void
406 { 485 {
407 if (!TREE_PUBLIC (decl) 486 if (!TREE_PUBLIC (decl)
408 || DECL_IS_BUILTIN (decl) 487 || DECL_IS_BUILTIN (decl)
409 || DECL_NAME (decl) == NULL_TREE) 488 || DECL_NAME (decl) == NULL_TREE)
410 return; 489 return;
411 VEC_safe_push (tree, gc, queue, decl); 490 vec_safe_push (queue, decl);
412 } 491 }
413 492
414 /* A function decl. */ 493 /* A function decl. */
415 494
416 static void 495 static void
418 { 497 {
419 real_debug_hooks->function_decl (decl); 498 real_debug_hooks->function_decl (decl);
420 go_decl (decl); 499 go_decl (decl);
421 } 500 }
422 501
502 static void
503 go_early_global_decl (tree decl)
504 {
505 go_decl (decl);
506 if (TREE_CODE (decl) != FUNCTION_DECL || DECL_STRUCT_FUNCTION (decl) != NULL)
507 real_debug_hooks->early_global_decl (decl);
508 }
509
423 /* A global variable decl. */ 510 /* A global variable decl. */
424 511
425 static void 512 static void
426 go_global_decl (tree decl) 513 go_late_global_decl (tree decl)
427 { 514 {
428 real_debug_hooks->global_decl (decl); 515 real_debug_hooks->late_global_decl (decl);
429 go_decl (decl);
430 } 516 }
431 517
432 /* A type declaration. */ 518 /* A type declaration. */
433 519
434 static void 520 static void
441 if (DECL_NAME (decl) == NULL_TREE 527 if (DECL_NAME (decl) == NULL_TREE
442 && (TYPE_NAME (TREE_TYPE (decl)) == NULL_TREE 528 && (TYPE_NAME (TREE_TYPE (decl)) == NULL_TREE
443 || TREE_CODE (TYPE_NAME (TREE_TYPE (decl))) != IDENTIFIER_NODE) 529 || TREE_CODE (TYPE_NAME (TREE_TYPE (decl))) != IDENTIFIER_NODE)
444 && TREE_CODE (TREE_TYPE (decl)) != ENUMERAL_TYPE) 530 && TREE_CODE (TREE_TYPE (decl)) != ENUMERAL_TYPE)
445 return; 531 return;
446 VEC_safe_push (tree, gc, queue, decl); 532 vec_safe_push (queue, decl);
447 } 533 }
448 534
449 /* A container for the data we pass around when generating information 535 /* A container for the data we pass around when generating information
450 at the end of the compilation. */ 536 at the end of the compilation. */
451 537
452 struct godump_container 538 struct godump_container
453 { 539 {
454 /* DECLs that we have already seen. */ 540 /* DECLs that we have already seen. */
455 struct pointer_set_t *decls_seen; 541 hash_set<tree> decls_seen;
456 542
457 /* Types which may potentially have to be defined as dummy 543 /* Types which may potentially have to be defined as dummy
458 types. */ 544 types. */
459 struct pointer_set_t *pot_dummy_types; 545 hash_set<const char *> pot_dummy_types;
460 546
461 /* Go keywords. */ 547 /* Go keywords. */
462 htab_t keyword_hash; 548 htab_t keyword_hash;
463 549
464 /* Global type definitions. */ 550 /* Global type definitions. */
465 htab_t type_hash; 551 htab_t type_hash;
552
553 /* Invalid types. */
554 htab_t invalid_hash;
466 555
467 /* Obstack used to write out a type definition. */ 556 /* Obstack used to write out a type definition. */
468 struct obstack type_obstack; 557 struct obstack type_obstack;
469 }; 558 };
470 559
474 go_append_string (struct obstack *ob, tree id) 563 go_append_string (struct obstack *ob, tree id)
475 { 564 {
476 obstack_grow (ob, IDENTIFIER_POINTER (id), IDENTIFIER_LENGTH (id)); 565 obstack_grow (ob, IDENTIFIER_POINTER (id), IDENTIFIER_LENGTH (id));
477 } 566 }
478 567
568 /* Given an integer PRECISION in bits, returns a constant string that is the
569 matching go int or uint type (depending on the IS_UNSIGNED flag). Returns a
570 NULL pointer if there is no matching go type. */
571
572 static const char *
573 go_get_uinttype_for_precision (unsigned int precision, bool is_unsigned)
574 {
575 switch (precision)
576 {
577 case 8:
578 return is_unsigned ? "uint8" : "int8";
579 case 16:
580 return is_unsigned ? "uint16" : "int16";
581 case 32:
582 return is_unsigned ? "uint32" : "int32";
583 case 64:
584 return is_unsigned ? "uint64" : "int64";
585 default:
586 return NULL;
587 }
588 }
589
590 /* Append an artificial variable name with the suffix _INDEX to OB. Returns
591 INDEX + 1. */
592
593 static unsigned int
594 go_append_artificial_name (struct obstack *ob, unsigned int index)
595 {
596 char buf[100];
597
598 /* FIXME: identifier may not be unique. */
599 obstack_grow (ob, "Godump_", 7);
600 snprintf (buf, sizeof buf, "%u", index);
601 obstack_grow (ob, buf, strlen (buf));
602
603 return index + 1;
604 }
605
606 /* Append the variable name from DECL to OB. If the name is in the
607 KEYWORD_HASH, prepend an '_'. */
608
609 static void
610 go_append_decl_name (struct obstack *ob, tree decl, htab_t keyword_hash)
611 {
612 const char *var_name;
613 void **slot;
614
615 /* Start variable name with an underscore if a keyword. */
616 var_name = IDENTIFIER_POINTER (DECL_NAME (decl));
617 slot = htab_find_slot (keyword_hash, var_name, NO_INSERT);
618 if (slot != NULL)
619 obstack_1grow (ob, '_');
620 go_append_string (ob, DECL_NAME (decl));
621 }
622
623 /* Appends a byte array with the necessary number of elements and the name
624 "Godump_INDEX_pad" to pad from FROM_OFFSET to TO_OFFSET to OB assuming that
625 the next field is automatically aligned to ALIGN_UNITS. Returns INDEX + 1,
626 or INDEX if no padding had to be appended. The resulting offset where the
627 next field is allocated is returned through RET_OFFSET. */
628
629 static unsigned int
630 go_append_padding (struct obstack *ob, unsigned int from_offset,
631 unsigned int to_offset, unsigned int align_units,
632 unsigned int index, unsigned int *ret_offset)
633 {
634 if (from_offset % align_units > 0)
635 from_offset += align_units - (from_offset % align_units);
636 gcc_assert (to_offset >= from_offset);
637 if (to_offset > from_offset)
638 {
639 char buf[100];
640
641 index = go_append_artificial_name (ob, index);
642 snprintf (buf, sizeof buf, "_pad [%u]byte; ", to_offset - from_offset);
643 obstack_grow (ob, buf, strlen (buf));
644 }
645 *ret_offset = to_offset;
646
647 return index;
648 }
649
650 /* Appends an array of type TYPE_STRING with zero elements and the name
651 "Godump_INDEX_align" to OB. If TYPE_STRING is a null pointer, ERROR_STRING
652 is appended instead of the type. Returns INDEX + 1. */
653
654 static unsigned int
655 go_force_record_alignment (struct obstack *ob, const char *type_string,
656 unsigned int index, const char *error_string)
657 {
658 index = go_append_artificial_name (ob, index);
659 obstack_grow (ob, "_align ", 7);
660 if (type_string == NULL)
661 obstack_grow (ob, error_string, strlen (error_string));
662 else
663 {
664 obstack_grow (ob, "[0]", 3);
665 obstack_grow (ob, type_string, strlen (type_string));
666 }
667 obstack_grow (ob, "; ", 2);
668
669 return index;
670 }
671
479 /* Write the Go version of TYPE to CONTAINER->TYPE_OBSTACK. 672 /* Write the Go version of TYPE to CONTAINER->TYPE_OBSTACK.
480 USE_TYPE_NAME is true if we can simply use a type name here without 673 USE_TYPE_NAME is true if we can simply use a type name here without
481 needing to define it. IS_FUNC_OK is true if we can output a func 674 needing to define it. IS_FUNC_OK is true if we can output a func
482 type here; the "func" keyword will already have been added. Return 675 type here; the "func" keyword will already have been added.
483 true if the type can be represented in Go, false otherwise. */ 676 Return true if the type can be represented in Go, false otherwise.
677 P_ART_I is used for indexing artificial elements in nested structures and
678 should always be a NULL pointer when called, except by certain recursive
679 calls from go_format_type() itself. */
484 680
485 static bool 681 static bool
486 go_format_type (struct godump_container *container, tree type, 682 go_format_type (struct godump_container *container, tree type,
487 bool use_type_name, bool is_func_ok) 683 bool use_type_name, bool is_func_ok, unsigned int *p_art_i,
684 bool is_anon_record_or_union)
488 { 685 {
489 bool ret; 686 bool ret;
490 struct obstack *ob; 687 struct obstack *ob;
491 688 unsigned int art_i_dummy;
689 bool is_union = false;
690
691 if (p_art_i == NULL)
692 {
693 art_i_dummy = 0;
694 p_art_i = &art_i_dummy;
695 }
492 ret = true; 696 ret = true;
493 ob = &container->type_obstack; 697 ob = &container->type_obstack;
494 698
495 if (TYPE_NAME (type) != NULL_TREE 699 if (TYPE_NAME (type) != NULL_TREE
496 && (pointer_set_contains (container->decls_seen, type) 700 && (container->decls_seen.contains (type)
497 || pointer_set_contains (container->decls_seen, TYPE_NAME (type))) 701 || container->decls_seen.contains (TYPE_NAME (type)))
498 && (AGGREGATE_TYPE_P (type) 702 && (AGGREGATE_TYPE_P (type)
499 || POINTER_TYPE_P (type) 703 || POINTER_TYPE_P (type)
500 || TREE_CODE (type) == FUNCTION_TYPE)) 704 || TREE_CODE (type) == FUNCTION_TYPE))
501 { 705 {
502 tree name; 706 tree name;
503 707 void **slot;
504 name = TYPE_NAME (type); 708
505 if (TREE_CODE (name) == IDENTIFIER_NODE) 709 name = TYPE_IDENTIFIER (type);
506 { 710
507 obstack_1grow (ob, '_'); 711 slot = htab_find_slot (container->invalid_hash, IDENTIFIER_POINTER (name),
508 go_append_string (ob, name); 712 NO_INSERT);
509 return ret; 713 if (slot != NULL)
510 } 714 ret = false;
511 else if (TREE_CODE (name) == TYPE_DECL) 715
512 { 716 obstack_1grow (ob, '_');
513 obstack_1grow (ob, '_'); 717 go_append_string (ob, name);
514 go_append_string (ob, DECL_NAME (name)); 718 return ret;
515 return ret; 719 }
516 } 720
517 } 721 container->decls_seen.add (type);
518
519 pointer_set_insert (container->decls_seen, type);
520 722
521 switch (TREE_CODE (type)) 723 switch (TREE_CODE (type))
522 { 724 {
725 case TYPE_DECL:
726 {
727 void **slot;
728
729 slot = htab_find_slot (container->invalid_hash,
730 IDENTIFIER_POINTER (DECL_NAME (type)),
731 NO_INSERT);
732 if (slot != NULL)
733 ret = false;
734
735 obstack_1grow (ob, '_');
736 go_append_string (ob, DECL_NAME (type));
737 }
738 break;
739
523 case ENUMERAL_TYPE: 740 case ENUMERAL_TYPE:
524 obstack_grow (ob, "int", 3);
525 break;
526
527 case TYPE_DECL:
528 obstack_1grow (ob, '_');
529 go_append_string (ob, DECL_NAME (type));
530 break;
531
532 case INTEGER_TYPE: 741 case INTEGER_TYPE:
533 { 742 {
534 const char *s; 743 const char *s;
535 char buf[100]; 744 char buf[100];
536 745
537 switch (TYPE_PRECISION (type)) 746 s = go_get_uinttype_for_precision (TYPE_PRECISION (type),
747 TYPE_UNSIGNED (type));
748 if (s == NULL)
538 { 749 {
539 case 8:
540 s = TYPE_UNSIGNED (type) ? "uint8" : "int8";
541 break;
542 case 16:
543 s = TYPE_UNSIGNED (type) ? "uint16" : "int16";
544 break;
545 case 32:
546 s = TYPE_UNSIGNED (type) ? "uint32" : "int32";
547 break;
548 case 64:
549 s = TYPE_UNSIGNED (type) ? "uint64" : "int64";
550 break;
551 default:
552 snprintf (buf, sizeof buf, "INVALID-int-%u%s", 750 snprintf (buf, sizeof buf, "INVALID-int-%u%s",
553 TYPE_PRECISION (type), 751 TYPE_PRECISION (type),
554 TYPE_UNSIGNED (type) ? "u" : ""); 752 TYPE_UNSIGNED (type) ? "u" : "");
555 s = buf; 753 s = buf;
556 ret = false; 754 ret = false;
557 break;
558 } 755 }
559 obstack_grow (ob, s, strlen (s)); 756 obstack_grow (ob, s, strlen (s));
560 } 757 }
561 break; 758 break;
562 759
582 } 779 }
583 obstack_grow (ob, s, strlen (s)); 780 obstack_grow (ob, s, strlen (s));
584 } 781 }
585 break; 782 break;
586 783
784 case COMPLEX_TYPE:
785 {
786 const char *s;
787 char buf[100];
788 tree real_type;
789
790 real_type = TREE_TYPE (type);
791 if (TREE_CODE (real_type) == REAL_TYPE)
792 {
793 switch (TYPE_PRECISION (real_type))
794 {
795 case 32:
796 s = "complex64";
797 break;
798 case 64:
799 s = "complex128";
800 break;
801 default:
802 snprintf (buf, sizeof buf, "INVALID-complex-%u",
803 2 * TYPE_PRECISION (real_type));
804 s = buf;
805 ret = false;
806 break;
807 }
808 }
809 else
810 {
811 s = "INVALID-complex-non-real";
812 ret = false;
813 }
814 obstack_grow (ob, s, strlen (s));
815 }
816 break;
817
587 case BOOLEAN_TYPE: 818 case BOOLEAN_TYPE:
588 obstack_grow (ob, "bool", 4); 819 obstack_grow (ob, "bool", 4);
589 break; 820 break;
590 821
591 case POINTER_TYPE: 822 case POINTER_TYPE:
595 || (POINTER_TYPE_P (TREE_TYPE (type)) 826 || (POINTER_TYPE_P (TREE_TYPE (type))
596 && (TREE_CODE (TREE_TYPE (TREE_TYPE (type))) 827 && (TREE_CODE (TREE_TYPE (TREE_TYPE (type)))
597 == FUNCTION_TYPE)))) 828 == FUNCTION_TYPE))))
598 { 829 {
599 tree name; 830 tree name;
600 831 void **slot;
601 name = TYPE_NAME (TREE_TYPE (type)); 832
602 if (TREE_CODE (name) == IDENTIFIER_NODE) 833 name = TYPE_IDENTIFIER (TREE_TYPE (type));
603 { 834
604 obstack_grow (ob, "*_", 2); 835 slot = htab_find_slot (container->invalid_hash,
605 go_append_string (ob, name); 836 IDENTIFIER_POINTER (name), NO_INSERT);
606 837 if (slot != NULL)
607 /* The pointer here can be used without the struct or 838 ret = false;
608 union definition. So this struct or union is a a 839
609 potential dummy type. */ 840 obstack_grow (ob, "*_", 2);
610 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (type))) 841 go_append_string (ob, name);
611 pointer_set_insert (container->pot_dummy_types, 842
612 IDENTIFIER_POINTER (name)); 843 /* The pointer here can be used without the struct or union
613 844 definition. So this struct or union is a potential dummy
614 return ret; 845 type. */
615 } 846 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (type)))
616 else if (TREE_CODE (name) == TYPE_DECL) 847 container->pot_dummy_types.add (IDENTIFIER_POINTER (name));
617 { 848
618 obstack_grow (ob, "*_", 2); 849 return ret;
619 go_append_string (ob, DECL_NAME (name));
620 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (type)))
621 pointer_set_insert (container->pot_dummy_types,
622 IDENTIFIER_POINTER (DECL_NAME (name)));
623 return ret;
624 }
625 } 850 }
626 if (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE) 851 if (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
627 obstack_grow (ob, "func", 4); 852 obstack_grow (ob, "func", 4);
628 else 853 else
629 obstack_1grow (ob, '*'); 854 obstack_1grow (ob, '*');
630 if (VOID_TYPE_P (TREE_TYPE (type))) 855 if (VOID_TYPE_P (TREE_TYPE (type)))
631 obstack_grow (ob, "byte", 4); 856 obstack_grow (ob, "byte", 4);
632 else 857 else
633 { 858 {
634 if (!go_format_type (container, TREE_TYPE (type), use_type_name, 859 if (!go_format_type (container, TREE_TYPE (type), use_type_name,
635 true)) 860 true, NULL, false))
636 ret = false; 861 ret = false;
637 } 862 }
638 break; 863 break;
639 864
640 case ARRAY_TYPE: 865 case ARRAY_TYPE:
644 && TYPE_MIN_VALUE (TYPE_DOMAIN (type)) != NULL_TREE 869 && TYPE_MIN_VALUE (TYPE_DOMAIN (type)) != NULL_TREE
645 && TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (type))) == INTEGER_CST 870 && TREE_CODE (TYPE_MIN_VALUE (TYPE_DOMAIN (type))) == INTEGER_CST
646 && tree_int_cst_sgn (TYPE_MIN_VALUE (TYPE_DOMAIN (type))) == 0 871 && tree_int_cst_sgn (TYPE_MIN_VALUE (TYPE_DOMAIN (type))) == 0
647 && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) != NULL_TREE 872 && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) != NULL_TREE
648 && TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) == INTEGER_CST 873 && TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) == INTEGER_CST
649 && host_integerp (TYPE_MAX_VALUE (TYPE_DOMAIN (type)), 0)) 874 && tree_fits_shwi_p (TYPE_MAX_VALUE (TYPE_DOMAIN (type))))
650 { 875 {
651 char buf[100]; 876 char buf[100];
652 877
653 snprintf (buf, sizeof buf, HOST_WIDE_INT_PRINT_DEC "+1", 878 snprintf (buf, sizeof buf, HOST_WIDE_INT_PRINT_DEC "+1",
654 tree_low_cst (TYPE_MAX_VALUE (TYPE_DOMAIN (type)), 0)); 879 tree_to_shwi (TYPE_MAX_VALUE (TYPE_DOMAIN (type))));
655 obstack_grow (ob, buf, strlen (buf)); 880 obstack_grow (ob, buf, strlen (buf));
656 } 881 }
882 else
883 obstack_1grow (ob, '0');
657 obstack_1grow (ob, ']'); 884 obstack_1grow (ob, ']');
658 if (!go_format_type (container, TREE_TYPE (type), use_type_name, false)) 885 if (!go_format_type (container, TREE_TYPE (type), use_type_name, false,
886 NULL, false))
659 ret = false; 887 ret = false;
660 break; 888 break;
661 889
662 case UNION_TYPE: 890 case UNION_TYPE:
891 is_union = true;
892 /* Fall through to RECORD_TYPE case. */
893 gcc_fallthrough ();
663 case RECORD_TYPE: 894 case RECORD_TYPE:
664 { 895 {
896 unsigned int prev_field_end;
897 unsigned int known_alignment;
665 tree field; 898 tree field;
666 int i; 899 bool emitted_a_field;
667 900
668 obstack_grow (ob, "struct { ", 9); 901 /* FIXME: Why is this necessary? Without it we can get a core
669 i = 0; 902 dump on the s390x headers, or from a file containing simply
670 for (field = TYPE_FIELDS (type); 903 "typedef struct S T;". */
904 layout_type (type);
905
906 prev_field_end = 0;
907 known_alignment = 1;
908 /* Anonymous records and unions are flattened, i.e. they are not put
909 into "struct { ... }". */
910 if (!is_anon_record_or_union)
911 obstack_grow (ob, "struct { ", 9);
912 for (field = TYPE_FIELDS (type), emitted_a_field = false;
671 field != NULL_TREE; 913 field != NULL_TREE;
672 field = TREE_CHAIN (field)) 914 field = TREE_CHAIN (field))
673 { 915 {
674 if (DECL_NAME (field) == NULL) 916 if (TREE_CODE (field) != FIELD_DECL)
917 continue;
918 if (DECL_BIT_FIELD (field))
919 /* Bit fields are replaced by padding. */
920 continue;
921 /* Only the first non-bitfield field is emitted for unions. */
922 if (!is_union || !emitted_a_field)
675 { 923 {
676 char buf[100]; 924 /* Emit the field. */
677 925 bool field_ok;
678 obstack_grow (ob, "_f", 2); 926 bool is_anon_substructure;
679 snprintf (buf, sizeof buf, "%d", i); 927 unsigned int decl_align_unit;
680 obstack_grow (ob, buf, strlen (buf)); 928 unsigned int decl_offset;
681 i++; 929
682 } 930 field_ok = true;
683 else 931 emitted_a_field = true;
684 { 932 is_anon_substructure =
685 const char *var_name; 933 (DECL_NAME (field) == NULL
686 void **slot; 934 && (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE
687 935 || TREE_CODE (TREE_TYPE (field)) == UNION_TYPE));
688 /* Start variable name with an underscore if a keyword. */ 936 /* Keep track of the alignment of named substructures, either
689 var_name = IDENTIFIER_POINTER (DECL_NAME (field)); 937 of the whole record, or the alignment of the emitted field
690 slot = htab_find_slot (container->keyword_hash, var_name, 938 (for unions). */
691 NO_INSERT); 939 decl_align_unit = DECL_ALIGN_UNIT (field);
692 if (slot != NULL) 940 if (!is_anon_substructure && decl_align_unit > known_alignment)
693 obstack_1grow (ob, '_'); 941 known_alignment = decl_align_unit;
694 go_append_string (ob, DECL_NAME (field)); 942 /* Pad to start of field. */
695 } 943 decl_offset =
696 obstack_1grow (ob, ' '); 944 TREE_INT_CST_LOW (DECL_FIELD_OFFSET (field))
697 if (DECL_BIT_FIELD (field)) 945 + precision_to_units
698 { 946 (TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (field)));
699 obstack_grow (ob, "INVALID-bit-field", 17); 947 {
700 ret = false; 948 unsigned int align_unit;
701 } 949
702 else 950 /* For anonymous records and unions there is no automatic
703 { 951 structure alignment, so use 1 as the alignment. */
704 /* Do not expand type if a record or union type or a 952 align_unit = (is_anon_substructure) ? 1 : decl_align_unit;
705 function pointer. */ 953 *p_art_i = go_append_padding
954 (ob, prev_field_end, decl_offset, align_unit, *p_art_i,
955 &prev_field_end);
956 }
957 if (DECL_SIZE_UNIT (field))
958 prev_field_end +=
959 TREE_INT_CST_LOW (DECL_SIZE_UNIT (field));
960 /* Emit the field name, but not for anonymous records and
961 unions. */
962 if (!is_anon_substructure)
963 {
964 if ((DECL_NAME (field) == NULL))
965 *p_art_i = go_append_artificial_name (ob, *p_art_i);
966 else
967 go_append_decl_name
968 (ob, field, container->keyword_hash);
969 obstack_1grow (ob, ' ');
970 }
971 /* Do not expand type if a record or union type or a function
972 pointer. */
706 if (TYPE_NAME (TREE_TYPE (field)) != NULL_TREE 973 if (TYPE_NAME (TREE_TYPE (field)) != NULL_TREE
707 && (RECORD_OR_UNION_TYPE_P (TREE_TYPE (field)) 974 && (RECORD_OR_UNION_TYPE_P (TREE_TYPE (field))
708 || (POINTER_TYPE_P (TREE_TYPE (field)) 975 || (POINTER_TYPE_P (TREE_TYPE (field))
709 && (TREE_CODE (TREE_TYPE (TREE_TYPE (field))) 976 && (TREE_CODE (TREE_TYPE (TREE_TYPE (field)))
710 == FUNCTION_TYPE)))) 977 == FUNCTION_TYPE))))
711 { 978 {
712 tree name = TYPE_NAME (TREE_TYPE (field)); 979 tree name;
713 if (TREE_CODE (name) == IDENTIFIER_NODE) 980 void **slot;
714 { 981
715 obstack_1grow (ob, '_'); 982 name = TYPE_IDENTIFIER (TREE_TYPE (field));
716 go_append_string (ob, name); 983
717 } 984 slot = htab_find_slot (container->invalid_hash,
718 else if (TREE_CODE (name) == TYPE_DECL) 985 IDENTIFIER_POINTER (name),
719 { 986 NO_INSERT);
720 obstack_1grow (ob, '_'); 987 if (slot != NULL)
721 go_append_string (ob, DECL_NAME (name)); 988 field_ok = false;
722 } 989
990 obstack_1grow (ob, '_');
991 go_append_string (ob, name);
723 } 992 }
724 else 993 else
725 { 994 {
726 if (!go_format_type (container, TREE_TYPE (field), true, 995 if (!go_format_type (container, TREE_TYPE (field), true,
727 false)) 996 false, p_art_i, is_anon_substructure))
728 ret = false; 997 field_ok = false;
729 } 998 }
730 } 999 if (!is_anon_substructure)
731 obstack_grow (ob, "; ", 2); 1000 obstack_grow (ob, "; ", 2);
732 1001 if (!field_ok)
733 /* Only output the first field of a union, and hope for 1002 ret = false;
734 the best. */ 1003 }
735 if (TREE_CODE (type) == UNION_TYPE)
736 break;
737 } 1004 }
738 obstack_1grow (ob, '}'); 1005 /* Padding. */
1006 *p_art_i = go_append_padding (ob, prev_field_end,
1007 TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type)),
1008 1, *p_art_i, &prev_field_end);
1009 /* Alignment. */
1010 if (!is_anon_record_or_union
1011 && known_alignment < TYPE_ALIGN_UNIT (type))
1012 {
1013 const char *s;
1014 char buf[100];
1015
1016 /* Enforce proper record alignment. */
1017 s = go_get_uinttype_for_precision
1018 (TYPE_ALIGN (type), TYPE_UNSIGNED (type));
1019 if (s == NULL)
1020 {
1021 snprintf (buf, sizeof buf, "INVALID-int-%u%s",
1022 TYPE_ALIGN (type), TYPE_UNSIGNED (type) ? "u" : "");
1023 s = buf;
1024 ret = false;
1025 }
1026 *p_art_i = go_force_record_alignment (ob, s, *p_art_i, buf);
1027 }
1028 if (!is_anon_record_or_union)
1029 obstack_1grow (ob, '}');
739 } 1030 }
740 break; 1031 break;
741 1032
742 case FUNCTION_TYPE: 1033 case FUNCTION_TYPE:
743 { 1034 {
744 tree args; 1035 tree arg_type;
745 bool is_varargs; 1036 bool is_varargs;
746 tree result; 1037 tree result;
1038 function_args_iterator iter;
1039 bool seen_arg;
747 1040
748 /* Go has no way to write a type which is a function but not a 1041 /* Go has no way to write a type which is a function but not a
749 pointer to a function. */ 1042 pointer to a function. */
750 if (!is_func_ok) 1043 if (!is_func_ok)
751 { 1044 {
752 obstack_grow (ob, "func*", 5); 1045 obstack_grow (ob, "func*", 5);
753 ret = false; 1046 ret = false;
754 } 1047 }
755 1048
756 obstack_1grow (ob, '('); 1049 obstack_1grow (ob, '(');
757 is_varargs = true; 1050 is_varargs = stdarg_p (type);
758 for (args = TYPE_ARG_TYPES (type); 1051 seen_arg = false;
759 args != NULL_TREE; 1052 FOREACH_FUNCTION_ARGS (type, arg_type, iter)
760 args = TREE_CHAIN (args))
761 { 1053 {
762 if (VOID_TYPE_P (TREE_VALUE (args))) 1054 if (VOID_TYPE_P (arg_type))
763 { 1055 break;
764 gcc_assert (TREE_CHAIN (args) == NULL); 1056 if (seen_arg)
765 is_varargs = false;
766 break;
767 }
768 if (args != TYPE_ARG_TYPES (type))
769 obstack_grow (ob, ", ", 2); 1057 obstack_grow (ob, ", ", 2);
770 if (!go_format_type (container, TREE_VALUE (args), true, false)) 1058 if (!go_format_type (container, arg_type, true, false, NULL, false))
771 ret = false; 1059 ret = false;
1060 seen_arg = true;
772 } 1061 }
773 if (is_varargs) 1062 if (is_varargs)
774 { 1063 {
775 if (TYPE_ARG_TYPES (type) != NULL_TREE) 1064 if (prototype_p (type))
776 obstack_grow (ob, ", ", 2); 1065 obstack_grow (ob, ", ", 2);
777 obstack_grow (ob, "...interface{}", 14); 1066 obstack_grow (ob, "...interface{}", 14);
778 } 1067 }
779 obstack_1grow (ob, ')'); 1068 obstack_1grow (ob, ')');
780 1069
781 result = TREE_TYPE (type); 1070 result = TREE_TYPE (type);
782 if (!VOID_TYPE_P (result)) 1071 if (!VOID_TYPE_P (result))
783 { 1072 {
784 obstack_1grow (ob, ' '); 1073 obstack_1grow (ob, ' ');
785 if (!go_format_type (container, result, use_type_name, false)) 1074 if (!go_format_type (container, result, use_type_name, false, NULL,
1075 false))
786 ret = false; 1076 ret = false;
787 } 1077 }
788 } 1078 }
789 break; 1079 break;
790 1080
805 { 1095 {
806 struct obstack *ob; 1096 struct obstack *ob;
807 1097
808 ob = &container->type_obstack; 1098 ob = &container->type_obstack;
809 obstack_1grow (ob, '\0'); 1099 obstack_1grow (ob, '\0');
810 fputs (obstack_base (ob), go_dump_file); 1100 fputs ((char *) obstack_base (ob), go_dump_file);
811 obstack_free (ob, obstack_base (ob)); 1101 obstack_free (ob, obstack_base (ob));
812 } 1102 }
813 1103
814 /* Output a function declaration. */ 1104 /* Output a function declaration. */
815 1105
816 static void 1106 static void
817 go_output_fndecl (struct godump_container *container, tree decl) 1107 go_output_fndecl (struct godump_container *container, tree decl)
818 { 1108 {
819 if (!go_format_type (container, TREE_TYPE (decl), false, true)) 1109 if (!go_format_type (container, TREE_TYPE (decl), false, true, NULL, false))
820 fprintf (go_dump_file, "// "); 1110 fprintf (go_dump_file, "// ");
821 fprintf (go_dump_file, "func _%s ", 1111 fprintf (go_dump_file, "func _%s ",
822 IDENTIFIER_POINTER (DECL_NAME (decl))); 1112 IDENTIFIER_POINTER (DECL_NAME (decl)));
823 go_output_type (container); 1113 go_output_type (container);
824 fprintf (go_dump_file, " __asm__(\"%s\")\n", 1114 fprintf (go_dump_file, " __asm__(\"%s\")\n",
832 { 1122 {
833 /* If we have an enum type, output the enum constants 1123 /* If we have an enum type, output the enum constants
834 separately. */ 1124 separately. */
835 if (TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE 1125 if (TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE
836 && TYPE_SIZE (TREE_TYPE (decl)) != 0 1126 && TYPE_SIZE (TREE_TYPE (decl)) != 0
837 && !pointer_set_contains (container->decls_seen, TREE_TYPE (decl)) 1127 && !container->decls_seen.contains (TREE_TYPE (decl))
838 && (TYPE_CANONICAL (TREE_TYPE (decl)) == NULL_TREE 1128 && (TYPE_CANONICAL (TREE_TYPE (decl)) == NULL_TREE
839 || !pointer_set_contains (container->decls_seen, 1129 || !container->decls_seen.contains
840 TYPE_CANONICAL (TREE_TYPE (decl))))) 1130 (TYPE_CANONICAL (TREE_TYPE (decl)))))
841 { 1131 {
842 tree element; 1132 tree element;
843 1133
844 for (element = TYPE_VALUES (TREE_TYPE (decl)); 1134 for (element = TYPE_VALUES (TREE_TYPE (decl));
845 element != NULL_TREE; 1135 element != NULL_TREE;
846 element = TREE_CHAIN (element)) 1136 element = TREE_CHAIN (element))
847 fprintf (go_dump_file, "const _%s = " HOST_WIDE_INT_PRINT_DEC "\n", 1137 {
848 IDENTIFIER_POINTER (TREE_PURPOSE (element)), 1138 const char *name;
849 tree_low_cst (TREE_VALUE (element), 0)); 1139 struct macro_hash_value *mhval;
850 pointer_set_insert (container->decls_seen, TREE_TYPE (decl)); 1140 void **slot;
1141 char buf[WIDE_INT_PRINT_BUFFER_SIZE];
1142
1143 name = IDENTIFIER_POINTER (TREE_PURPOSE (element));
1144
1145 /* Sometimes a name will be defined as both an enum constant
1146 and a macro. Avoid duplicate definition errors by
1147 treating enum constants as macros. */
1148 mhval = XNEW (struct macro_hash_value);
1149 mhval->name = xstrdup (name);
1150 mhval->value = NULL;
1151 slot = htab_find_slot (macro_hash, mhval, INSERT);
1152 if (*slot != NULL)
1153 macro_hash_del (*slot);
1154
1155 if (tree_fits_shwi_p (TREE_VALUE (element)))
1156 snprintf (buf, sizeof buf, HOST_WIDE_INT_PRINT_DEC,
1157 tree_to_shwi (TREE_VALUE (element)));
1158 else if (tree_fits_uhwi_p (TREE_VALUE (element)))
1159 snprintf (buf, sizeof buf, HOST_WIDE_INT_PRINT_UNSIGNED,
1160 tree_to_uhwi (TREE_VALUE (element)));
1161 else
1162 print_hex (wi::to_wide (element), buf);
1163
1164 mhval->value = xstrdup (buf);
1165 *slot = mhval;
1166 }
1167 container->decls_seen.add (TREE_TYPE (decl));
851 if (TYPE_CANONICAL (TREE_TYPE (decl)) != NULL_TREE) 1168 if (TYPE_CANONICAL (TREE_TYPE (decl)) != NULL_TREE)
852 pointer_set_insert (container->decls_seen, 1169 container->decls_seen.add (TYPE_CANONICAL (TREE_TYPE (decl)));
853 TYPE_CANONICAL (TREE_TYPE (decl)));
854 } 1170 }
855 1171
856 if (DECL_NAME (decl) != NULL_TREE) 1172 if (DECL_NAME (decl) != NULL_TREE)
857 { 1173 {
858 void **slot; 1174 void **slot;
863 slot = htab_find_slot (container->type_hash, type, INSERT); 1179 slot = htab_find_slot (container->type_hash, type, INSERT);
864 if (*slot != NULL) 1180 if (*slot != NULL)
865 return; 1181 return;
866 *slot = CONST_CAST (void *, (const void *) type); 1182 *slot = CONST_CAST (void *, (const void *) type);
867 1183
868 if (!go_format_type (container, TREE_TYPE (decl), false, false)) 1184 if (!go_format_type (container, TREE_TYPE (decl), false, false, NULL,
869 fprintf (go_dump_file, "// "); 1185 false))
1186 {
1187 fprintf (go_dump_file, "// ");
1188 slot = htab_find_slot (container->invalid_hash, type, INSERT);
1189 *slot = CONST_CAST (void *, (const void *) type);
1190 }
870 fprintf (go_dump_file, "type _%s ", 1191 fprintf (go_dump_file, "type _%s ",
871 IDENTIFIER_POINTER (DECL_NAME (decl))); 1192 IDENTIFIER_POINTER (DECL_NAME (decl)));
872 go_output_type (container); 1193 go_output_type (container);
873 pointer_set_insert (container->decls_seen, decl); 1194
1195 if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl)))
1196 {
1197 HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
1198
1199 if (size > 0)
1200 fprintf (go_dump_file,
1201 "\nconst _sizeof_%s = " HOST_WIDE_INT_PRINT_DEC,
1202 IDENTIFIER_POINTER (DECL_NAME (decl)),
1203 size);
1204 }
1205
1206 container->decls_seen.add (decl);
874 } 1207 }
875 else if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl))) 1208 else if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl)))
876 { 1209 {
877 void **slot; 1210 void **slot;
878 const char *type; 1211 const char *type;
1212 HOST_WIDE_INT size;
879 1213
880 type = IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE ((decl)))); 1214 type = IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE ((decl))));
881 /* If type defined already, skip. */ 1215 /* If type defined already, skip. */
882 slot = htab_find_slot (container->type_hash, type, INSERT); 1216 slot = htab_find_slot (container->type_hash, type, INSERT);
883 if (*slot != NULL) 1217 if (*slot != NULL)
884 return; 1218 return;
885 *slot = CONST_CAST (void *, (const void *) type); 1219 *slot = CONST_CAST (void *, (const void *) type);
886 1220
887 if (!go_format_type (container, TREE_TYPE (decl), false, false)) 1221 if (!go_format_type (container, TREE_TYPE (decl), false, false, NULL,
888 fprintf (go_dump_file, "// "); 1222 false))
1223 {
1224 fprintf (go_dump_file, "// ");
1225 slot = htab_find_slot (container->invalid_hash, type, INSERT);
1226 *slot = CONST_CAST (void *, (const void *) type);
1227 }
889 fprintf (go_dump_file, "type _%s ", 1228 fprintf (go_dump_file, "type _%s ",
890 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (decl)))); 1229 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (decl))));
891 go_output_type (container); 1230 go_output_type (container);
1231
1232 size = int_size_in_bytes (TREE_TYPE (decl));
1233 if (size > 0)
1234 fprintf (go_dump_file,
1235 "\nconst _sizeof_%s = " HOST_WIDE_INT_PRINT_DEC,
1236 IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (decl))),
1237 size);
892 } 1238 }
893 else 1239 else
894 return; 1240 return;
895 1241
896 fprintf (go_dump_file, "\n"); 1242 fprintf (go_dump_file, "\n");
900 1246
901 static void 1247 static void
902 go_output_var (struct godump_container *container, tree decl) 1248 go_output_var (struct godump_container *container, tree decl)
903 { 1249 {
904 bool is_valid; 1250 bool is_valid;
905 1251 tree type_name;
906 if (pointer_set_contains (container->decls_seen, decl) 1252 tree id;
907 || pointer_set_contains (container->decls_seen, DECL_NAME (decl))) 1253
1254 if (container->decls_seen.contains (decl)
1255 || container->decls_seen.contains (DECL_NAME (decl)))
908 return; 1256 return;
909 pointer_set_insert (container->decls_seen, decl); 1257 container->decls_seen.add (decl);
910 pointer_set_insert (container->decls_seen, DECL_NAME (decl)); 1258 container->decls_seen.add (DECL_NAME (decl));
911 1259
912 is_valid = go_format_type (container, TREE_TYPE (decl), true, false); 1260 type_name = TYPE_NAME (TREE_TYPE (decl));
1261 id = NULL_TREE;
1262 if (type_name != NULL_TREE && TREE_CODE (type_name) == IDENTIFIER_NODE)
1263 id = type_name;
1264 else if (type_name != NULL_TREE && TREE_CODE (type_name) == TYPE_DECL
1265 && DECL_SOURCE_LOCATION (type_name) != BUILTINS_LOCATION
1266 && DECL_NAME (type_name))
1267 id = DECL_NAME (type_name);
1268 if (id != NULL_TREE
1269 && (!htab_find_slot (container->type_hash, IDENTIFIER_POINTER (id),
1270 NO_INSERT)
1271 || htab_find_slot (container->invalid_hash, IDENTIFIER_POINTER (id),
1272 NO_INSERT)))
1273 id = NULL_TREE;
1274 if (id != NULL_TREE)
1275 {
1276 struct obstack *ob;
1277
1278 ob = &container->type_obstack;
1279 obstack_1grow (ob, '_');
1280 go_append_string (ob, id);
1281 is_valid = htab_find_slot (container->type_hash, IDENTIFIER_POINTER (id),
1282 NO_INSERT) != NULL;
1283 }
1284 else
1285 is_valid = go_format_type (container, TREE_TYPE (decl), true, false, NULL,
1286 false);
913 if (is_valid 1287 if (is_valid
914 && htab_find_slot (container->type_hash, 1288 && htab_find_slot (container->type_hash,
915 IDENTIFIER_POINTER (DECL_NAME (decl)), 1289 IDENTIFIER_POINTER (DECL_NAME (decl)),
916 NO_INSERT) != NULL) 1290 NO_INSERT) != NULL)
917 { 1291 {
927 go_output_type (container); 1301 go_output_type (container);
928 fprintf (go_dump_file, "\n"); 1302 fprintf (go_dump_file, "\n");
929 1303
930 /* Sometimes an extern variable is declared with an unknown struct 1304 /* Sometimes an extern variable is declared with an unknown struct
931 type. */ 1305 type. */
932 if (TYPE_NAME (TREE_TYPE (decl)) != NULL_TREE 1306 if (type_name != NULL_TREE && RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl)))
933 && RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl))) 1307 {
934 {
935 tree type_name = TYPE_NAME (TREE_TYPE (decl));
936 if (TREE_CODE (type_name) == IDENTIFIER_NODE) 1308 if (TREE_CODE (type_name) == IDENTIFIER_NODE)
937 pointer_set_insert (container->pot_dummy_types, 1309 container->pot_dummy_types.add (IDENTIFIER_POINTER (type_name));
938 IDENTIFIER_POINTER (type_name));
939 else if (TREE_CODE (type_name) == TYPE_DECL) 1310 else if (TREE_CODE (type_name) == TYPE_DECL)
940 pointer_set_insert (container->pot_dummy_types, 1311 container->pot_dummy_types.add
941 IDENTIFIER_POINTER (DECL_NAME (type_name))); 1312 (IDENTIFIER_POINTER (DECL_NAME (type_name)));
942 } 1313 }
1314 }
1315
1316 /* Output the final value of a preprocessor macro or enum constant.
1317 This is called via htab_traverse_noresize. */
1318
1319 static int
1320 go_print_macro (void **slot, void *arg ATTRIBUTE_UNUSED)
1321 {
1322 struct macro_hash_value *mhval = (struct macro_hash_value *) *slot;
1323 fprintf (go_dump_file, "const _%s = %s\n", mhval->name, mhval->value);
1324 return 1;
943 } 1325 }
944 1326
945 /* Build a hash table with the Go keywords. */ 1327 /* Build a hash table with the Go keywords. */
946 1328
947 static const char * const keywords[] = { 1329 static const char * const keywords[] = {
965 } 1347 }
966 } 1348 }
967 1349
968 /* Traversing the pot_dummy_types and seeing which types are present 1350 /* Traversing the pot_dummy_types and seeing which types are present
969 in the global types hash table and creating dummy definitions if 1351 in the global types hash table and creating dummy definitions if
970 not found. This function is invoked by pointer_set_traverse. */ 1352 not found. This function is invoked by hash_set::traverse. */
971 1353
972 static bool 1354 bool
973 find_dummy_types (const void *ptr, void *adata) 1355 find_dummy_types (const char *const &ptr, godump_container *adata)
974 { 1356 {
975 struct godump_container *data = (struct godump_container *) adata; 1357 struct godump_container *data = (struct godump_container *) adata;
976 const char *type = (const char *) ptr; 1358 const char *type = (const char *) ptr;
977 void **slot; 1359 void **slot;
1360 void **islot;
978 1361
979 slot = htab_find_slot (data->type_hash, type, NO_INSERT); 1362 slot = htab_find_slot (data->type_hash, type, NO_INSERT);
980 if (slot == NULL) 1363 islot = htab_find_slot (data->invalid_hash, type, NO_INSERT);
1364 if (slot == NULL || islot != NULL)
981 fprintf (go_dump_file, "type _%s struct {}\n", type); 1365 fprintf (go_dump_file, "type _%s struct {}\n", type);
982 return true; 1366 return true;
983 } 1367 }
984 1368
985 /* Output symbols. */ 1369 /* Output symbols. */
991 unsigned int ix; 1375 unsigned int ix;
992 tree decl; 1376 tree decl;
993 1377
994 real_debug_hooks->finish (filename); 1378 real_debug_hooks->finish (filename);
995 1379
996 container.decls_seen = pointer_set_create ();
997 container.pot_dummy_types = pointer_set_create ();
998 container.type_hash = htab_create (100, htab_hash_string, 1380 container.type_hash = htab_create (100, htab_hash_string,
999 string_hash_eq, NULL); 1381 string_hash_eq, NULL);
1382 container.invalid_hash = htab_create (10, htab_hash_string,
1383 string_hash_eq, NULL);
1000 container.keyword_hash = htab_create (50, htab_hash_string, 1384 container.keyword_hash = htab_create (50, htab_hash_string,
1001 string_hash_eq, NULL); 1385 string_hash_eq, NULL);
1002 obstack_init (&container.type_obstack); 1386 obstack_init (&container.type_obstack);
1003 1387
1004 keyword_hash_init (&container); 1388 keyword_hash_init (&container);
1005 1389
1006 FOR_EACH_VEC_ELT (tree, queue, ix, decl) 1390 FOR_EACH_VEC_SAFE_ELT (queue, ix, decl)
1007 { 1391 {
1008 switch (TREE_CODE (decl)) 1392 switch (TREE_CODE (decl))
1009 { 1393 {
1010 case FUNCTION_DECL: 1394 case FUNCTION_DECL:
1011 go_output_fndecl (&container, decl); 1395 go_output_fndecl (&container, decl);
1018 case VAR_DECL: 1402 case VAR_DECL:
1019 go_output_var (&container, decl); 1403 go_output_var (&container, decl);
1020 break; 1404 break;
1021 1405
1022 default: 1406 default:
1023 gcc_unreachable(); 1407 gcc_unreachable ();
1024 } 1408 }
1025 } 1409 }
1026 1410
1411 htab_traverse_noresize (macro_hash, go_print_macro, NULL);
1412
1027 /* To emit dummy definitions. */ 1413 /* To emit dummy definitions. */
1028 pointer_set_traverse (container.pot_dummy_types, find_dummy_types, 1414 container.pot_dummy_types.traverse<godump_container *, find_dummy_types>
1029 (void *) &container); 1415 (&container);
1030 1416
1031 pointer_set_destroy (container.decls_seen);
1032 pointer_set_destroy (container.pot_dummy_types);
1033 htab_delete (container.type_hash); 1417 htab_delete (container.type_hash);
1418 htab_delete (container.invalid_hash);
1034 htab_delete (container.keyword_hash); 1419 htab_delete (container.keyword_hash);
1035 obstack_free (&container.type_obstack, NULL); 1420 obstack_free (&container.type_obstack, NULL);
1036 1421
1037 queue = NULL; 1422 vec_free (queue);
1038 1423
1039 if (fclose (go_dump_file) != 0) 1424 if (fclose (go_dump_file) != 0)
1040 error ("could not close Go dump file: %m"); 1425 error ("could not close Go dump file: %m");
1041 go_dump_file = NULL; 1426 go_dump_file = NULL;
1042 } 1427 }
1058 1443
1059 go_debug_hooks.finish = go_finish; 1444 go_debug_hooks.finish = go_finish;
1060 go_debug_hooks.define = go_define; 1445 go_debug_hooks.define = go_define;
1061 go_debug_hooks.undef = go_undef; 1446 go_debug_hooks.undef = go_undef;
1062 go_debug_hooks.function_decl = go_function_decl; 1447 go_debug_hooks.function_decl = go_function_decl;
1063 go_debug_hooks.global_decl = go_global_decl; 1448 go_debug_hooks.early_global_decl = go_early_global_decl;
1449 go_debug_hooks.late_global_decl = go_late_global_decl;
1064 go_debug_hooks.type_decl = go_type_decl; 1450 go_debug_hooks.type_decl = go_type_decl;
1065 1451
1066 macro_hash = htab_create (100, htab_hash_string, string_hash_eq, NULL); 1452 macro_hash = htab_create (100, macro_hash_hashval, macro_hash_eq,
1453 macro_hash_del);
1067 1454
1068 return &go_debug_hooks; 1455 return &go_debug_hooks;
1069 } 1456 }
1070 1457
1071 #include "gt-godump.h" 1458 #include "gt-godump.h"