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