prdbg.c revision 60484
133965Sjdp/* prdbg.c -- Print out generic debugging information.
260484Sobrien   Copyright (C) 1995, 1996, 1999 Free Software Foundation, Inc.
333965Sjdp   Written by Ian Lance Taylor <ian@cygnus.com>.
433965Sjdp
533965Sjdp   This file is part of GNU Binutils.
633965Sjdp
733965Sjdp   This program is free software; you can redistribute it and/or modify
833965Sjdp   it under the terms of the GNU General Public License as published by
933965Sjdp   the Free Software Foundation; either version 2 of the License, or
1033965Sjdp   (at your option) any later version.
1133965Sjdp
1233965Sjdp   This program is distributed in the hope that it will be useful,
1333965Sjdp   but WITHOUT ANY WARRANTY; without even the implied warranty of
1433965Sjdp   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1533965Sjdp   GNU General Public License for more details.
1633965Sjdp
1733965Sjdp   You should have received a copy of the GNU General Public License
1833965Sjdp   along with this program; if not, write to the Free Software
1933965Sjdp   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
2033965Sjdp   02111-1307, USA.  */
2133965Sjdp
2233965Sjdp/* This file prints out the generic debugging information, by
2333965Sjdp   supplying a set of routines to debug_write.  */
2433965Sjdp
2533965Sjdp#include <stdio.h>
2633965Sjdp#include <assert.h>
2733965Sjdp
2833965Sjdp#include "bfd.h"
2933965Sjdp#include "bucomm.h"
3033965Sjdp#include "libiberty.h"
3133965Sjdp#include "debug.h"
3233965Sjdp#include "budbg.h"
3333965Sjdp
3433965Sjdp/* This is the structure we use as a handle for these routines.  */
3533965Sjdp
3633965Sjdpstruct pr_handle
3733965Sjdp{
3833965Sjdp  /* File to print information to.  */
3933965Sjdp  FILE *f;
4033965Sjdp  /* Current indentation level.  */
4133965Sjdp  unsigned int indent;
4233965Sjdp  /* Type stack.  */
4333965Sjdp  struct pr_stack *stack;
4433965Sjdp  /* Parameter number we are about to output.  */
4533965Sjdp  int parameter;
4633965Sjdp};
4733965Sjdp
4833965Sjdp/* The type stack.  */
4933965Sjdp
5033965Sjdpstruct pr_stack
5133965Sjdp{
5233965Sjdp  /* Next element on the stack.  */
5333965Sjdp  struct pr_stack *next;
5433965Sjdp  /* This element.  */
5533965Sjdp  char *type;
5633965Sjdp  /* Current visibility of fields if this is a class.  */
5733965Sjdp  enum debug_visibility visibility;
5833965Sjdp  /* Name of the current method we are handling.  */
5933965Sjdp  const char *method;
6033965Sjdp};
6133965Sjdp
6233965Sjdpstatic void indent PARAMS ((struct pr_handle *));
6333965Sjdpstatic boolean push_type PARAMS ((struct pr_handle *, const char *));
6433965Sjdpstatic boolean prepend_type PARAMS ((struct pr_handle *, const char *));
6533965Sjdpstatic boolean append_type PARAMS ((struct pr_handle *, const char *));
6633965Sjdpstatic boolean substitute_type PARAMS ((struct pr_handle *, const char *));
6733965Sjdpstatic boolean indent_type PARAMS ((struct pr_handle *));
6833965Sjdpstatic char *pop_type PARAMS ((struct pr_handle *));
6933965Sjdpstatic void print_vma PARAMS ((bfd_vma, char *, boolean, boolean));
7033965Sjdpstatic boolean pr_fix_visibility
7133965Sjdp  PARAMS ((struct pr_handle *, enum debug_visibility));
7233965Sjdp
7333965Sjdpstatic boolean pr_start_compilation_unit PARAMS ((PTR, const char *));
7433965Sjdpstatic boolean pr_start_source PARAMS ((PTR, const char *));
7533965Sjdpstatic boolean pr_empty_type PARAMS ((PTR));
7633965Sjdpstatic boolean pr_void_type PARAMS ((PTR));
7733965Sjdpstatic boolean pr_int_type PARAMS ((PTR, unsigned int, boolean));
7833965Sjdpstatic boolean pr_float_type PARAMS ((PTR, unsigned int));
7933965Sjdpstatic boolean pr_complex_type PARAMS ((PTR, unsigned int));
8033965Sjdpstatic boolean pr_bool_type PARAMS ((PTR, unsigned int));
8133965Sjdpstatic boolean pr_enum_type
8233965Sjdp  PARAMS ((PTR, const char *, const char **, bfd_signed_vma *));
8333965Sjdpstatic boolean pr_pointer_type PARAMS ((PTR));
8433965Sjdpstatic boolean pr_function_type PARAMS ((PTR, int, boolean));
8533965Sjdpstatic boolean pr_reference_type PARAMS ((PTR));
8633965Sjdpstatic boolean pr_range_type PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma));
8733965Sjdpstatic boolean pr_array_type
8833965Sjdp  PARAMS ((PTR, bfd_signed_vma, bfd_signed_vma, boolean));
8933965Sjdpstatic boolean pr_set_type PARAMS ((PTR, boolean));
9033965Sjdpstatic boolean pr_offset_type PARAMS ((PTR));
9133965Sjdpstatic boolean pr_method_type PARAMS ((PTR, boolean, int, boolean));
9233965Sjdpstatic boolean pr_const_type PARAMS ((PTR));
9333965Sjdpstatic boolean pr_volatile_type PARAMS ((PTR));
9433965Sjdpstatic boolean pr_start_struct_type
9533965Sjdp  PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int));
9633965Sjdpstatic boolean pr_struct_field
9733965Sjdp  PARAMS ((PTR, const char *, bfd_vma, bfd_vma, enum debug_visibility));
9833965Sjdpstatic boolean pr_end_struct_type PARAMS ((PTR));
9933965Sjdpstatic boolean pr_start_class_type
10033965Sjdp  PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int, boolean,
10133965Sjdp	   boolean));
10233965Sjdpstatic boolean pr_class_static_member
10333965Sjdp  PARAMS ((PTR, const char *, const char *, enum debug_visibility));
10433965Sjdpstatic boolean pr_class_baseclass
10533965Sjdp  PARAMS ((PTR, bfd_vma, boolean, enum debug_visibility));
10633965Sjdpstatic boolean pr_class_start_method PARAMS ((PTR, const char *));
10733965Sjdpstatic boolean pr_class_method_variant
10833965Sjdp  PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean,
10933965Sjdp	   bfd_vma, boolean));
11033965Sjdpstatic boolean pr_class_static_method_variant
11133965Sjdp  PARAMS ((PTR, const char *, enum debug_visibility, boolean, boolean));
11233965Sjdpstatic boolean pr_class_end_method PARAMS ((PTR));
11333965Sjdpstatic boolean pr_end_class_type PARAMS ((PTR));
11433965Sjdpstatic boolean pr_typedef_type PARAMS ((PTR, const char *));
11533965Sjdpstatic boolean pr_tag_type
11633965Sjdp  PARAMS ((PTR, const char *, unsigned int, enum debug_type_kind));
11733965Sjdpstatic boolean pr_typdef PARAMS ((PTR, const char *));
11833965Sjdpstatic boolean pr_tag PARAMS ((PTR, const char *));
11933965Sjdpstatic boolean pr_int_constant PARAMS ((PTR, const char *, bfd_vma));
12033965Sjdpstatic boolean pr_float_constant PARAMS ((PTR, const char *, double));
12133965Sjdpstatic boolean pr_typed_constant PARAMS ((PTR, const char *, bfd_vma));
12233965Sjdpstatic boolean pr_variable
12333965Sjdp  PARAMS ((PTR, const char *, enum debug_var_kind, bfd_vma));
12433965Sjdpstatic boolean pr_start_function PARAMS ((PTR, const char *, boolean));
12533965Sjdpstatic boolean pr_function_parameter
12633965Sjdp  PARAMS ((PTR, const char *, enum debug_parm_kind, bfd_vma));
12733965Sjdpstatic boolean pr_start_block PARAMS ((PTR, bfd_vma));
12833965Sjdpstatic boolean pr_end_block PARAMS ((PTR, bfd_vma));
12933965Sjdpstatic boolean pr_end_function PARAMS ((PTR));
13033965Sjdpstatic boolean pr_lineno PARAMS ((PTR, const char *, unsigned long, bfd_vma));
13133965Sjdp
13233965Sjdpstatic const struct debug_write_fns pr_fns =
13333965Sjdp{
13433965Sjdp  pr_start_compilation_unit,
13533965Sjdp  pr_start_source,
13633965Sjdp  pr_empty_type,
13733965Sjdp  pr_void_type,
13833965Sjdp  pr_int_type,
13933965Sjdp  pr_float_type,
14033965Sjdp  pr_complex_type,
14133965Sjdp  pr_bool_type,
14233965Sjdp  pr_enum_type,
14333965Sjdp  pr_pointer_type,
14433965Sjdp  pr_function_type,
14533965Sjdp  pr_reference_type,
14633965Sjdp  pr_range_type,
14733965Sjdp  pr_array_type,
14833965Sjdp  pr_set_type,
14933965Sjdp  pr_offset_type,
15033965Sjdp  pr_method_type,
15133965Sjdp  pr_const_type,
15233965Sjdp  pr_volatile_type,
15333965Sjdp  pr_start_struct_type,
15433965Sjdp  pr_struct_field,
15533965Sjdp  pr_end_struct_type,
15633965Sjdp  pr_start_class_type,
15733965Sjdp  pr_class_static_member,
15833965Sjdp  pr_class_baseclass,
15933965Sjdp  pr_class_start_method,
16033965Sjdp  pr_class_method_variant,
16133965Sjdp  pr_class_static_method_variant,
16233965Sjdp  pr_class_end_method,
16333965Sjdp  pr_end_class_type,
16433965Sjdp  pr_typedef_type,
16533965Sjdp  pr_tag_type,
16633965Sjdp  pr_typdef,
16733965Sjdp  pr_tag,
16833965Sjdp  pr_int_constant,
16933965Sjdp  pr_float_constant,
17033965Sjdp  pr_typed_constant,
17133965Sjdp  pr_variable,
17233965Sjdp  pr_start_function,
17333965Sjdp  pr_function_parameter,
17433965Sjdp  pr_start_block,
17533965Sjdp  pr_end_block,
17633965Sjdp  pr_end_function,
17733965Sjdp  pr_lineno
17833965Sjdp};
17933965Sjdp
18033965Sjdp/* Print out the generic debugging information recorded in dhandle.  */
18133965Sjdp
18233965Sjdpboolean
18333965Sjdpprint_debugging_info (f, dhandle)
18433965Sjdp     FILE *f;
18533965Sjdp     PTR dhandle;
18633965Sjdp{
18733965Sjdp  struct pr_handle info;
18833965Sjdp
18933965Sjdp  info.f = f;
19033965Sjdp  info.indent = 0;
19133965Sjdp  info.stack = NULL;
19233965Sjdp  info.parameter = 0;
19333965Sjdp
19433965Sjdp  return debug_write (dhandle, &pr_fns, (PTR) &info);
19533965Sjdp}
19633965Sjdp
19733965Sjdp/* Indent to the current indentation level.  */
19833965Sjdp
19933965Sjdpstatic void
20033965Sjdpindent (info)
20133965Sjdp     struct pr_handle *info;
20233965Sjdp{
20333965Sjdp  unsigned int i;
20433965Sjdp
20533965Sjdp  for (i = 0; i < info->indent; i++)
20633965Sjdp    putc (' ', info->f);
20733965Sjdp}
20833965Sjdp
20933965Sjdp/* Push a type on the type stack.  */
21033965Sjdp
21133965Sjdpstatic boolean
21233965Sjdppush_type (info, type)
21333965Sjdp     struct pr_handle *info;
21433965Sjdp     const char *type;
21533965Sjdp{
21633965Sjdp  struct pr_stack *n;
21733965Sjdp
21833965Sjdp  if (type == NULL)
21933965Sjdp    return false;
22033965Sjdp
22133965Sjdp  n = (struct pr_stack *) xmalloc (sizeof *n);
22233965Sjdp  memset (n, 0, sizeof *n);
22333965Sjdp
22433965Sjdp  n->type = xstrdup (type);
22533965Sjdp  n->visibility = DEBUG_VISIBILITY_IGNORE;
22633965Sjdp  n->method = NULL;
22733965Sjdp  n->next = info->stack;
22833965Sjdp  info->stack = n;
22933965Sjdp
23033965Sjdp  return true;
23133965Sjdp}
23233965Sjdp
23333965Sjdp/* Prepend a string onto the type on the top of the type stack.  */
23433965Sjdp
23533965Sjdpstatic boolean
23633965Sjdpprepend_type (info, s)
23733965Sjdp     struct pr_handle *info;
23833965Sjdp     const char *s;
23933965Sjdp{
24033965Sjdp  char *n;
24133965Sjdp
24233965Sjdp  assert (info->stack != NULL);
24333965Sjdp
24433965Sjdp  n = (char *) xmalloc (strlen (s) + strlen (info->stack->type) + 1);
24533965Sjdp  sprintf (n, "%s%s", s, info->stack->type);
24633965Sjdp  free (info->stack->type);
24733965Sjdp  info->stack->type = n;
24833965Sjdp
24933965Sjdp  return true;
25033965Sjdp}
25133965Sjdp
25233965Sjdp/* Append a string to the type on the top of the type stack.  */
25333965Sjdp
25433965Sjdpstatic boolean
25533965Sjdpappend_type (info, s)
25633965Sjdp     struct pr_handle *info;
25733965Sjdp     const char *s;
25833965Sjdp{
25933965Sjdp  unsigned int len;
26033965Sjdp
26133965Sjdp  if (s == NULL)
26233965Sjdp    return false;
26333965Sjdp
26433965Sjdp  assert (info->stack != NULL);
26533965Sjdp
26633965Sjdp  len = strlen (info->stack->type);
26733965Sjdp  info->stack->type = (char *) xrealloc (info->stack->type,
26833965Sjdp					 len + strlen (s) + 1);
26933965Sjdp  strcpy (info->stack->type + len, s);
27033965Sjdp
27133965Sjdp  return true;
27233965Sjdp}
27333965Sjdp
27433965Sjdp/* We use an underscore to indicate where the name should go in a type
27533965Sjdp   string.  This function substitutes a string for the underscore.  If
27633965Sjdp   there is no underscore, the name follows the type.  */
27733965Sjdp
27833965Sjdpstatic boolean
27933965Sjdpsubstitute_type (info, s)
28033965Sjdp     struct pr_handle *info;
28133965Sjdp     const char *s;
28233965Sjdp{
28333965Sjdp  char *u;
28433965Sjdp
28533965Sjdp  assert (info->stack != NULL);
28633965Sjdp
28733965Sjdp  u = strchr (info->stack->type, '|');
28833965Sjdp  if (u != NULL)
28933965Sjdp    {
29033965Sjdp      char *n;
29133965Sjdp
29233965Sjdp      n = (char *) xmalloc (strlen (info->stack->type) + strlen (s));
29333965Sjdp
29433965Sjdp      memcpy (n, info->stack->type, u - info->stack->type);
29533965Sjdp      strcpy (n + (u - info->stack->type), s);
29633965Sjdp      strcat (n, u + 1);
29733965Sjdp
29833965Sjdp      free (info->stack->type);
29933965Sjdp      info->stack->type = n;
30033965Sjdp
30133965Sjdp      return true;
30233965Sjdp    }
30333965Sjdp
30433965Sjdp  if (strchr (s, '|') != NULL
30533965Sjdp      && (strchr (info->stack->type, '{') != NULL
30633965Sjdp	  || strchr (info->stack->type, '(') != NULL))
30733965Sjdp    {
30833965Sjdp      if (! prepend_type (info, "(")
30933965Sjdp	  || ! append_type (info, ")"))
31033965Sjdp	return false;
31133965Sjdp    }
31233965Sjdp
31333965Sjdp  if (*s == '\0')
31433965Sjdp    return true;
31533965Sjdp
31633965Sjdp  return (append_type (info, " ")
31733965Sjdp	  && append_type (info, s));
31833965Sjdp}
31933965Sjdp
32033965Sjdp/* Indent the type at the top of the stack by appending spaces.  */
32133965Sjdp
32233965Sjdpstatic boolean
32333965Sjdpindent_type (info)
32433965Sjdp     struct pr_handle *info;
32533965Sjdp{
32633965Sjdp  unsigned int i;
32733965Sjdp
32833965Sjdp  for (i = 0; i < info->indent; i++)
32933965Sjdp    {
33033965Sjdp      if (! append_type (info, " "))
33133965Sjdp	return false;
33233965Sjdp    }
33333965Sjdp
33433965Sjdp  return true;
33533965Sjdp}
33633965Sjdp
33733965Sjdp/* Pop a type from the type stack.  */
33833965Sjdp
33933965Sjdpstatic char *
34033965Sjdppop_type (info)
34133965Sjdp     struct pr_handle *info;
34233965Sjdp{
34333965Sjdp  struct pr_stack *o;
34433965Sjdp  char *ret;
34533965Sjdp
34633965Sjdp  assert (info->stack != NULL);
34733965Sjdp
34833965Sjdp  o = info->stack;
34933965Sjdp  info->stack = o->next;
35033965Sjdp  ret = o->type;
35133965Sjdp  free (o);
35233965Sjdp
35333965Sjdp  return ret;
35433965Sjdp}
35533965Sjdp
35633965Sjdp/* Print a VMA value into a string.  */
35733965Sjdp
35833965Sjdpstatic void
35933965Sjdpprint_vma (vma, buf, unsignedp, hexp)
36033965Sjdp     bfd_vma vma;
36133965Sjdp     char *buf;
36233965Sjdp     boolean unsignedp;
36333965Sjdp     boolean hexp;
36433965Sjdp{
36533965Sjdp  if (sizeof (vma) <= sizeof (unsigned long))
36633965Sjdp    {
36733965Sjdp      if (hexp)
36833965Sjdp	sprintf (buf, "0x%lx", (unsigned long) vma);
36933965Sjdp      else if (unsignedp)
37033965Sjdp	sprintf (buf, "%lu", (unsigned long) vma);
37133965Sjdp      else
37233965Sjdp	sprintf (buf, "%ld", (long) vma);
37333965Sjdp    }
37433965Sjdp  else
37533965Sjdp    {
37633965Sjdp      buf[0] = '0';
37733965Sjdp      buf[1] = 'x';
37833965Sjdp      sprintf_vma (buf + 2, vma);
37933965Sjdp    }
38033965Sjdp}
38133965Sjdp
38233965Sjdp/* Start a new compilation unit.  */
38333965Sjdp
38433965Sjdpstatic boolean
38533965Sjdppr_start_compilation_unit (p, filename)
38633965Sjdp     PTR p;
38733965Sjdp     const char *filename;
38833965Sjdp{
38933965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
39033965Sjdp
39133965Sjdp  assert (info->indent == 0);
39233965Sjdp
39333965Sjdp  fprintf (info->f, "%s:\n", filename);
39433965Sjdp
39533965Sjdp  return true;
39633965Sjdp}
39733965Sjdp
39833965Sjdp/* Start a source file within a compilation unit.  */
39933965Sjdp
40033965Sjdpstatic boolean
40133965Sjdppr_start_source (p, filename)
40233965Sjdp     PTR p;
40333965Sjdp     const char *filename;
40433965Sjdp{
40533965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
40633965Sjdp
40733965Sjdp  assert (info->indent == 0);
40833965Sjdp
40933965Sjdp  fprintf (info->f, " %s:\n", filename);
41033965Sjdp
41133965Sjdp  return true;
41233965Sjdp}
41333965Sjdp
41433965Sjdp/* Push an empty type onto the type stack.  */
41533965Sjdp
41633965Sjdpstatic boolean
41733965Sjdppr_empty_type (p)
41833965Sjdp     PTR p;
41933965Sjdp{
42033965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
42133965Sjdp
42233965Sjdp  return push_type (info, "<undefined>");
42333965Sjdp}
42433965Sjdp
42533965Sjdp/* Push a void type onto the type stack.  */
42633965Sjdp
42733965Sjdpstatic boolean
42833965Sjdppr_void_type (p)
42933965Sjdp     PTR p;
43033965Sjdp{
43133965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
43233965Sjdp
43333965Sjdp  return push_type (info, "void");
43433965Sjdp}
43533965Sjdp
43633965Sjdp/* Push an integer type onto the type stack.  */
43733965Sjdp
43833965Sjdpstatic boolean
43933965Sjdppr_int_type (p, size, unsignedp)
44033965Sjdp     PTR p;
44133965Sjdp     unsigned int size;
44233965Sjdp     boolean unsignedp;
44333965Sjdp{
44433965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
44533965Sjdp  char ab[10];
44633965Sjdp
44733965Sjdp  sprintf (ab, "%sint%d", unsignedp ? "u" : "", size * 8);
44833965Sjdp  return push_type (info, ab);
44933965Sjdp}
45033965Sjdp
45133965Sjdp/* Push a floating type onto the type stack.  */
45233965Sjdp
45333965Sjdpstatic boolean
45433965Sjdppr_float_type (p, size)
45533965Sjdp     PTR p;
45633965Sjdp     unsigned int size;
45733965Sjdp{
45833965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
45933965Sjdp  char ab[10];
46033965Sjdp
46133965Sjdp  if (size == 4)
46233965Sjdp    return push_type (info, "float");
46333965Sjdp  else if (size == 8)
46433965Sjdp    return push_type (info, "double");
46533965Sjdp
46633965Sjdp  sprintf (ab, "float%d", size * 8);
46733965Sjdp  return push_type (info, ab);
46833965Sjdp}
46933965Sjdp
47033965Sjdp/* Push a complex type onto the type stack.  */
47133965Sjdp
47233965Sjdpstatic boolean
47333965Sjdppr_complex_type (p, size)
47433965Sjdp     PTR p;
47533965Sjdp     unsigned int size;
47633965Sjdp{
47733965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
47833965Sjdp
47933965Sjdp  if (! pr_float_type (p, size))
48033965Sjdp    return false;
48133965Sjdp
48233965Sjdp  return prepend_type (info, "complex ");
48333965Sjdp}
48433965Sjdp
48533965Sjdp/* Push a boolean type onto the type stack.  */
48633965Sjdp
48733965Sjdpstatic boolean
48833965Sjdppr_bool_type (p, size)
48933965Sjdp     PTR p;
49033965Sjdp     unsigned int size;
49133965Sjdp{
49233965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
49333965Sjdp  char ab[10];
49433965Sjdp
49533965Sjdp  sprintf (ab, "bool%d", size * 8);
49633965Sjdp
49733965Sjdp  return push_type (info, ab);
49833965Sjdp}
49933965Sjdp
50033965Sjdp/* Push an enum type onto the type stack.  */
50133965Sjdp
50233965Sjdpstatic boolean
50333965Sjdppr_enum_type (p, tag, names, values)
50433965Sjdp     PTR p;
50533965Sjdp     const char *tag;
50633965Sjdp     const char **names;
50733965Sjdp     bfd_signed_vma *values;
50833965Sjdp{
50933965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
51033965Sjdp  unsigned int i;
51133965Sjdp  bfd_signed_vma val;
51233965Sjdp
51333965Sjdp  if (! push_type (info, "enum "))
51433965Sjdp    return false;
51533965Sjdp  if (tag != NULL)
51633965Sjdp    {
51733965Sjdp      if (! append_type (info, tag)
51833965Sjdp	  || ! append_type (info, " "))
51933965Sjdp	return false;
52033965Sjdp    }
52133965Sjdp  if (! append_type (info, "{ "))
52233965Sjdp    return false;
52333965Sjdp
52433965Sjdp  if (names == NULL)
52533965Sjdp    {
52633965Sjdp      if (! append_type (info, "/* undefined */"))
52733965Sjdp	return false;
52833965Sjdp    }
52933965Sjdp  else
53033965Sjdp    {
53133965Sjdp      val = 0;
53233965Sjdp      for (i = 0; names[i] != NULL; i++)
53333965Sjdp	{
53433965Sjdp	  if (i > 0)
53533965Sjdp	    {
53633965Sjdp	      if (! append_type (info, ", "))
53733965Sjdp		return false;
53833965Sjdp	    }
53933965Sjdp
54033965Sjdp	  if (! append_type (info, names[i]))
54133965Sjdp	    return false;
54233965Sjdp
54333965Sjdp	  if (values[i] != val)
54433965Sjdp	    {
54533965Sjdp	      char ab[20];
54633965Sjdp
54733965Sjdp	      print_vma (values[i], ab, false, false);
54833965Sjdp	      if (! append_type (info, " = ")
54933965Sjdp		  || ! append_type (info, ab))
55033965Sjdp		return false;
55133965Sjdp	      val = values[i];
55233965Sjdp	    }
55333965Sjdp
55433965Sjdp	  ++val;
55533965Sjdp	}
55633965Sjdp    }
55733965Sjdp
55833965Sjdp  return append_type (info, " }");
55933965Sjdp}
56033965Sjdp
56133965Sjdp/* Turn the top type on the stack into a pointer.  */
56233965Sjdp
56333965Sjdpstatic boolean
56433965Sjdppr_pointer_type (p)
56533965Sjdp     PTR p;
56633965Sjdp{
56733965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
56833965Sjdp  char *s;
56933965Sjdp
57033965Sjdp  assert (info->stack != NULL);
57133965Sjdp
57233965Sjdp  s = strchr (info->stack->type, '|');
57333965Sjdp  if (s != NULL && s[1] == '[')
57433965Sjdp    return substitute_type (info, "(*|)");
57533965Sjdp  return substitute_type (info, "*|");
57633965Sjdp}
57733965Sjdp
57833965Sjdp/* Turn the top type on the stack into a function returning that type.  */
57933965Sjdp
58033965Sjdpstatic boolean
58133965Sjdppr_function_type (p, argcount, varargs)
58233965Sjdp     PTR p;
58333965Sjdp     int argcount;
58433965Sjdp     boolean varargs;
58533965Sjdp{
58633965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
58733965Sjdp  char **arg_types;
58833965Sjdp  unsigned int len;
58933965Sjdp  char *s;
59033965Sjdp
59133965Sjdp  assert (info->stack != NULL);
59233965Sjdp
59333965Sjdp  len = 10;
59433965Sjdp
59533965Sjdp  if (argcount <= 0)
59633965Sjdp    {
59733965Sjdp      arg_types = NULL;
59833965Sjdp      len += 15;
59933965Sjdp    }
60033965Sjdp  else
60133965Sjdp    {
60233965Sjdp      int i;
60333965Sjdp
60433965Sjdp      arg_types = (char **) xmalloc (argcount * sizeof *arg_types);
60533965Sjdp      for (i = argcount - 1; i >= 0; i--)
60633965Sjdp	{
60733965Sjdp	  if (! substitute_type (info, ""))
60833965Sjdp	    return false;
60933965Sjdp	  arg_types[i] = pop_type (info);
61033965Sjdp	  if (arg_types[i] == NULL)
61133965Sjdp	    return false;
61233965Sjdp	  len += strlen (arg_types[i]) + 2;
61333965Sjdp	}
61433965Sjdp      if (varargs)
61533965Sjdp	len += 5;
61633965Sjdp    }
61733965Sjdp
61833965Sjdp  /* Now the return type is on the top of the stack.  */
61933965Sjdp
62033965Sjdp  s = (char *) xmalloc (len);
62133965Sjdp  strcpy (s, "(|) (");
62233965Sjdp
62333965Sjdp  if (argcount < 0)
62433965Sjdp    strcat (s, "/* unknown */");
62533965Sjdp  else
62633965Sjdp    {
62733965Sjdp      int i;
62833965Sjdp
62933965Sjdp      for (i = 0; i < argcount; i++)
63033965Sjdp	{
63133965Sjdp	  if (i > 0)
63233965Sjdp	    strcat (s, ", ");
63333965Sjdp	  strcat (s, arg_types[i]);
63433965Sjdp	}
63533965Sjdp      if (varargs)
63633965Sjdp	{
63733965Sjdp	  if (i > 0)
63833965Sjdp	    strcat (s, ", ");
63933965Sjdp	  strcat (s, "...");
64033965Sjdp	}
64133965Sjdp      if (argcount > 0)
64233965Sjdp	free (arg_types);
64333965Sjdp    }
64433965Sjdp
64533965Sjdp  strcat (s, ")");
64633965Sjdp
64733965Sjdp  if (! substitute_type (info, s))
64833965Sjdp    return false;
64933965Sjdp
65033965Sjdp  free (s);
65133965Sjdp
65233965Sjdp  return true;
65333965Sjdp}
65433965Sjdp
65533965Sjdp/* Turn the top type on the stack into a reference to that type.  */
65633965Sjdp
65733965Sjdpstatic boolean
65833965Sjdppr_reference_type (p)
65933965Sjdp     PTR p;
66033965Sjdp{
66133965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
66233965Sjdp
66333965Sjdp  assert (info->stack != NULL);
66433965Sjdp
66533965Sjdp  return substitute_type (info, "&|");
66633965Sjdp}
66733965Sjdp
66833965Sjdp/* Make a range type.  */
66933965Sjdp
67033965Sjdpstatic boolean
67133965Sjdppr_range_type (p, lower, upper)
67233965Sjdp     PTR p;
67333965Sjdp     bfd_signed_vma lower;
67433965Sjdp     bfd_signed_vma upper;
67533965Sjdp{
67633965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
67733965Sjdp  char abl[20], abu[20];
67833965Sjdp
67933965Sjdp  assert (info->stack != NULL);
68033965Sjdp
68133965Sjdp  if (! substitute_type (info, ""))
68233965Sjdp    return false;
68333965Sjdp
68433965Sjdp  print_vma (lower, abl, false, false);
68533965Sjdp  print_vma (upper, abu, false, false);
68633965Sjdp
68733965Sjdp  return (prepend_type (info, "range (")
68833965Sjdp	  && append_type (info, "):")
68933965Sjdp	  && append_type (info, abl)
69033965Sjdp	  && append_type (info, ":")
69133965Sjdp	  && append_type (info, abu));
69233965Sjdp}
69333965Sjdp
69433965Sjdp/* Make an array type.  */
69533965Sjdp
69633965Sjdp/*ARGSUSED*/
69733965Sjdpstatic boolean
69833965Sjdppr_array_type (p, lower, upper, stringp)
69933965Sjdp     PTR p;
70033965Sjdp     bfd_signed_vma lower;
70133965Sjdp     bfd_signed_vma upper;
70233965Sjdp     boolean stringp;
70333965Sjdp{
70433965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
70533965Sjdp  char *range_type;
70633965Sjdp  char abl[20], abu[20], ab[50];
70733965Sjdp
70833965Sjdp  range_type = pop_type (info);
70933965Sjdp  if (range_type == NULL)
71033965Sjdp    return false;
71133965Sjdp
71233965Sjdp  if (lower == 0)
71333965Sjdp    {
71433965Sjdp      if (upper == -1)
71533965Sjdp	sprintf (ab, "|[]");
71633965Sjdp      else
71733965Sjdp	{
71833965Sjdp	  print_vma (upper + 1, abu, false, false);
71933965Sjdp	  sprintf (ab, "|[%s]", abu);
72033965Sjdp	}
72133965Sjdp    }
72233965Sjdp  else
72333965Sjdp    {
72433965Sjdp      print_vma (lower, abl, false, false);
72533965Sjdp      print_vma (upper, abu, false, false);
72633965Sjdp      sprintf (ab, "|[%s:%s]", abl, abu);
72733965Sjdp    }
72833965Sjdp
72933965Sjdp  if (! substitute_type (info, ab))
73033965Sjdp    return false;
73133965Sjdp
73233965Sjdp  if (strcmp (range_type, "int") != 0)
73333965Sjdp    {
73433965Sjdp      if (! append_type (info, ":")
73533965Sjdp	  || ! append_type (info, range_type))
73633965Sjdp	return false;
73733965Sjdp    }
73833965Sjdp
73933965Sjdp  if (stringp)
74033965Sjdp    {
74133965Sjdp      if (! append_type (info, " /* string */"))
74233965Sjdp	return false;
74333965Sjdp    }
74433965Sjdp
74533965Sjdp  return true;
74633965Sjdp}
74733965Sjdp
74833965Sjdp/* Make a set type.  */
74933965Sjdp
75033965Sjdp/*ARGSUSED*/
75133965Sjdpstatic boolean
75233965Sjdppr_set_type (p, bitstringp)
75333965Sjdp     PTR p;
75433965Sjdp     boolean bitstringp;
75533965Sjdp{
75633965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
75733965Sjdp
75833965Sjdp  if (! substitute_type (info, ""))
75933965Sjdp    return false;
76033965Sjdp
76133965Sjdp  if (! prepend_type (info, "set { ")
76233965Sjdp      || ! append_type (info, " }"))
76333965Sjdp    return false;
76433965Sjdp
76533965Sjdp  if (bitstringp)
76633965Sjdp    {
76733965Sjdp      if (! append_type (info, "/* bitstring */"))
76833965Sjdp	return false;
76933965Sjdp    }
77033965Sjdp
77133965Sjdp  return true;
77233965Sjdp}
77333965Sjdp
77433965Sjdp/* Make an offset type.  */
77533965Sjdp
77633965Sjdpstatic boolean
77733965Sjdppr_offset_type (p)
77833965Sjdp     PTR p;
77933965Sjdp{
78033965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
78133965Sjdp  char *t;
78233965Sjdp
78333965Sjdp  if (! substitute_type (info, ""))
78433965Sjdp    return false;
78533965Sjdp
78633965Sjdp  t = pop_type (info);
78733965Sjdp  if (t == NULL)
78833965Sjdp    return false;
78933965Sjdp
79033965Sjdp  return (substitute_type (info, "")
79133965Sjdp	  && prepend_type (info, " ")
79233965Sjdp	  && prepend_type (info, t)
79333965Sjdp	  && append_type (info, "::|"));
79433965Sjdp}
79533965Sjdp
79633965Sjdp/* Make a method type.  */
79733965Sjdp
79833965Sjdpstatic boolean
79933965Sjdppr_method_type (p, domain, argcount, varargs)
80033965Sjdp     PTR p;
80133965Sjdp     boolean domain;
80233965Sjdp     int argcount;
80333965Sjdp     boolean varargs;
80433965Sjdp{
80533965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
80633965Sjdp  unsigned int len;
80733965Sjdp  char *domain_type;
80833965Sjdp  char **arg_types;
80933965Sjdp  char *s;
81033965Sjdp
81133965Sjdp  len = 10;
81233965Sjdp
81333965Sjdp  if (! domain)
81433965Sjdp    domain_type = NULL;
81533965Sjdp  else
81633965Sjdp    {
81733965Sjdp      if (! substitute_type (info, ""))
81833965Sjdp	return false;
81933965Sjdp      domain_type = pop_type (info);
82033965Sjdp      if (domain_type == NULL)
82133965Sjdp	return false;
82233965Sjdp      if (strncmp (domain_type, "class ", sizeof "class " - 1) == 0
82333965Sjdp	  && strchr (domain_type + sizeof "class " - 1, ' ') == NULL)
82433965Sjdp	domain_type += sizeof "class " - 1;
82533965Sjdp      else if (strncmp (domain_type, "union class ",
82633965Sjdp			sizeof "union class ") == 0
82733965Sjdp	       && (strchr (domain_type + sizeof "union class " - 1, ' ')
82833965Sjdp		   == NULL))
82933965Sjdp	domain_type += sizeof "union class " - 1;
83033965Sjdp      len += strlen (domain_type);
83133965Sjdp    }
83233965Sjdp
83333965Sjdp  if (argcount <= 0)
83433965Sjdp    {
83533965Sjdp      arg_types = NULL;
83633965Sjdp      len += 15;
83733965Sjdp    }
83833965Sjdp  else
83933965Sjdp    {
84033965Sjdp      int i;
84133965Sjdp
84233965Sjdp      arg_types = (char **) xmalloc (argcount * sizeof *arg_types);
84333965Sjdp      for (i = argcount - 1; i >= 0; i--)
84433965Sjdp	{
84533965Sjdp	  if (! substitute_type (info, ""))
84633965Sjdp	    return false;
84733965Sjdp	  arg_types[i] = pop_type (info);
84833965Sjdp	  if (arg_types[i] == NULL)
84933965Sjdp	    return false;
85033965Sjdp	  len += strlen (arg_types[i]) + 2;
85133965Sjdp	}
85233965Sjdp      if (varargs)
85333965Sjdp	len += 5;
85433965Sjdp    }
85533965Sjdp
85633965Sjdp  /* Now the return type is on the top of the stack.  */
85733965Sjdp
85833965Sjdp  s = (char *) xmalloc (len);
85933965Sjdp  if (! domain)
86033965Sjdp    *s = '\0';
86133965Sjdp  else
86233965Sjdp    strcpy (s, domain_type);
86333965Sjdp  strcat (s, "::| (");
86433965Sjdp
86533965Sjdp  if (argcount < 0)
86633965Sjdp    strcat (s, "/* unknown */");
86733965Sjdp  else
86833965Sjdp    {
86933965Sjdp      int i;
87033965Sjdp
87133965Sjdp      for (i = 0; i < argcount; i++)
87233965Sjdp	{
87333965Sjdp	  if (i > 0)
87433965Sjdp	    strcat (s, ", ");
87533965Sjdp	  strcat (s, arg_types[i]);
87633965Sjdp	}
87733965Sjdp      if (varargs)
87833965Sjdp	{
87933965Sjdp	  if (i > 0)
88033965Sjdp	    strcat (s, ", ");
88133965Sjdp	  strcat (s, "...");
88233965Sjdp	}
88333965Sjdp      if (argcount > 0)
88433965Sjdp	free (arg_types);
88533965Sjdp    }
88633965Sjdp
88733965Sjdp  strcat (s, ")");
88833965Sjdp
88933965Sjdp  if (! substitute_type (info, s))
89033965Sjdp    return false;
89133965Sjdp
89233965Sjdp  free (s);
89333965Sjdp
89433965Sjdp  return true;
89533965Sjdp}
89633965Sjdp
89733965Sjdp/* Make a const qualified type.  */
89833965Sjdp
89933965Sjdpstatic boolean
90033965Sjdppr_const_type (p)
90133965Sjdp     PTR p;
90233965Sjdp{
90333965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
90433965Sjdp
90533965Sjdp  return substitute_type (info, "const |");
90633965Sjdp}
90733965Sjdp
90833965Sjdp/* Make a volatile qualified type.  */
90933965Sjdp
91033965Sjdpstatic boolean
91133965Sjdppr_volatile_type (p)
91233965Sjdp     PTR p;
91333965Sjdp{
91433965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
91533965Sjdp
91633965Sjdp  return substitute_type (info, "volatile |");
91733965Sjdp}
91833965Sjdp
91933965Sjdp/* Start accumulating a struct type.  */
92033965Sjdp
92133965Sjdpstatic boolean
92233965Sjdppr_start_struct_type (p, tag, id, structp, size)
92333965Sjdp     PTR p;
92433965Sjdp     const char *tag;
92533965Sjdp     unsigned int id;
92633965Sjdp     boolean structp;
92733965Sjdp     unsigned int size;
92833965Sjdp{
92933965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
93033965Sjdp
93133965Sjdp  info->indent += 2;
93233965Sjdp
93333965Sjdp  if (! push_type (info, structp ? "struct " : "union "))
93433965Sjdp    return false;
93533965Sjdp  if (tag != NULL)
93633965Sjdp    {
93733965Sjdp      if (! append_type (info, tag))
93833965Sjdp	return false;
93933965Sjdp    }
94033965Sjdp  else
94133965Sjdp    {
94233965Sjdp      char idbuf[20];
94333965Sjdp
94433965Sjdp      sprintf (idbuf, "%%anon%u", id);
94533965Sjdp      if (! append_type (info, idbuf))
94633965Sjdp	return false;
94733965Sjdp    }
94833965Sjdp
94933965Sjdp  if (! append_type (info, " {"))
95033965Sjdp    return false;
95133965Sjdp  if (size != 0 || tag != NULL)
95233965Sjdp    {
95333965Sjdp      char ab[30];
95433965Sjdp
95533965Sjdp      if (! append_type (info, " /*"))
95633965Sjdp	return false;
95733965Sjdp
95833965Sjdp      if (size != 0)
95933965Sjdp	{
96033965Sjdp	  sprintf (ab, " size %u", size);
96133965Sjdp	  if (! append_type (info, ab))
96233965Sjdp	    return false;
96333965Sjdp	}
96433965Sjdp      if (tag != NULL)
96533965Sjdp	{
96633965Sjdp	  sprintf (ab, " id %u", id);
96733965Sjdp	  if (! append_type (info, ab))
96833965Sjdp	    return false;
96933965Sjdp	}
97033965Sjdp      if (! append_type (info, " */"))
97133965Sjdp	return false;
97233965Sjdp    }
97333965Sjdp  if (! append_type (info, "\n"))
97433965Sjdp    return false;
97533965Sjdp
97633965Sjdp  info->stack->visibility = DEBUG_VISIBILITY_PUBLIC;
97733965Sjdp
97833965Sjdp  return indent_type (info);
97933965Sjdp}
98033965Sjdp
98133965Sjdp/* Output the visibility of a field in a struct.  */
98233965Sjdp
98333965Sjdpstatic boolean
98433965Sjdppr_fix_visibility (info, visibility)
98533965Sjdp     struct pr_handle *info;
98633965Sjdp     enum debug_visibility visibility;
98733965Sjdp{
98860484Sobrien  const char *s = NULL;
98933965Sjdp  char *t;
99033965Sjdp  unsigned int len;
99133965Sjdp
99233965Sjdp  assert (info->stack != NULL);
99333965Sjdp
99433965Sjdp  if (info->stack->visibility == visibility)
99533965Sjdp    return true;
99633965Sjdp
99733965Sjdp  assert (info->stack->visibility != DEBUG_VISIBILITY_IGNORE);
99833965Sjdp
99933965Sjdp  switch (visibility)
100033965Sjdp    {
100133965Sjdp    case DEBUG_VISIBILITY_PUBLIC:
100233965Sjdp      s = "public";
100333965Sjdp      break;
100433965Sjdp    case DEBUG_VISIBILITY_PRIVATE:
100533965Sjdp      s = "private";
100633965Sjdp      break;
100733965Sjdp    case DEBUG_VISIBILITY_PROTECTED:
100833965Sjdp      s = "protected";
100933965Sjdp      break;
101033965Sjdp    case DEBUG_VISIBILITY_IGNORE:
101133965Sjdp      s = "/* ignore */";
101233965Sjdp      break;
101333965Sjdp    default:
101433965Sjdp      abort ();
101533965Sjdp      return false;
101633965Sjdp    }
101733965Sjdp
101833965Sjdp  /* Trim off a trailing space in the struct string, to make the
101933965Sjdp     output look a bit better, then stick on the visibility string.  */
102033965Sjdp
102133965Sjdp  t = info->stack->type;
102233965Sjdp  len = strlen (t);
102333965Sjdp  assert (t[len - 1] == ' ');
102433965Sjdp  t[len - 1] = '\0';
102533965Sjdp
102633965Sjdp  if (! append_type (info, s)
102733965Sjdp      || ! append_type (info, ":\n")
102833965Sjdp      || ! indent_type (info))
102933965Sjdp    return false;
103033965Sjdp
103133965Sjdp  info->stack->visibility = visibility;
103233965Sjdp
103333965Sjdp  return true;
103433965Sjdp}
103533965Sjdp
103633965Sjdp/* Add a field to a struct type.  */
103733965Sjdp
103833965Sjdpstatic boolean
103933965Sjdppr_struct_field (p, name, bitpos, bitsize, visibility)
104033965Sjdp     PTR p;
104133965Sjdp     const char *name;
104233965Sjdp     bfd_vma bitpos;
104333965Sjdp     bfd_vma bitsize;
104433965Sjdp     enum debug_visibility visibility;
104533965Sjdp{
104633965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
104733965Sjdp  char ab[20];
104833965Sjdp  char *t;
104933965Sjdp
105033965Sjdp  if (! substitute_type (info, name))
105133965Sjdp    return false;
105233965Sjdp
105333965Sjdp  if (! append_type (info, "; /* "))
105433965Sjdp    return false;
105533965Sjdp
105633965Sjdp  if (bitsize != 0)
105733965Sjdp    {
105833965Sjdp      print_vma (bitsize, ab, true, false);
105933965Sjdp      if (! append_type (info, "bitsize ")
106033965Sjdp	  || ! append_type (info, ab)
106133965Sjdp	  || ! append_type (info, ", "))
106233965Sjdp	return false;
106333965Sjdp    }
106433965Sjdp
106533965Sjdp  print_vma (bitpos, ab, true, false);
106633965Sjdp  if (! append_type (info, "bitpos ")
106733965Sjdp      || ! append_type (info, ab)
106833965Sjdp      || ! append_type (info, " */\n")
106933965Sjdp      || ! indent_type (info))
107033965Sjdp    return false;
107133965Sjdp
107233965Sjdp  t = pop_type (info);
107333965Sjdp  if (t == NULL)
107433965Sjdp    return false;
107533965Sjdp
107633965Sjdp  if (! pr_fix_visibility (info, visibility))
107733965Sjdp    return false;
107833965Sjdp
107933965Sjdp  return append_type (info, t);
108033965Sjdp}
108133965Sjdp
108233965Sjdp/* Finish a struct type.  */
108333965Sjdp
108433965Sjdpstatic boolean
108533965Sjdppr_end_struct_type (p)
108633965Sjdp     PTR p;
108733965Sjdp{
108833965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
108933965Sjdp  char *s;
109033965Sjdp
109133965Sjdp  assert (info->stack != NULL);
109233965Sjdp  assert (info->indent >= 2);
109333965Sjdp
109433965Sjdp  info->indent -= 2;
109533965Sjdp
109633965Sjdp  /* Change the trailing indentation to have a close brace.  */
109733965Sjdp  s = info->stack->type + strlen (info->stack->type) - 2;
109833965Sjdp  assert (s[0] == ' ' && s[1] == ' ' && s[2] == '\0');
109933965Sjdp
110033965Sjdp  *s++ = '}';
110133965Sjdp  *s = '\0';
110233965Sjdp
110333965Sjdp  return true;
110433965Sjdp}
110533965Sjdp
110633965Sjdp/* Start a class type.  */
110733965Sjdp
110833965Sjdpstatic boolean
110933965Sjdppr_start_class_type (p, tag, id, structp, size, vptr, ownvptr)
111033965Sjdp     PTR p;
111133965Sjdp     const char *tag;
111233965Sjdp     unsigned int id;
111333965Sjdp     boolean structp;
111433965Sjdp     unsigned int size;
111533965Sjdp     boolean vptr;
111633965Sjdp     boolean ownvptr;
111733965Sjdp{
111833965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
111933965Sjdp  char *tv = NULL;
112033965Sjdp
112133965Sjdp  info->indent += 2;
112233965Sjdp
112333965Sjdp  if (vptr && ! ownvptr)
112433965Sjdp    {
112533965Sjdp      tv = pop_type (info);
112633965Sjdp      if (tv == NULL)
112733965Sjdp	return false;
112833965Sjdp    }
112933965Sjdp
113033965Sjdp  if (! push_type (info, structp ? "class " : "union class "))
113133965Sjdp    return false;
113233965Sjdp  if (tag != NULL)
113333965Sjdp    {
113433965Sjdp      if (! append_type (info, tag))
113533965Sjdp	return false;
113633965Sjdp    }
113733965Sjdp  else
113833965Sjdp    {
113933965Sjdp      char idbuf[20];
114033965Sjdp
114133965Sjdp      sprintf (idbuf, "%%anon%u", id);
114233965Sjdp      if (! append_type (info, idbuf))
114333965Sjdp	return false;
114433965Sjdp    }
114533965Sjdp
114633965Sjdp  if (! append_type (info, " {"))
114733965Sjdp    return false;
114833965Sjdp  if (size != 0 || vptr || ownvptr || tag != NULL)
114933965Sjdp    {
115033965Sjdp      if (! append_type (info, " /*"))
115133965Sjdp	return false;
115233965Sjdp
115333965Sjdp      if (size != 0)
115433965Sjdp	{
115533965Sjdp	  char ab[20];
115633965Sjdp
115733965Sjdp	  sprintf (ab, "%u", size);
115833965Sjdp	  if (! append_type (info, " size ")
115933965Sjdp	      || ! append_type (info, ab))
116033965Sjdp	    return false;
116133965Sjdp	}
116233965Sjdp
116333965Sjdp      if (vptr)
116433965Sjdp	{
116533965Sjdp	  if (! append_type (info, " vtable "))
116633965Sjdp	    return false;
116733965Sjdp	  if (ownvptr)
116833965Sjdp	    {
116933965Sjdp	      if (! append_type (info, "self "))
117033965Sjdp		return false;
117133965Sjdp	    }
117233965Sjdp	  else
117333965Sjdp	    {
117433965Sjdp	      if (! append_type (info, tv)
117533965Sjdp		  || ! append_type (info, " "))
117633965Sjdp		return false;
117733965Sjdp	    }
117833965Sjdp	}
117933965Sjdp
118033965Sjdp      if (tag != NULL)
118133965Sjdp	{
118233965Sjdp	  char ab[30];
118333965Sjdp
118433965Sjdp	  sprintf (ab, " id %u", id);
118533965Sjdp	  if (! append_type (info, ab))
118633965Sjdp	    return false;
118733965Sjdp	}
118833965Sjdp
118933965Sjdp      if (! append_type (info, " */"))
119033965Sjdp	return false;
119133965Sjdp    }
119233965Sjdp
119333965Sjdp  info->stack->visibility = DEBUG_VISIBILITY_PRIVATE;
119433965Sjdp
119533965Sjdp  return (append_type (info, "\n")
119633965Sjdp	  && indent_type (info));
119733965Sjdp}
119833965Sjdp
119933965Sjdp/* Add a static member to a class.  */
120033965Sjdp
120133965Sjdpstatic boolean
120233965Sjdppr_class_static_member (p, name, physname, visibility)
120333965Sjdp     PTR p;
120433965Sjdp     const char *name;
120533965Sjdp     const char *physname;
120633965Sjdp     enum debug_visibility visibility;
120733965Sjdp{
120833965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
120933965Sjdp  char *t;
121033965Sjdp
121133965Sjdp  if (! substitute_type (info, name))
121233965Sjdp    return false;
121333965Sjdp
121433965Sjdp  if (! prepend_type (info, "static ")
121533965Sjdp      || ! append_type (info, "; /* ")
121633965Sjdp      || ! append_type (info, physname)
121733965Sjdp      || ! append_type (info, " */\n")
121833965Sjdp      || ! indent_type (info))
121933965Sjdp    return false;
122033965Sjdp
122133965Sjdp  t = pop_type (info);
122233965Sjdp  if (t == NULL)
122333965Sjdp    return false;
122433965Sjdp
122533965Sjdp  if (! pr_fix_visibility (info, visibility))
122633965Sjdp    return false;
122733965Sjdp
122833965Sjdp  return append_type (info, t);
122933965Sjdp}
123033965Sjdp
123133965Sjdp/* Add a base class to a class.  */
123233965Sjdp
123333965Sjdpstatic boolean
123433965Sjdppr_class_baseclass (p, bitpos, virtual, visibility)
123533965Sjdp     PTR p;
123633965Sjdp     bfd_vma bitpos;
123733965Sjdp     boolean virtual;
123833965Sjdp     enum debug_visibility visibility;
123933965Sjdp{
124033965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
124133965Sjdp  char *t;
124233965Sjdp  const char *prefix;
124333965Sjdp  char ab[20];
124433965Sjdp  char *s, *l, *n;
124533965Sjdp
124633965Sjdp  assert (info->stack != NULL && info->stack->next != NULL);
124733965Sjdp
124833965Sjdp  if (! substitute_type (info, ""))
124933965Sjdp    return false;
125033965Sjdp
125133965Sjdp  t = pop_type (info);
125233965Sjdp  if (t == NULL)
125333965Sjdp    return false;
125433965Sjdp
125533965Sjdp  if (strncmp (t, "class ", sizeof "class " - 1) == 0)
125633965Sjdp    t += sizeof "class " - 1;
125733965Sjdp
125833965Sjdp  /* Push it back on to take advantage of the prepend_type and
125933965Sjdp     append_type routines.  */
126033965Sjdp  if (! push_type (info, t))
126133965Sjdp    return false;
126233965Sjdp
126333965Sjdp  if (virtual)
126433965Sjdp    {
126533965Sjdp      if (! prepend_type (info, "virtual "))
126633965Sjdp	return false;
126733965Sjdp    }
126833965Sjdp
126933965Sjdp  switch (visibility)
127033965Sjdp    {
127133965Sjdp    case DEBUG_VISIBILITY_PUBLIC:
127233965Sjdp      prefix = "public ";
127333965Sjdp      break;
127433965Sjdp    case DEBUG_VISIBILITY_PROTECTED:
127533965Sjdp      prefix = "protected ";
127633965Sjdp      break;
127733965Sjdp    case DEBUG_VISIBILITY_PRIVATE:
127833965Sjdp      prefix = "private ";
127933965Sjdp      break;
128033965Sjdp    default:
128133965Sjdp      prefix = "/* unknown visibility */ ";
128233965Sjdp      break;
128333965Sjdp    }
128433965Sjdp
128533965Sjdp  if (! prepend_type (info, prefix))
128633965Sjdp    return false;
128733965Sjdp
128833965Sjdp  if (bitpos != 0)
128933965Sjdp    {
129033965Sjdp      print_vma (bitpos, ab, true, false);
129133965Sjdp      if (! append_type (info, " /* bitpos ")
129233965Sjdp	  || ! append_type (info, ab)
129333965Sjdp	  || ! append_type (info, " */"))
129433965Sjdp	return false;
129533965Sjdp    }
129633965Sjdp
129733965Sjdp  /* Now the top of the stack is something like "public A / * bitpos
129833965Sjdp     10 * /".  The next element on the stack is something like "class
129933965Sjdp     xx { / * size 8 * /\n...".  We want to substitute the top of the
130033965Sjdp     stack in before the {.  */
130133965Sjdp  s = strchr (info->stack->next->type, '{');
130233965Sjdp  assert (s != NULL);
130333965Sjdp  --s;
130433965Sjdp
130533965Sjdp  /* If there is already a ':', then we already have a baseclass, and
130633965Sjdp     we must append this one after a comma.  */
130733965Sjdp  for (l = info->stack->next->type; l != s; l++)
130833965Sjdp    if (*l == ':')
130933965Sjdp      break;
131033965Sjdp  if (! prepend_type (info, l == s ? " : " : ", "))
131133965Sjdp    return false;
131233965Sjdp
131333965Sjdp  t = pop_type (info);
131433965Sjdp  if (t == NULL)
131533965Sjdp    return false;
131633965Sjdp
131733965Sjdp  n = (char *) xmalloc (strlen (info->stack->type) + strlen (t) + 1);
131833965Sjdp  memcpy (n, info->stack->type, s - info->stack->type);
131933965Sjdp  strcpy (n + (s - info->stack->type), t);
132033965Sjdp  strcat (n, s);
132133965Sjdp
132233965Sjdp  free (info->stack->type);
132333965Sjdp  info->stack->type = n;
132433965Sjdp
132533965Sjdp  free (t);
132633965Sjdp
132733965Sjdp  return true;
132833965Sjdp}
132933965Sjdp
133033965Sjdp/* Start adding a method to a class.  */
133133965Sjdp
133233965Sjdpstatic boolean
133333965Sjdppr_class_start_method (p, name)
133433965Sjdp     PTR p;
133533965Sjdp     const char *name;
133633965Sjdp{
133733965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
133833965Sjdp
133933965Sjdp  assert (info->stack != NULL);
134033965Sjdp  info->stack->method = name;
134133965Sjdp  return true;
134233965Sjdp}
134333965Sjdp
134433965Sjdp/* Add a variant to a method.  */
134533965Sjdp
134633965Sjdpstatic boolean
134733965Sjdppr_class_method_variant (p, physname, visibility, constp, volatilep, voffset,
134833965Sjdp			 context)
134933965Sjdp     PTR p;
135033965Sjdp     const char *physname;
135133965Sjdp     enum debug_visibility visibility;
135233965Sjdp     boolean constp;
135333965Sjdp     boolean volatilep;
135433965Sjdp     bfd_vma voffset;
135533965Sjdp     boolean context;
135633965Sjdp{
135733965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
135833965Sjdp  char *method_type;
135933965Sjdp  char *context_type;
136033965Sjdp
136133965Sjdp  assert (info->stack != NULL);
136233965Sjdp  assert (info->stack->next != NULL);
136333965Sjdp
136433965Sjdp  /* Put the const and volatile qualifiers on the type.  */
136533965Sjdp  if (volatilep)
136633965Sjdp    {
136733965Sjdp      if (! append_type (info, " volatile"))
136833965Sjdp	return false;
136933965Sjdp    }
137033965Sjdp  if (constp)
137133965Sjdp    {
137233965Sjdp      if (! append_type (info, " const"))
137333965Sjdp	return false;
137433965Sjdp    }
137533965Sjdp
137633965Sjdp  /* Stick the name of the method into its type.  */
137733965Sjdp  if (! substitute_type (info,
137833965Sjdp			 (context
137933965Sjdp			  ? info->stack->next->next->method
138033965Sjdp			  : info->stack->next->method)))
138133965Sjdp    return false;
138233965Sjdp
138333965Sjdp  /* Get the type.  */
138433965Sjdp  method_type = pop_type (info);
138533965Sjdp  if (method_type == NULL)
138633965Sjdp    return false;
138733965Sjdp
138833965Sjdp  /* Pull off the context type if there is one.  */
138933965Sjdp  if (! context)
139033965Sjdp    context_type = NULL;
139133965Sjdp  else
139233965Sjdp    {
139333965Sjdp      context_type = pop_type (info);
139433965Sjdp      if (context_type == NULL)
139533965Sjdp	return false;
139633965Sjdp    }
139733965Sjdp
139833965Sjdp  /* Now the top of the stack is the class.  */
139933965Sjdp
140033965Sjdp  if (! pr_fix_visibility (info, visibility))
140133965Sjdp    return false;
140233965Sjdp
140333965Sjdp  if (! append_type (info, method_type)
140433965Sjdp      || ! append_type (info, " /* ")
140533965Sjdp      || ! append_type (info, physname)
140633965Sjdp      || ! append_type (info, " "))
140733965Sjdp    return false;
140833965Sjdp  if (context || voffset != 0)
140933965Sjdp    {
141033965Sjdp      char ab[20];
141133965Sjdp
141233965Sjdp      if (context)
141333965Sjdp	{
141433965Sjdp	  if (! append_type (info, "context ")
141533965Sjdp	      || ! append_type (info, context_type)
141633965Sjdp	      || ! append_type (info, " "))
141733965Sjdp	    return false;
141833965Sjdp	}
141933965Sjdp      print_vma (voffset, ab, true, false);
142033965Sjdp      if (! append_type (info, "voffset ")
142133965Sjdp	  || ! append_type (info, ab))
142233965Sjdp	return false;
142333965Sjdp    }
142433965Sjdp
142533965Sjdp  return (append_type (info, " */;\n")
142633965Sjdp	  && indent_type (info));
142733965Sjdp}
142833965Sjdp
142933965Sjdp/* Add a static variant to a method.  */
143033965Sjdp
143133965Sjdpstatic boolean
143233965Sjdppr_class_static_method_variant (p, physname, visibility, constp, volatilep)
143333965Sjdp     PTR p;
143433965Sjdp     const char *physname;
143533965Sjdp     enum debug_visibility visibility;
143633965Sjdp     boolean constp;
143733965Sjdp     boolean volatilep;
143833965Sjdp{
143933965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
144033965Sjdp  char *method_type;
144133965Sjdp
144233965Sjdp  assert (info->stack != NULL);
144333965Sjdp  assert (info->stack->next != NULL);
144433965Sjdp  assert (info->stack->next->method != NULL);
144533965Sjdp
144633965Sjdp  /* Put the const and volatile qualifiers on the type.  */
144733965Sjdp  if (volatilep)
144833965Sjdp    {
144933965Sjdp      if (! append_type (info, " volatile"))
145033965Sjdp	return false;
145133965Sjdp    }
145233965Sjdp  if (constp)
145333965Sjdp    {
145433965Sjdp      if (! append_type (info, " const"))
145533965Sjdp	return false;
145633965Sjdp    }
145733965Sjdp
145833965Sjdp  /* Mark it as static.  */
145933965Sjdp  if (! prepend_type (info, "static "))
146033965Sjdp    return false;
146133965Sjdp
146233965Sjdp  /* Stick the name of the method into its type.  */
146333965Sjdp  if (! substitute_type (info, info->stack->next->method))
146433965Sjdp    return false;
146533965Sjdp
146633965Sjdp  /* Get the type.  */
146733965Sjdp  method_type = pop_type (info);
146833965Sjdp  if (method_type == NULL)
146933965Sjdp    return false;
147033965Sjdp
147133965Sjdp  /* Now the top of the stack is the class.  */
147233965Sjdp
147333965Sjdp  if (! pr_fix_visibility (info, visibility))
147433965Sjdp    return false;
147533965Sjdp
147633965Sjdp  return (append_type (info, method_type)
147733965Sjdp	  && append_type (info, " /* ")
147833965Sjdp	  && append_type (info, physname)
147933965Sjdp	  && append_type (info, " */;\n")
148033965Sjdp	  && indent_type (info));
148133965Sjdp}
148233965Sjdp
148333965Sjdp/* Finish up a method.  */
148433965Sjdp
148533965Sjdpstatic boolean
148633965Sjdppr_class_end_method (p)
148733965Sjdp     PTR p;
148833965Sjdp{
148933965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
149033965Sjdp
149133965Sjdp  info->stack->method = NULL;
149233965Sjdp  return true;
149333965Sjdp}
149433965Sjdp
149533965Sjdp/* Finish up a class.  */
149633965Sjdp
149733965Sjdpstatic boolean
149833965Sjdppr_end_class_type (p)
149933965Sjdp     PTR p;
150033965Sjdp{
150133965Sjdp  return pr_end_struct_type (p);
150233965Sjdp}
150333965Sjdp
150433965Sjdp/* Push a type on the stack using a typedef name.  */
150533965Sjdp
150633965Sjdpstatic boolean
150733965Sjdppr_typedef_type (p, name)
150833965Sjdp     PTR p;
150933965Sjdp     const char *name;
151033965Sjdp{
151133965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
151233965Sjdp
151333965Sjdp  return push_type (info, name);
151433965Sjdp}
151533965Sjdp
151633965Sjdp/* Push a type on the stack using a tag name.  */
151733965Sjdp
151833965Sjdpstatic boolean
151933965Sjdppr_tag_type (p, name, id, kind)
152033965Sjdp     PTR p;
152133965Sjdp     const char *name;
152233965Sjdp     unsigned int id;
152333965Sjdp     enum debug_type_kind kind;
152433965Sjdp{
152533965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
152633965Sjdp  const char *t, *tag;
152733965Sjdp  char idbuf[20];
152833965Sjdp
152933965Sjdp  switch (kind)
153033965Sjdp    {
153133965Sjdp    case DEBUG_KIND_STRUCT:
153233965Sjdp      t = "struct ";
153333965Sjdp      break;
153433965Sjdp    case DEBUG_KIND_UNION:
153533965Sjdp      t = "union ";
153633965Sjdp      break;
153733965Sjdp    case DEBUG_KIND_ENUM:
153833965Sjdp      t = "enum ";
153933965Sjdp      break;
154033965Sjdp    case DEBUG_KIND_CLASS:
154133965Sjdp      t = "class ";
154233965Sjdp      break;
154333965Sjdp    case DEBUG_KIND_UNION_CLASS:
154433965Sjdp      t = "union class ";
154533965Sjdp      break;
154633965Sjdp    default:
154733965Sjdp      abort ();
154833965Sjdp      return false;
154933965Sjdp    }
155033965Sjdp
155133965Sjdp  if (! push_type (info, t))
155233965Sjdp    return false;
155333965Sjdp  if (name != NULL)
155433965Sjdp    tag = name;
155533965Sjdp  else
155633965Sjdp    {
155733965Sjdp      sprintf (idbuf, "%%anon%u", id);
155833965Sjdp      tag = idbuf;
155933965Sjdp    }
156033965Sjdp
156133965Sjdp  if (! append_type (info, tag))
156233965Sjdp    return false;
156333965Sjdp  if (name != NULL && kind != DEBUG_KIND_ENUM)
156433965Sjdp    {
156533965Sjdp      sprintf (idbuf, " /* id %u */", id);
156633965Sjdp      if (! append_type (info, idbuf))
156733965Sjdp	return false;
156833965Sjdp    }
156933965Sjdp
157033965Sjdp  return true;
157133965Sjdp}
157233965Sjdp
157333965Sjdp/* Output a typedef.  */
157433965Sjdp
157533965Sjdpstatic boolean
157633965Sjdppr_typdef (p, name)
157733965Sjdp     PTR p;
157833965Sjdp     const char *name;
157933965Sjdp{
158033965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
158133965Sjdp  char *s;
158233965Sjdp
158333965Sjdp  if (! substitute_type (info, name))
158433965Sjdp    return false;
158533965Sjdp
158633965Sjdp  s = pop_type (info);
158733965Sjdp  if (s == NULL)
158833965Sjdp    return false;
158933965Sjdp
159033965Sjdp  indent (info);
159133965Sjdp  fprintf (info->f, "typedef %s;\n", s);
159233965Sjdp
159333965Sjdp  free (s);
159433965Sjdp
159533965Sjdp  return true;
159633965Sjdp}
159733965Sjdp
159833965Sjdp/* Output a tag.  The tag should already be in the string on the
159933965Sjdp   stack, so all we have to do here is print it out.  */
160033965Sjdp
160133965Sjdp/*ARGSUSED*/
160233965Sjdpstatic boolean
160333965Sjdppr_tag (p, name)
160433965Sjdp     PTR p;
160560484Sobrien     const char *name ATTRIBUTE_UNUSED;
160633965Sjdp{
160733965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
160833965Sjdp  char *t;
160933965Sjdp
161033965Sjdp  t = pop_type (info);
161133965Sjdp  if (t == NULL)
161233965Sjdp    return false;
161333965Sjdp
161433965Sjdp  indent (info);
161533965Sjdp  fprintf (info->f, "%s;\n", t);
161633965Sjdp
161733965Sjdp  free (t);
161833965Sjdp
161933965Sjdp  return true;
162033965Sjdp}
162133965Sjdp
162233965Sjdp/* Output an integer constant.  */
162333965Sjdp
162433965Sjdpstatic boolean
162533965Sjdppr_int_constant (p, name, val)
162633965Sjdp     PTR p;
162733965Sjdp     const char *name;
162833965Sjdp     bfd_vma val;
162933965Sjdp{
163033965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
163133965Sjdp  char ab[20];
163233965Sjdp
163333965Sjdp  indent (info);
163433965Sjdp  print_vma (val, ab, false, false);
163533965Sjdp  fprintf (info->f, "const int %s = %s;\n", name, ab);
163633965Sjdp  return true;
163733965Sjdp}
163833965Sjdp
163933965Sjdp/* Output a floating point constant.  */
164033965Sjdp
164133965Sjdpstatic boolean
164233965Sjdppr_float_constant (p, name, val)
164333965Sjdp     PTR p;
164433965Sjdp     const char *name;
164533965Sjdp     double val;
164633965Sjdp{
164733965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
164833965Sjdp
164933965Sjdp  indent (info);
165033965Sjdp  fprintf (info->f, "const double %s = %g;\n", name, val);
165133965Sjdp  return true;
165233965Sjdp}
165333965Sjdp
165433965Sjdp/* Output a typed constant.  */
165533965Sjdp
165633965Sjdpstatic boolean
165733965Sjdppr_typed_constant (p, name, val)
165833965Sjdp     PTR p;
165933965Sjdp     const char *name;
166033965Sjdp     bfd_vma val;
166133965Sjdp{
166233965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
166333965Sjdp  char *t;
166433965Sjdp  char ab[20];
166533965Sjdp
166633965Sjdp  t = pop_type (info);
166733965Sjdp  if (t == NULL)
166833965Sjdp    return false;
166933965Sjdp
167033965Sjdp  indent (info);
167133965Sjdp  print_vma (val, ab, false, false);
167233965Sjdp  fprintf (info->f, "const %s %s = %s;\n", t, name, ab);
167333965Sjdp
167433965Sjdp  free (t);
167533965Sjdp
167633965Sjdp  return true;
167733965Sjdp}
167833965Sjdp
167933965Sjdp/* Output a variable.  */
168033965Sjdp
168133965Sjdpstatic boolean
168233965Sjdppr_variable (p, name, kind, val)
168333965Sjdp     PTR p;
168433965Sjdp     const char *name;
168533965Sjdp     enum debug_var_kind kind;
168633965Sjdp     bfd_vma val;
168733965Sjdp{
168833965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
168933965Sjdp  char *t;
169033965Sjdp  char ab[20];
169133965Sjdp
169233965Sjdp  if (! substitute_type (info, name))
169333965Sjdp    return false;
169433965Sjdp
169533965Sjdp  t = pop_type (info);
169633965Sjdp  if (t == NULL)
169733965Sjdp    return false;
169833965Sjdp
169933965Sjdp  indent (info);
170033965Sjdp  switch (kind)
170133965Sjdp    {
170233965Sjdp    case DEBUG_STATIC:
170333965Sjdp    case DEBUG_LOCAL_STATIC:
170433965Sjdp      fprintf (info->f, "static ");
170533965Sjdp      break;
170633965Sjdp    case DEBUG_REGISTER:
170733965Sjdp      fprintf (info->f, "register ");
170833965Sjdp      break;
170933965Sjdp    default:
171033965Sjdp      break;
171133965Sjdp    }
171233965Sjdp  print_vma (val, ab, true, true);
171333965Sjdp  fprintf (info->f, "%s /* %s */;\n", t, ab);
171433965Sjdp
171533965Sjdp  free (t);
171633965Sjdp
171733965Sjdp  return true;
171833965Sjdp}
171933965Sjdp
172033965Sjdp/* Start outputting a function.  */
172133965Sjdp
172233965Sjdpstatic boolean
172333965Sjdppr_start_function (p, name, global)
172433965Sjdp     PTR p;
172533965Sjdp     const char *name;
172633965Sjdp     boolean global;
172733965Sjdp{
172833965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
172933965Sjdp  char *t;
173033965Sjdp
173133965Sjdp  if (! substitute_type (info, name))
173233965Sjdp    return false;
173333965Sjdp
173433965Sjdp  t = pop_type (info);
173533965Sjdp  if (t == NULL)
173633965Sjdp    return false;
173733965Sjdp
173833965Sjdp  indent (info);
173933965Sjdp  if (! global)
174033965Sjdp    fprintf (info->f, "static ");
174133965Sjdp  fprintf (info->f, "%s (", t);
174233965Sjdp
174333965Sjdp  info->parameter = 1;
174433965Sjdp
174533965Sjdp  return true;
174633965Sjdp}
174733965Sjdp
174833965Sjdp/* Output a function parameter.  */
174933965Sjdp
175033965Sjdpstatic boolean
175133965Sjdppr_function_parameter (p, name, kind, val)
175233965Sjdp     PTR p;
175333965Sjdp     const char *name;
175433965Sjdp     enum debug_parm_kind kind;
175533965Sjdp     bfd_vma val;
175633965Sjdp{
175733965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
175833965Sjdp  char *t;
175933965Sjdp  char ab[20];
176033965Sjdp
176133965Sjdp  if (kind == DEBUG_PARM_REFERENCE
176233965Sjdp      || kind == DEBUG_PARM_REF_REG)
176333965Sjdp    {
176433965Sjdp      if (! pr_reference_type (p))
176533965Sjdp	return false;
176633965Sjdp    }
176733965Sjdp
176833965Sjdp  if (! substitute_type (info, name))
176933965Sjdp    return false;
177033965Sjdp
177133965Sjdp  t = pop_type (info);
177233965Sjdp  if (t == NULL)
177333965Sjdp    return false;
177433965Sjdp
177533965Sjdp  if (info->parameter != 1)
177633965Sjdp    fprintf (info->f, ", ");
177733965Sjdp
177833965Sjdp  if (kind == DEBUG_PARM_REG || kind == DEBUG_PARM_REF_REG)
177933965Sjdp    fprintf (info->f, "register ");
178033965Sjdp
178133965Sjdp  print_vma (val, ab, true, true);
178233965Sjdp  fprintf (info->f, "%s /* %s */", t, ab);
178333965Sjdp
178433965Sjdp  free (t);
178533965Sjdp
178633965Sjdp  ++info->parameter;
178733965Sjdp
178833965Sjdp  return true;
178933965Sjdp}
179033965Sjdp
179133965Sjdp/* Start writing out a block.  */
179233965Sjdp
179333965Sjdpstatic boolean
179433965Sjdppr_start_block (p, addr)
179533965Sjdp     PTR p;
179633965Sjdp     bfd_vma addr;
179733965Sjdp{
179833965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
179933965Sjdp  char ab[20];
180033965Sjdp
180133965Sjdp  if (info->parameter > 0)
180233965Sjdp    {
180333965Sjdp      fprintf (info->f, ")\n");
180433965Sjdp      info->parameter = 0;
180533965Sjdp    }
180633965Sjdp
180733965Sjdp  indent (info);
180833965Sjdp  print_vma (addr, ab, true, true);
180933965Sjdp  fprintf (info->f, "{ /* %s */\n", ab);
181033965Sjdp
181133965Sjdp  info->indent += 2;
181233965Sjdp
181333965Sjdp  return true;
181433965Sjdp}
181533965Sjdp
181633965Sjdp/* Write out line number information.  */
181733965Sjdp
181833965Sjdpstatic boolean
181933965Sjdppr_lineno (p, filename, lineno, addr)
182033965Sjdp     PTR p;
182133965Sjdp     const char *filename;
182233965Sjdp     unsigned long lineno;
182333965Sjdp     bfd_vma addr;
182433965Sjdp{
182533965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
182633965Sjdp  char ab[20];
182733965Sjdp
182833965Sjdp  indent (info);
182933965Sjdp  print_vma (addr, ab, true, true);
183033965Sjdp  fprintf (info->f, "/* file %s line %lu addr %s */\n", filename, lineno, ab);
183133965Sjdp
183233965Sjdp  return true;
183333965Sjdp}
183433965Sjdp
183533965Sjdp/* Finish writing out a block.  */
183633965Sjdp
183733965Sjdpstatic boolean
183833965Sjdppr_end_block (p, addr)
183933965Sjdp     PTR p;
184033965Sjdp     bfd_vma addr;
184133965Sjdp{
184233965Sjdp  struct pr_handle *info = (struct pr_handle *) p;
184333965Sjdp  char ab[20];
184433965Sjdp
184533965Sjdp  info->indent -= 2;
184633965Sjdp
184733965Sjdp  indent (info);
184833965Sjdp  print_vma (addr, ab, true, true);
184933965Sjdp  fprintf (info->f, "} /* %s */\n", ab);
185033965Sjdp
185133965Sjdp  return true;
185233965Sjdp}
185333965Sjdp
185433965Sjdp/* Finish writing out a function.  */
185533965Sjdp
185633965Sjdp/*ARGSUSED*/
185733965Sjdpstatic boolean
185833965Sjdppr_end_function (p)
185960484Sobrien     PTR p ATTRIBUTE_UNUSED;
186033965Sjdp{
186133965Sjdp  return true;
186233965Sjdp}
1863