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