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
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 3, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along 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
60static struct gcc_debug_hooks go_debug_hooks;
61
62/* The real debug hooks.  */
63
64static const struct gcc_debug_hooks *real_debug_hooks;
65
66/* The file where we should write information.  */
67
68static FILE *go_dump_file;
69
70/* A queue of decls to output.  */
71
72static GTY(()) vec<tree, va_gc> *queue;
73
74/* A hash table of macros we have seen.  */
75
76static htab_t macro_hash;
77
78/* The type of a value in macro_hash.  */
79
80struct 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
91static inline unsigned int
92precision_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
99static hashval_t
100macro_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
108static int
109macro_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
118static void
119macro_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
129static int
130string_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
137static void
138go_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
481static void
482go_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
498static void
499go_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
510static void
511go_function_decl (tree decl)
512{
513  real_debug_hooks->function_decl (decl);
514  go_decl (decl);
515}
516
517/* A global variable decl.  */
518
519static void
520go_global_decl (tree decl)
521{
522  real_debug_hooks->global_decl (decl);
523  go_decl (decl);
524}
525
526/* A type declaration.  */
527
528static void
529go_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
546struct 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
570static void
571go_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
580static const char *
581go_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
601static unsigned int
602go_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
617static void
618go_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
637static unsigned int
638go_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
662static unsigned int
663go_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
689static bool
690go_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
1108static void
1109go_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
1121static void
1122go_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
1135static void
1136go_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
1262static void
1263go_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
1334static int
1335go_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
1344static 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
1351static void
1352keyword_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
1369bool
1370find_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
1386static void
1387go_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
1446const struct gcc_debug_hooks *
1447dump_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"
1473