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