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