Back to index

cell-binutils  2.17cvs20070401
prdbg.c
Go to the documentation of this file.
00001 /* prdbg.c -- Print out generic debugging information.
00002    Copyright 1995, 1996, 1999, 2002, 2003, 2004, 2006
00003    Free Software Foundation, Inc.
00004    Written by Ian Lance Taylor <ian@cygnus.com>.
00005    Tags style generation written by Salvador E. Tropea <set@computer.org>.
00006 
00007    This file is part of GNU Binutils.
00008 
00009    This program is free software; you can redistribute it and/or modify
00010    it under the terms of the GNU General Public License as published by
00011    the Free Software Foundation; either version 2 of the License, or
00012    (at your option) any later version.
00013 
00014    This program is distributed in the hope that it will be useful,
00015    but WITHOUT ANY WARRANTY; without even the implied warranty of
00016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017    GNU General Public License for more details.
00018 
00019    You should have received a copy of the GNU General Public License
00020    along with this program; if not, write to the Free Software
00021    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
00022    02110-1301, USA.  */
00023 
00024 /* This file prints out the generic debugging information, by
00025    supplying a set of routines to debug_write.  */
00026 
00027 #include <stdio.h>
00028 #include <assert.h>
00029 
00030 #include "bfd.h"
00031 #include "bucomm.h"
00032 #include "libiberty.h"
00033 #include "debug.h"
00034 #include "budbg.h"
00035 
00036 /* This is the structure we use as a handle for these routines.  */
00037 
00038 struct pr_handle
00039 {
00040   /* File to print information to.  */
00041   FILE *f;
00042   /* Current indentation level.  */
00043   unsigned int indent;
00044   /* Type stack.  */
00045   struct pr_stack *stack;
00046   /* Parameter number we are about to output.  */
00047   int parameter;
00048   /* The following are used only by the tags code (tg_).  */
00049   /* Name of the file we are using.  */
00050   char *filename;
00051   /* The BFD.  */
00052   bfd *abfd;
00053   /* The symbols table for this BFD.  */
00054   asymbol **syms;
00055   /* Pointer to a function to demangle symbols.  */
00056   char *(*demangler) (bfd *, const char *);
00057 };
00058 
00059 /* The type stack.  */
00060 
00061 struct pr_stack
00062 {
00063   /* Next element on the stack.  */
00064   struct pr_stack *next;
00065   /* This element.  */
00066   char *type;
00067   /* Current visibility of fields if this is a class.  */
00068   enum debug_visibility visibility;
00069   /* Name of the current method we are handling.  */
00070   const char *method;
00071   /* The following are used only by the tags code (tg_).  */
00072   /* Type for the container (struct, union, class, union class).  */
00073   const char *flavor;
00074   /* A comma separated list of parent classes.  */
00075   char *parents;
00076   /* How many parents contains parents.  */
00077   int num_parents;
00078 };
00079 
00080 static void indent (struct pr_handle *);
00081 static bfd_boolean push_type (struct pr_handle *, const char *);
00082 static bfd_boolean prepend_type (struct pr_handle *, const char *);
00083 static bfd_boolean append_type (struct pr_handle *, const char *);
00084 static bfd_boolean substitute_type (struct pr_handle *, const char *);
00085 static bfd_boolean indent_type (struct pr_handle *);
00086 static char *pop_type (struct pr_handle *);
00087 static void print_vma (bfd_vma, char *, bfd_boolean, bfd_boolean);
00088 static bfd_boolean pr_fix_visibility
00089   (struct pr_handle *, enum debug_visibility);
00090 static bfd_boolean pr_start_compilation_unit (void *, const char *);
00091 static bfd_boolean pr_start_source (void *, const char *);
00092 static bfd_boolean pr_empty_type (void *);
00093 static bfd_boolean pr_void_type (void *);
00094 static bfd_boolean pr_int_type (void *, unsigned int, bfd_boolean);
00095 static bfd_boolean pr_float_type (void *, unsigned int);
00096 static bfd_boolean pr_complex_type (void *, unsigned int);
00097 static bfd_boolean pr_bool_type (void *, unsigned int);
00098 static bfd_boolean pr_enum_type
00099   (void *, const char *, const char **, bfd_signed_vma *);
00100 static bfd_boolean pr_pointer_type (void *);
00101 static bfd_boolean pr_function_type (void *, int, bfd_boolean);
00102 static bfd_boolean pr_reference_type (void *);
00103 static bfd_boolean pr_range_type (void *, bfd_signed_vma, bfd_signed_vma);
00104 static bfd_boolean pr_array_type
00105   (void *, bfd_signed_vma, bfd_signed_vma, bfd_boolean);
00106 static bfd_boolean pr_set_type (void *, bfd_boolean);
00107 static bfd_boolean pr_offset_type (void *);
00108 static bfd_boolean pr_method_type (void *, bfd_boolean, int, bfd_boolean);
00109 static bfd_boolean pr_const_type (void *);
00110 static bfd_boolean pr_volatile_type (void *);
00111 static bfd_boolean pr_start_struct_type
00112   (void *, const char *, unsigned int, bfd_boolean, unsigned int);
00113 static bfd_boolean pr_struct_field
00114   (void *, const char *, bfd_vma, bfd_vma, enum debug_visibility);
00115 static bfd_boolean pr_end_struct_type (void *);
00116 static bfd_boolean pr_start_class_type
00117   (void *, const char *, unsigned int, bfd_boolean, unsigned int,
00118    bfd_boolean, bfd_boolean);
00119 static bfd_boolean pr_class_static_member
00120   (void *, const char *, const char *, enum debug_visibility);
00121 static bfd_boolean pr_class_baseclass
00122   (void *, bfd_vma, bfd_boolean, enum debug_visibility);
00123 static bfd_boolean pr_class_start_method (void *, const char *);
00124 static bfd_boolean pr_class_method_variant
00125   (void *, const char *, enum debug_visibility, bfd_boolean, bfd_boolean,
00126    bfd_vma, bfd_boolean);
00127 static bfd_boolean pr_class_static_method_variant
00128   (void *, const char *, enum debug_visibility, bfd_boolean, bfd_boolean);
00129 static bfd_boolean pr_class_end_method (void *);
00130 static bfd_boolean pr_end_class_type (void *);
00131 static bfd_boolean pr_typedef_type (void *, const char *);
00132 static bfd_boolean pr_tag_type
00133   (void *, const char *, unsigned int, enum debug_type_kind);
00134 static bfd_boolean pr_typdef (void *, const char *);
00135 static bfd_boolean pr_tag (void *, const char *);
00136 static bfd_boolean pr_int_constant (void *, const char *, bfd_vma);
00137 static bfd_boolean pr_float_constant (void *, const char *, double);
00138 static bfd_boolean pr_typed_constant (void *, const char *, bfd_vma);
00139 static bfd_boolean pr_variable
00140   (void *, const char *, enum debug_var_kind, bfd_vma);
00141 static bfd_boolean pr_start_function (void *, const char *, bfd_boolean);
00142 static bfd_boolean pr_function_parameter
00143   (void *, const char *, enum debug_parm_kind, bfd_vma);
00144 static bfd_boolean pr_start_block (void *, bfd_vma);
00145 static bfd_boolean pr_end_block (void *, bfd_vma);
00146 static bfd_boolean pr_end_function (void *);
00147 static bfd_boolean pr_lineno (void *, const char *, unsigned long, bfd_vma);
00148 static bfd_boolean append_parent (struct pr_handle *, const char *);
00149 /* Only used by tg_ code.  */
00150 static bfd_boolean tg_fix_visibility
00151   (struct pr_handle *, enum debug_visibility);
00152 static void find_address_in_section (bfd *, asection *, void *);
00153 static void translate_addresses (bfd *, char *, FILE *, asymbol **);
00154 static const char *visibility_name (enum debug_visibility);
00155 /* Tags style replacements.  */
00156 static bfd_boolean tg_start_compilation_unit (void *, const char *);
00157 static bfd_boolean tg_start_source (void *, const char *);
00158 static bfd_boolean tg_enum_type
00159   (void *, const char *, const char **, bfd_signed_vma *);
00160 static bfd_boolean tg_start_struct_type
00161   (void *, const char *, unsigned int, bfd_boolean, unsigned int);
00162 static bfd_boolean pr_struct_field
00163   (void *, const char *, bfd_vma, bfd_vma, enum debug_visibility);
00164 static bfd_boolean tg_struct_field
00165   (void *, const char *, bfd_vma, bfd_vma, enum debug_visibility);
00166 static bfd_boolean tg_struct_field
00167   (void *, const char *, bfd_vma, bfd_vma, enum debug_visibility);
00168 static bfd_boolean tg_end_struct_type (void *);
00169 static bfd_boolean tg_start_class_type
00170   (void *, const char *, unsigned int, bfd_boolean, unsigned int, bfd_boolean, bfd_boolean);
00171 static bfd_boolean tg_class_static_member
00172   (void *, const char *, const char *, enum debug_visibility);
00173 static bfd_boolean tg_class_baseclass
00174   (void *, bfd_vma, bfd_boolean, enum debug_visibility);
00175 static bfd_boolean tg_class_method_variant
00176   (void *, const char *, enum debug_visibility, bfd_boolean, bfd_boolean, bfd_vma, bfd_boolean);
00177 static bfd_boolean tg_class_static_method_variant
00178   (void *, const char *, enum debug_visibility, bfd_boolean, bfd_boolean);
00179 static bfd_boolean tg_end_class_type (void *);
00180 static bfd_boolean tg_tag_type
00181   (void *, const char *, unsigned int, enum debug_type_kind);
00182 static bfd_boolean tg_typdef (void *, const char *);
00183 static bfd_boolean tg_tag (void *, const char *);
00184 static bfd_boolean tg_int_constant (void *, const char *, bfd_vma);
00185 static bfd_boolean tg_float_constant (void *, const char *, double);
00186 static bfd_boolean tg_typed_constant (void *, const char *, bfd_vma);
00187 static bfd_boolean tg_variable
00188   (void *, const char *, enum debug_var_kind, bfd_vma);
00189 static bfd_boolean tg_start_function (void *, const char *, bfd_boolean);
00190 static bfd_boolean tg_function_parameter
00191   (void *, const char *, enum debug_parm_kind, bfd_vma);
00192 static bfd_boolean tg_start_block (void *, bfd_vma);
00193 static bfd_boolean tg_end_block (void *, bfd_vma);
00194 static bfd_boolean tg_lineno (void *, const char *, unsigned long, bfd_vma);
00195 
00196 static const struct debug_write_fns pr_fns =
00197 {
00198   pr_start_compilation_unit,
00199   pr_start_source,
00200   pr_empty_type,
00201   pr_void_type,
00202   pr_int_type,
00203   pr_float_type,
00204   pr_complex_type,
00205   pr_bool_type,
00206   pr_enum_type,
00207   pr_pointer_type,
00208   pr_function_type,
00209   pr_reference_type,
00210   pr_range_type,
00211   pr_array_type,
00212   pr_set_type,
00213   pr_offset_type,
00214   pr_method_type,
00215   pr_const_type,
00216   pr_volatile_type,
00217   pr_start_struct_type,
00218   pr_struct_field,
00219   pr_end_struct_type,
00220   pr_start_class_type,
00221   pr_class_static_member,
00222   pr_class_baseclass,
00223   pr_class_start_method,
00224   pr_class_method_variant,
00225   pr_class_static_method_variant,
00226   pr_class_end_method,
00227   pr_end_class_type,
00228   pr_typedef_type,
00229   pr_tag_type,
00230   pr_typdef,
00231   pr_tag,
00232   pr_int_constant,
00233   pr_float_constant,
00234   pr_typed_constant,
00235   pr_variable,
00236   pr_start_function,
00237   pr_function_parameter,
00238   pr_start_block,
00239   pr_end_block,
00240   pr_end_function,
00241   pr_lineno
00242 };
00243 
00244 static const struct debug_write_fns tg_fns =
00245 {
00246   tg_start_compilation_unit,
00247   tg_start_source,
00248   pr_empty_type,            /* Same, push_type.  */
00249   pr_void_type,                    /* Same, push_type.  */
00250   pr_int_type,                     /* Same, push_type.  */
00251   pr_float_type,            /* Same, push_type.  */
00252   pr_complex_type,          /* Same, push_type.  */
00253   pr_bool_type,                    /* Same, push_type.  */
00254   tg_enum_type,
00255   pr_pointer_type,          /* Same, changes to pointer.  */
00256   pr_function_type,         /* Same, push_type.  */
00257   pr_reference_type,        /* Same, changes to reference.  */
00258   pr_range_type,            /* FIXME: What's that?.  */
00259   pr_array_type,            /* Same, push_type.  */
00260   pr_set_type,                     /* FIXME: What's that?.  */
00261   pr_offset_type,           /* FIXME: What's that?.  */
00262   pr_method_type,           /* Same.  */
00263   pr_const_type,            /* Same, changes to const.  */
00264   pr_volatile_type,         /* Same, changes to volatile.  */
00265   tg_start_struct_type,
00266   tg_struct_field,
00267   tg_end_struct_type,
00268   tg_start_class_type,
00269   tg_class_static_member,
00270   tg_class_baseclass,
00271   pr_class_start_method,    /* Same, remembers that's a method.  */
00272   tg_class_method_variant,
00273   tg_class_static_method_variant,
00274   pr_class_end_method,             /* Same, forgets that's a method.  */
00275   tg_end_class_type,
00276   pr_typedef_type,          /* Same, just push type.  */
00277   tg_tag_type,
00278   tg_typdef,
00279   tg_tag,
00280   tg_int_constant,          /* Untested.  */
00281   tg_float_constant,        /* Untested.  */
00282   tg_typed_constant,        /* Untested.  */
00283   tg_variable,
00284   tg_start_function,
00285   tg_function_parameter,
00286   tg_start_block,
00287   tg_end_block,
00288   pr_end_function,          /* Same, does nothing.  */
00289   tg_lineno
00290 };
00291 
00292 /* Print out the generic debugging information recorded in dhandle.  */
00293 
00294 bfd_boolean
00295 print_debugging_info (FILE *f, void *dhandle, bfd *abfd, asymbol **syms,
00296                     void *demangler, bfd_boolean as_tags)
00297 {
00298   struct pr_handle info;
00299 
00300   info.f = f;
00301   info.indent = 0;
00302   info.stack = NULL;
00303   info.parameter = 0;
00304   info.filename = NULL;
00305   info.abfd = abfd;
00306   info.syms = syms;
00307   info.demangler = demangler;
00308 
00309   if (as_tags)
00310     {
00311       fputs ("!_TAG_FILE_FORMAT\t2\t/extended format/\n", f);
00312       fputs ("!_TAG_FILE_SORTED\t0\t/0=unsorted, 1=sorted/\n", f);
00313       fputs ("!_TAG_PROGRAM_AUTHOR\tIan Lance Taylor, Salvador E. Tropea and others\t//\n", f);
00314       fputs ("!_TAG_PROGRAM_NAME\tobjdump\t/From GNU binutils/\n", f);
00315     }
00316 
00317   return as_tags ? debug_write (dhandle, &tg_fns, (void *) & info)
00318     : debug_write (dhandle, &pr_fns, (void *) & info);
00319 }
00320 
00321 /* Indent to the current indentation level.  */
00322 
00323 static void
00324 indent (struct pr_handle *info)
00325 {
00326   unsigned int i;
00327 
00328   for (i = 0; i < info->indent; i++)
00329     putc (' ', info->f);
00330 }
00331 
00332 /* Push a type on the type stack.  */
00333 
00334 static bfd_boolean
00335 push_type (struct pr_handle *info, const char *type)
00336 {
00337   struct pr_stack *n;
00338 
00339   if (type == NULL)
00340     return FALSE;
00341 
00342   n = (struct pr_stack *) xmalloc (sizeof *n);
00343   memset (n, 0, sizeof *n);
00344 
00345   n->type = xstrdup (type);
00346   n->visibility = DEBUG_VISIBILITY_IGNORE;
00347   n->method = NULL;
00348   n->next = info->stack;
00349   info->stack = n;
00350 
00351   return TRUE;
00352 }
00353 
00354 /* Prepend a string onto the type on the top of the type stack.  */
00355 
00356 static bfd_boolean
00357 prepend_type (struct pr_handle *info, const char *s)
00358 {
00359   char *n;
00360 
00361   assert (info->stack != NULL);
00362 
00363   n = (char *) xmalloc (strlen (s) + strlen (info->stack->type) + 1);
00364   sprintf (n, "%s%s", s, info->stack->type);
00365   free (info->stack->type);
00366   info->stack->type = n;
00367 
00368   return TRUE;
00369 }
00370 
00371 /* Append a string to the type on the top of the type stack.  */
00372 
00373 static bfd_boolean
00374 append_type (struct pr_handle *info, const char *s)
00375 {
00376   unsigned int len;
00377 
00378   if (s == NULL)
00379     return FALSE;
00380 
00381   assert (info->stack != NULL);
00382 
00383   len = strlen (info->stack->type);
00384   info->stack->type = (char *) xrealloc (info->stack->type,
00385                                     len + strlen (s) + 1);
00386   strcpy (info->stack->type + len, s);
00387 
00388   return TRUE;
00389 }
00390 
00391 /* Append a string to the parents on the top of the type stack.  */
00392 
00393 static bfd_boolean
00394 append_parent (struct pr_handle *info, const char *s)
00395 {
00396   unsigned int len;
00397 
00398   if (s == NULL)
00399     return FALSE;
00400 
00401   assert (info->stack != NULL);
00402 
00403   len = info->stack->parents ? strlen (info->stack->parents) : 0;
00404   info->stack->parents = (char *) xrealloc (info->stack->parents,
00405                                        len + strlen (s) + 1);
00406   strcpy (info->stack->parents + len, s);
00407 
00408   return TRUE;
00409 }
00410 
00411 /* We use an underscore to indicate where the name should go in a type
00412    string.  This function substitutes a string for the underscore.  If
00413    there is no underscore, the name follows the type.  */
00414 
00415 static bfd_boolean
00416 substitute_type (struct pr_handle *info, const char *s)
00417 {
00418   char *u;
00419 
00420   assert (info->stack != NULL);
00421 
00422   u = strchr (info->stack->type, '|');
00423   if (u != NULL)
00424     {
00425       char *n;
00426 
00427       n = (char *) xmalloc (strlen (info->stack->type) + strlen (s));
00428 
00429       memcpy (n, info->stack->type, u - info->stack->type);
00430       strcpy (n + (u - info->stack->type), s);
00431       strcat (n, u + 1);
00432 
00433       free (info->stack->type);
00434       info->stack->type = n;
00435 
00436       return TRUE;
00437     }
00438 
00439   if (strchr (s, '|') != NULL
00440       && (strchr (info->stack->type, '{') != NULL
00441          || strchr (info->stack->type, '(') != NULL))
00442     {
00443       if (! prepend_type (info, "(")
00444          || ! append_type (info, ")"))
00445        return FALSE;
00446     }
00447 
00448   if (*s == '\0')
00449     return TRUE;
00450 
00451   return (append_type (info, " ")
00452          && append_type (info, s));
00453 }
00454 
00455 /* Indent the type at the top of the stack by appending spaces.  */
00456 
00457 static bfd_boolean
00458 indent_type (struct pr_handle *info)
00459 {
00460   unsigned int i;
00461 
00462   for (i = 0; i < info->indent; i++)
00463     {
00464       if (! append_type (info, " "))
00465        return FALSE;
00466     }
00467 
00468   return TRUE;
00469 }
00470 
00471 /* Pop a type from the type stack.  */
00472 
00473 static char *
00474 pop_type (struct pr_handle *info)
00475 {
00476   struct pr_stack *o;
00477   char *ret;
00478 
00479   assert (info->stack != NULL);
00480 
00481   o = info->stack;
00482   info->stack = o->next;
00483   ret = o->type;
00484   free (o);
00485 
00486   return ret;
00487 }
00488 
00489 /* Print a VMA value into a string.  */
00490 
00491 static void
00492 print_vma (bfd_vma vma, char *buf, bfd_boolean unsignedp, bfd_boolean hexp)
00493 {
00494   if (sizeof (vma) <= sizeof (unsigned long))
00495     {
00496       if (hexp)
00497        sprintf (buf, "0x%lx", (unsigned long) vma);
00498       else if (unsignedp)
00499        sprintf (buf, "%lu", (unsigned long) vma);
00500       else
00501        sprintf (buf, "%ld", (long) vma);
00502     }
00503   else
00504     {
00505       buf[0] = '0';
00506       buf[1] = 'x';
00507       sprintf_vma (buf + 2, vma);
00508     }
00509 }
00510 
00511 /* Start a new compilation unit.  */
00512 
00513 static bfd_boolean
00514 pr_start_compilation_unit (void *p, const char *filename)
00515 {
00516   struct pr_handle *info = (struct pr_handle *) p;
00517 
00518   assert (info->indent == 0);
00519 
00520   fprintf (info->f, "%s:\n", filename);
00521 
00522   return TRUE;
00523 }
00524 
00525 /* Start a source file within a compilation unit.  */
00526 
00527 static bfd_boolean
00528 pr_start_source (void *p, const char *filename)
00529 {
00530   struct pr_handle *info = (struct pr_handle *) p;
00531 
00532   assert (info->indent == 0);
00533 
00534   fprintf (info->f, " %s:\n", filename);
00535 
00536   return TRUE;
00537 }
00538 
00539 /* Push an empty type onto the type stack.  */
00540 
00541 static bfd_boolean
00542 pr_empty_type (void *p)
00543 {
00544   struct pr_handle *info = (struct pr_handle *) p;
00545 
00546   return push_type (info, "<undefined>");
00547 }
00548 
00549 /* Push a void type onto the type stack.  */
00550 
00551 static bfd_boolean
00552 pr_void_type (void *p)
00553 {
00554   struct pr_handle *info = (struct pr_handle *) p;
00555 
00556   return push_type (info, "void");
00557 }
00558 
00559 /* Push an integer type onto the type stack.  */
00560 
00561 static bfd_boolean
00562 pr_int_type (void *p, unsigned int size, bfd_boolean unsignedp)
00563 {
00564   struct pr_handle *info = (struct pr_handle *) p;
00565   char ab[10];
00566 
00567   sprintf (ab, "%sint%d", unsignedp ? "u" : "", size * 8);
00568   return push_type (info, ab);
00569 }
00570 
00571 /* Push a floating type onto the type stack.  */
00572 
00573 static bfd_boolean
00574 pr_float_type (void *p, unsigned int size)
00575 {
00576   struct pr_handle *info = (struct pr_handle *) p;
00577   char ab[10];
00578 
00579   if (size == 4)
00580     return push_type (info, "float");
00581   else if (size == 8)
00582     return push_type (info, "double");
00583 
00584   sprintf (ab, "float%d", size * 8);
00585   return push_type (info, ab);
00586 }
00587 
00588 /* Push a complex type onto the type stack.  */
00589 
00590 static bfd_boolean
00591 pr_complex_type (void *p, unsigned int size)
00592 {
00593   struct pr_handle *info = (struct pr_handle *) p;
00594 
00595   if (! pr_float_type (p, size))
00596     return FALSE;
00597 
00598   return prepend_type (info, "complex ");
00599 }
00600 
00601 /* Push a bfd_boolean type onto the type stack.  */
00602 
00603 static bfd_boolean
00604 pr_bool_type (void *p, unsigned int size)
00605 {
00606   struct pr_handle *info = (struct pr_handle *) p;
00607   char ab[10];
00608 
00609   sprintf (ab, "bool%d", size * 8);
00610 
00611   return push_type (info, ab);
00612 }
00613 
00614 /* Push an enum type onto the type stack.  */
00615 
00616 static bfd_boolean
00617 pr_enum_type (void *p, const char *tag, const char **names,
00618              bfd_signed_vma *values)
00619 {
00620   struct pr_handle *info = (struct pr_handle *) p;
00621   unsigned int i;
00622   bfd_signed_vma val;
00623 
00624   if (! push_type (info, "enum "))
00625     return FALSE;
00626   if (tag != NULL)
00627     {
00628       if (! append_type (info, tag)
00629          || ! append_type (info, " "))
00630        return FALSE;
00631     }
00632   if (! append_type (info, "{ "))
00633     return FALSE;
00634 
00635   if (names == NULL)
00636     {
00637       if (! append_type (info, "/* undefined */"))
00638        return FALSE;
00639     }
00640   else
00641     {
00642       val = 0;
00643       for (i = 0; names[i] != NULL; i++)
00644        {
00645          if (i > 0)
00646            {
00647              if (! append_type (info, ", "))
00648               return FALSE;
00649            }
00650 
00651          if (! append_type (info, names[i]))
00652            return FALSE;
00653 
00654          if (values[i] != val)
00655            {
00656              char ab[20];
00657 
00658              print_vma (values[i], ab, FALSE, FALSE);
00659              if (! append_type (info, " = ")
00660                 || ! append_type (info, ab))
00661               return FALSE;
00662              val = values[i];
00663            }
00664 
00665          ++val;
00666        }
00667     }
00668 
00669   return append_type (info, " }");
00670 }
00671 
00672 /* Turn the top type on the stack into a pointer.  */
00673 
00674 static bfd_boolean
00675 pr_pointer_type (void *p)
00676 {
00677   struct pr_handle *info = (struct pr_handle *) p;
00678   char *s;
00679 
00680   assert (info->stack != NULL);
00681 
00682   s = strchr (info->stack->type, '|');
00683   if (s != NULL && s[1] == '[')
00684     return substitute_type (info, "(*|)");
00685   return substitute_type (info, "*|");
00686 }
00687 
00688 /* Turn the top type on the stack into a function returning that type.  */
00689 
00690 static bfd_boolean
00691 pr_function_type (void *p, int argcount, bfd_boolean varargs)
00692 {
00693   struct pr_handle *info = (struct pr_handle *) p;
00694   char **arg_types;
00695   unsigned int len;
00696   char *s;
00697 
00698   assert (info->stack != NULL);
00699 
00700   len = 10;
00701 
00702   if (argcount <= 0)
00703     {
00704       arg_types = NULL;
00705       len += 15;
00706     }
00707   else
00708     {
00709       int i;
00710 
00711       arg_types = (char **) xmalloc (argcount * sizeof *arg_types);
00712       for (i = argcount - 1; i >= 0; i--)
00713        {
00714          if (! substitute_type (info, ""))
00715            return FALSE;
00716          arg_types[i] = pop_type (info);
00717          if (arg_types[i] == NULL)
00718            return FALSE;
00719          len += strlen (arg_types[i]) + 2;
00720        }
00721       if (varargs)
00722        len += 5;
00723     }
00724 
00725   /* Now the return type is on the top of the stack.  */
00726 
00727   s = xmalloc (len);
00728   LITSTRCPY (s, "(|) (");
00729 
00730   if (argcount < 0)
00731     strcat (s, "/* unknown */");
00732   else
00733     {
00734       int i;
00735 
00736       for (i = 0; i < argcount; i++)
00737        {
00738          if (i > 0)
00739            strcat (s, ", ");
00740          strcat (s, arg_types[i]);
00741        }
00742       if (varargs)
00743        {
00744          if (i > 0)
00745            strcat (s, ", ");
00746          strcat (s, "...");
00747        }
00748       if (argcount > 0)
00749        free (arg_types);
00750     }
00751 
00752   strcat (s, ")");
00753 
00754   if (! substitute_type (info, s))
00755     return FALSE;
00756 
00757   free (s);
00758 
00759   return TRUE;
00760 }
00761 
00762 /* Turn the top type on the stack into a reference to that type.  */
00763 
00764 static bfd_boolean
00765 pr_reference_type (void *p)
00766 {
00767   struct pr_handle *info = (struct pr_handle *) p;
00768 
00769   assert (info->stack != NULL);
00770 
00771   return substitute_type (info, "&|");
00772 }
00773 
00774 /* Make a range type.  */
00775 
00776 static bfd_boolean
00777 pr_range_type (void *p, bfd_signed_vma lower, bfd_signed_vma upper)
00778 {
00779   struct pr_handle *info = (struct pr_handle *) p;
00780   char abl[20], abu[20];
00781 
00782   assert (info->stack != NULL);
00783 
00784   if (! substitute_type (info, ""))
00785     return FALSE;
00786 
00787   print_vma (lower, abl, FALSE, FALSE);
00788   print_vma (upper, abu, FALSE, FALSE);
00789 
00790   return (prepend_type (info, "range (")
00791          && append_type (info, "):")
00792          && append_type (info, abl)
00793          && append_type (info, ":")
00794          && append_type (info, abu));
00795 }
00796 
00797 /* Make an array type.  */
00798 
00799 static bfd_boolean
00800 pr_array_type (void *p, bfd_signed_vma lower, bfd_signed_vma upper,
00801               bfd_boolean stringp)
00802 {
00803   struct pr_handle *info = (struct pr_handle *) p;
00804   char *range_type;
00805   char abl[20], abu[20], ab[50];
00806 
00807   range_type = pop_type (info);
00808   if (range_type == NULL)
00809     return FALSE;
00810 
00811   if (lower == 0)
00812     {
00813       if (upper == -1)
00814        sprintf (ab, "|[]");
00815       else
00816        {
00817          print_vma (upper + 1, abu, FALSE, FALSE);
00818          sprintf (ab, "|[%s]", abu);
00819        }
00820     }
00821   else
00822     {
00823       print_vma (lower, abl, FALSE, FALSE);
00824       print_vma (upper, abu, FALSE, FALSE);
00825       sprintf (ab, "|[%s:%s]", abl, abu);
00826     }
00827 
00828   if (! substitute_type (info, ab))
00829     return FALSE;
00830 
00831   if (strcmp (range_type, "int") != 0)
00832     {
00833       if (! append_type (info, ":")
00834          || ! append_type (info, range_type))
00835        return FALSE;
00836     }
00837 
00838   if (stringp)
00839     {
00840       if (! append_type (info, " /* string */"))
00841        return FALSE;
00842     }
00843 
00844   return TRUE;
00845 }
00846 
00847 /* Make a set type.  */
00848 
00849 static bfd_boolean
00850 pr_set_type (void *p, bfd_boolean bitstringp)
00851 {
00852   struct pr_handle *info = (struct pr_handle *) p;
00853 
00854   if (! substitute_type (info, ""))
00855     return FALSE;
00856 
00857   if (! prepend_type (info, "set { ")
00858       || ! append_type (info, " }"))
00859     return FALSE;
00860 
00861   if (bitstringp)
00862     {
00863       if (! append_type (info, "/* bitstring */"))
00864        return FALSE;
00865     }
00866 
00867   return TRUE;
00868 }
00869 
00870 /* Make an offset type.  */
00871 
00872 static bfd_boolean
00873 pr_offset_type (void *p)
00874 {
00875   struct pr_handle *info = (struct pr_handle *) p;
00876   char *t;
00877 
00878   if (! substitute_type (info, ""))
00879     return FALSE;
00880 
00881   t = pop_type (info);
00882   if (t == NULL)
00883     return FALSE;
00884 
00885   return (substitute_type (info, "")
00886          && prepend_type (info, " ")
00887          && prepend_type (info, t)
00888          && append_type (info, "::|"));
00889 }
00890 
00891 /* Make a method type.  */
00892 
00893 static bfd_boolean
00894 pr_method_type (void *p, bfd_boolean domain, int argcount, bfd_boolean varargs)
00895 {
00896   struct pr_handle *info = (struct pr_handle *) p;
00897   unsigned int len;
00898   char *domain_type;
00899   char **arg_types;
00900   char *s;
00901 
00902   len = 10;
00903 
00904   if (! domain)
00905     domain_type = NULL;
00906   else
00907     {
00908       if (! substitute_type (info, ""))
00909        return FALSE;
00910       domain_type = pop_type (info);
00911       if (domain_type == NULL)
00912        return FALSE;
00913       if (CONST_STRNEQ (domain_type, "class ")
00914          && strchr (domain_type + sizeof "class " - 1, ' ') == NULL)
00915        domain_type += sizeof "class " - 1;
00916       else if (CONST_STRNEQ (domain_type, "union class ")
00917               && (strchr (domain_type + sizeof "union class " - 1, ' ')
00918                  == NULL))
00919        domain_type += sizeof "union class " - 1;
00920       len += strlen (domain_type);
00921     }
00922 
00923   if (argcount <= 0)
00924     {
00925       arg_types = NULL;
00926       len += 15;
00927     }
00928   else
00929     {
00930       int i;
00931 
00932       arg_types = (char **) xmalloc (argcount * sizeof *arg_types);
00933       for (i = argcount - 1; i >= 0; i--)
00934        {
00935          if (! substitute_type (info, ""))
00936            return FALSE;
00937          arg_types[i] = pop_type (info);
00938          if (arg_types[i] == NULL)
00939            return FALSE;
00940          len += strlen (arg_types[i]) + 2;
00941        }
00942       if (varargs)
00943        len += 5;
00944     }
00945 
00946   /* Now the return type is on the top of the stack.  */
00947 
00948   s = (char *) xmalloc (len);
00949   if (! domain)
00950     *s = '\0';
00951   else
00952     strcpy (s, domain_type);
00953   strcat (s, "::| (");
00954 
00955   if (argcount < 0)
00956     strcat (s, "/* unknown */");
00957   else
00958     {
00959       int i;
00960 
00961       for (i = 0; i < argcount; i++)
00962        {
00963          if (i > 0)
00964            strcat (s, ", ");
00965          strcat (s, arg_types[i]);
00966        }
00967       if (varargs)
00968        {
00969          if (i > 0)
00970            strcat (s, ", ");
00971          strcat (s, "...");
00972        }
00973       if (argcount > 0)
00974        free (arg_types);
00975     }
00976 
00977   strcat (s, ")");
00978 
00979   if (! substitute_type (info, s))
00980     return FALSE;
00981 
00982   free (s);
00983 
00984   return TRUE;
00985 }
00986 
00987 /* Make a const qualified type.  */
00988 
00989 static bfd_boolean
00990 pr_const_type (void *p)
00991 {
00992   struct pr_handle *info = (struct pr_handle *) p;
00993 
00994   return substitute_type (info, "const |");
00995 }
00996 
00997 /* Make a volatile qualified type.  */
00998 
00999 static bfd_boolean
01000 pr_volatile_type (void *p)
01001 {
01002   struct pr_handle *info = (struct pr_handle *) p;
01003 
01004   return substitute_type (info, "volatile |");
01005 }
01006 
01007 /* Start accumulating a struct type.  */
01008 
01009 static bfd_boolean
01010 pr_start_struct_type (void *p, const char *tag, unsigned int id,
01011                     bfd_boolean structp, unsigned int size)
01012 {
01013   struct pr_handle *info = (struct pr_handle *) p;
01014 
01015   info->indent += 2;
01016 
01017   if (! push_type (info, structp ? "struct " : "union "))
01018     return FALSE;
01019   if (tag != NULL)
01020     {
01021       if (! append_type (info, tag))
01022        return FALSE;
01023     }
01024   else
01025     {
01026       char idbuf[20];
01027 
01028       sprintf (idbuf, "%%anon%u", id);
01029       if (! append_type (info, idbuf))
01030        return FALSE;
01031     }
01032 
01033   if (! append_type (info, " {"))
01034     return FALSE;
01035   if (size != 0 || tag != NULL)
01036     {
01037       char ab[30];
01038 
01039       if (! append_type (info, " /*"))
01040        return FALSE;
01041 
01042       if (size != 0)
01043        {
01044          sprintf (ab, " size %u", size);
01045          if (! append_type (info, ab))
01046            return FALSE;
01047        }
01048       if (tag != NULL)
01049        {
01050          sprintf (ab, " id %u", id);
01051          if (! append_type (info, ab))
01052            return FALSE;
01053        }
01054       if (! append_type (info, " */"))
01055        return FALSE;
01056     }
01057   if (! append_type (info, "\n"))
01058     return FALSE;
01059 
01060   info->stack->visibility = DEBUG_VISIBILITY_PUBLIC;
01061 
01062   return indent_type (info);
01063 }
01064 
01065 /* Output the visibility of a field in a struct.  */
01066 
01067 static bfd_boolean
01068 pr_fix_visibility (struct pr_handle *info, enum debug_visibility visibility)
01069 {
01070   const char *s = NULL;
01071   char *t;
01072   unsigned int len;
01073 
01074   assert (info->stack != NULL);
01075 
01076   if (info->stack->visibility == visibility)
01077     return TRUE;
01078 
01079   switch (visibility)
01080     {
01081     case DEBUG_VISIBILITY_PUBLIC:
01082       s = "public";
01083       break;
01084     case DEBUG_VISIBILITY_PRIVATE:
01085       s = "private";
01086       break;
01087     case DEBUG_VISIBILITY_PROTECTED:
01088       s = "protected";
01089       break;
01090     case DEBUG_VISIBILITY_IGNORE:
01091       s = "/* ignore */";
01092       break;
01093     default:
01094       abort ();
01095       return FALSE;
01096     }
01097 
01098   /* Trim off a trailing space in the struct string, to make the
01099      output look a bit better, then stick on the visibility string.  */
01100 
01101   t = info->stack->type;
01102   len = strlen (t);
01103   assert (t[len - 1] == ' ');
01104   t[len - 1] = '\0';
01105 
01106   if (! append_type (info, s)
01107       || ! append_type (info, ":\n")
01108       || ! indent_type (info))
01109     return FALSE;
01110 
01111   info->stack->visibility = visibility;
01112 
01113   return TRUE;
01114 }
01115 
01116 /* Add a field to a struct type.  */
01117 
01118 static bfd_boolean
01119 pr_struct_field (void *p, const char *name, bfd_vma bitpos, bfd_vma bitsize,
01120                enum debug_visibility visibility)
01121 {
01122   struct pr_handle *info = (struct pr_handle *) p;
01123   char ab[20];
01124   char *t;
01125 
01126   if (! substitute_type (info, name))
01127     return FALSE;
01128 
01129   if (! append_type (info, "; /* "))
01130     return FALSE;
01131 
01132   if (bitsize != 0)
01133     {
01134       print_vma (bitsize, ab, TRUE, FALSE);
01135       if (! append_type (info, "bitsize ")
01136          || ! append_type (info, ab)
01137          || ! append_type (info, ", "))
01138        return FALSE;
01139     }
01140 
01141   print_vma (bitpos, ab, TRUE, FALSE);
01142   if (! append_type (info, "bitpos ")
01143       || ! append_type (info, ab)
01144       || ! append_type (info, " */\n")
01145       || ! indent_type (info))
01146     return FALSE;
01147 
01148   t = pop_type (info);
01149   if (t == NULL)
01150     return FALSE;
01151 
01152   if (! pr_fix_visibility (info, visibility))
01153     return FALSE;
01154 
01155   return append_type (info, t);
01156 }
01157 
01158 /* Finish a struct type.  */
01159 
01160 static bfd_boolean
01161 pr_end_struct_type (void *p)
01162 {
01163   struct pr_handle *info = (struct pr_handle *) p;
01164   char *s;
01165 
01166   assert (info->stack != NULL);
01167   assert (info->indent >= 2);
01168 
01169   info->indent -= 2;
01170 
01171   /* Change the trailing indentation to have a close brace.  */
01172   s = info->stack->type + strlen (info->stack->type) - 2;
01173   assert (s[0] == ' ' && s[1] == ' ' && s[2] == '\0');
01174 
01175   *s++ = '}';
01176   *s = '\0';
01177 
01178   return TRUE;
01179 }
01180 
01181 /* Start a class type.  */
01182 
01183 static bfd_boolean
01184 pr_start_class_type (void *p, const char *tag, unsigned int id,
01185                    bfd_boolean structp, unsigned int size,
01186                    bfd_boolean vptr, bfd_boolean ownvptr)
01187 {
01188   struct pr_handle *info = (struct pr_handle *) p;
01189   char *tv = NULL;
01190 
01191   info->indent += 2;
01192 
01193   if (vptr && ! ownvptr)
01194     {
01195       tv = pop_type (info);
01196       if (tv == NULL)
01197        return FALSE;
01198     }
01199 
01200   if (! push_type (info, structp ? "class " : "union class "))
01201     return FALSE;
01202   if (tag != NULL)
01203     {
01204       if (! append_type (info, tag))
01205        return FALSE;
01206     }
01207   else
01208     {
01209       char idbuf[20];
01210 
01211       sprintf (idbuf, "%%anon%u", id);
01212       if (! append_type (info, idbuf))
01213        return FALSE;
01214     }
01215 
01216   if (! append_type (info, " {"))
01217     return FALSE;
01218   if (size != 0 || vptr || ownvptr || tag != NULL)
01219     {
01220       if (! append_type (info, " /*"))
01221        return FALSE;
01222 
01223       if (size != 0)
01224        {
01225          char ab[20];
01226 
01227          sprintf (ab, "%u", size);
01228          if (! append_type (info, " size ")
01229              || ! append_type (info, ab))
01230            return FALSE;
01231        }
01232 
01233       if (vptr)
01234        {
01235          if (! append_type (info, " vtable "))
01236            return FALSE;
01237          if (ownvptr)
01238            {
01239              if (! append_type (info, "self "))
01240               return FALSE;
01241            }
01242          else
01243            {
01244              if (! append_type (info, tv)
01245                 || ! append_type (info, " "))
01246               return FALSE;
01247            }
01248        }
01249 
01250       if (tag != NULL)
01251        {
01252          char ab[30];
01253 
01254          sprintf (ab, " id %u", id);
01255          if (! append_type (info, ab))
01256            return FALSE;
01257        }
01258 
01259       if (! append_type (info, " */"))
01260        return FALSE;
01261     }
01262 
01263   info->stack->visibility = DEBUG_VISIBILITY_PRIVATE;
01264 
01265   return (append_type (info, "\n")
01266          && indent_type (info));
01267 }
01268 
01269 /* Add a static member to a class.  */
01270 
01271 static bfd_boolean
01272 pr_class_static_member (void *p, const char *name, const char *physname,
01273                      enum debug_visibility visibility)
01274 {
01275   struct pr_handle *info = (struct pr_handle *) p;
01276   char *t;
01277 
01278   if (! substitute_type (info, name))
01279     return FALSE;
01280 
01281   if (! prepend_type (info, "static ")
01282       || ! append_type (info, "; /* ")
01283       || ! append_type (info, physname)
01284       || ! append_type (info, " */\n")
01285       || ! indent_type (info))
01286     return FALSE;
01287 
01288   t = pop_type (info);
01289   if (t == NULL)
01290     return FALSE;
01291 
01292   if (! pr_fix_visibility (info, visibility))
01293     return FALSE;
01294 
01295   return append_type (info, t);
01296 }
01297 
01298 /* Add a base class to a class.  */
01299 
01300 static bfd_boolean
01301 pr_class_baseclass (void *p, bfd_vma bitpos, bfd_boolean virtual,
01302                   enum debug_visibility visibility)
01303 {
01304   struct pr_handle *info = (struct pr_handle *) p;
01305   char *t;
01306   const char *prefix;
01307   char ab[20];
01308   char *s, *l, *n;
01309 
01310   assert (info->stack != NULL && info->stack->next != NULL);
01311 
01312   if (! substitute_type (info, ""))
01313     return FALSE;
01314 
01315   t = pop_type (info);
01316   if (t == NULL)
01317     return FALSE;
01318 
01319   if (CONST_STRNEQ (t, "class "))
01320     t += sizeof "class " - 1;
01321 
01322   /* Push it back on to take advantage of the prepend_type and
01323      append_type routines.  */
01324   if (! push_type (info, t))
01325     return FALSE;
01326 
01327   if (virtual)
01328     {
01329       if (! prepend_type (info, "virtual "))
01330        return FALSE;
01331     }
01332 
01333   switch (visibility)
01334     {
01335     case DEBUG_VISIBILITY_PUBLIC:
01336       prefix = "public ";
01337       break;
01338     case DEBUG_VISIBILITY_PROTECTED:
01339       prefix = "protected ";
01340       break;
01341     case DEBUG_VISIBILITY_PRIVATE:
01342       prefix = "private ";
01343       break;
01344     default:
01345       prefix = "/* unknown visibility */ ";
01346       break;
01347     }
01348 
01349   if (! prepend_type (info, prefix))
01350     return FALSE;
01351 
01352   if (bitpos != 0)
01353     {
01354       print_vma (bitpos, ab, TRUE, FALSE);
01355       if (! append_type (info, " /* bitpos ")
01356          || ! append_type (info, ab)
01357          || ! append_type (info, " */"))
01358        return FALSE;
01359     }
01360 
01361   /* Now the top of the stack is something like "public A / * bitpos
01362      10 * /".  The next element on the stack is something like "class
01363      xx { / * size 8 * /\n...".  We want to substitute the top of the
01364      stack in before the {.  */
01365   s = strchr (info->stack->next->type, '{');
01366   assert (s != NULL);
01367   --s;
01368 
01369   /* If there is already a ':', then we already have a baseclass, and
01370      we must append this one after a comma.  */
01371   for (l = info->stack->next->type; l != s; l++)
01372     if (*l == ':')
01373       break;
01374   if (! prepend_type (info, l == s ? " : " : ", "))
01375     return FALSE;
01376 
01377   t = pop_type (info);
01378   if (t == NULL)
01379     return FALSE;
01380 
01381   n = (char *) xmalloc (strlen (info->stack->type) + strlen (t) + 1);
01382   memcpy (n, info->stack->type, s - info->stack->type);
01383   strcpy (n + (s - info->stack->type), t);
01384   strcat (n, s);
01385 
01386   free (info->stack->type);
01387   info->stack->type = n;
01388 
01389   free (t);
01390 
01391   return TRUE;
01392 }
01393 
01394 /* Start adding a method to a class.  */
01395 
01396 static bfd_boolean
01397 pr_class_start_method (void *p, const char *name)
01398 {
01399   struct pr_handle *info = (struct pr_handle *) p;
01400 
01401   assert (info->stack != NULL);
01402   info->stack->method = name;
01403   return TRUE;
01404 }
01405 
01406 /* Add a variant to a method.  */
01407 
01408 static bfd_boolean
01409 pr_class_method_variant (void *p, const char *physname,
01410                       enum debug_visibility visibility,
01411                       bfd_boolean constp, bfd_boolean volatilep,
01412                       bfd_vma voffset, bfd_boolean context)
01413 {
01414   struct pr_handle *info = (struct pr_handle *) p;
01415   char *method_type;
01416   char *context_type;
01417 
01418   assert (info->stack != NULL);
01419   assert (info->stack->next != NULL);
01420 
01421   /* Put the const and volatile qualifiers on the type.  */
01422   if (volatilep)
01423     {
01424       if (! append_type (info, " volatile"))
01425        return FALSE;
01426     }
01427   if (constp)
01428     {
01429       if (! append_type (info, " const"))
01430        return FALSE;
01431     }
01432 
01433   /* Stick the name of the method into its type.  */
01434   if (! substitute_type (info,
01435                       (context
01436                        ? info->stack->next->next->method
01437                        : info->stack->next->method)))
01438     return FALSE;
01439 
01440   /* Get the type.  */
01441   method_type = pop_type (info);
01442   if (method_type == NULL)
01443     return FALSE;
01444 
01445   /* Pull off the context type if there is one.  */
01446   if (! context)
01447     context_type = NULL;
01448   else
01449     {
01450       context_type = pop_type (info);
01451       if (context_type == NULL)
01452        return FALSE;
01453     }
01454 
01455   /* Now the top of the stack is the class.  */
01456 
01457   if (! pr_fix_visibility (info, visibility))
01458     return FALSE;
01459 
01460   if (! append_type (info, method_type)
01461       || ! append_type (info, " /* ")
01462       || ! append_type (info, physname)
01463       || ! append_type (info, " "))
01464     return FALSE;
01465   if (context || voffset != 0)
01466     {
01467       char ab[20];
01468 
01469       if (context)
01470        {
01471          if (! append_type (info, "context ")
01472              || ! append_type (info, context_type)
01473              || ! append_type (info, " "))
01474            return FALSE;
01475        }
01476       print_vma (voffset, ab, TRUE, FALSE);
01477       if (! append_type (info, "voffset ")
01478          || ! append_type (info, ab))
01479        return FALSE;
01480     }
01481 
01482   return (append_type (info, " */;\n")
01483          && indent_type (info));
01484 }
01485 
01486 /* Add a static variant to a method.  */
01487 
01488 static bfd_boolean
01489 pr_class_static_method_variant (void *p, const char *physname,
01490                             enum debug_visibility visibility,
01491                             bfd_boolean constp, bfd_boolean volatilep)
01492 {
01493   struct pr_handle *info = (struct pr_handle *) p;
01494   char *method_type;
01495 
01496   assert (info->stack != NULL);
01497   assert (info->stack->next != NULL);
01498   assert (info->stack->next->method != NULL);
01499 
01500   /* Put the const and volatile qualifiers on the type.  */
01501   if (volatilep)
01502     {
01503       if (! append_type (info, " volatile"))
01504        return FALSE;
01505     }
01506   if (constp)
01507     {
01508       if (! append_type (info, " const"))
01509        return FALSE;
01510     }
01511 
01512   /* Mark it as static.  */
01513   if (! prepend_type (info, "static "))
01514     return FALSE;
01515 
01516   /* Stick the name of the method into its type.  */
01517   if (! substitute_type (info, info->stack->next->method))
01518     return FALSE;
01519 
01520   /* Get the type.  */
01521   method_type = pop_type (info);
01522   if (method_type == NULL)
01523     return FALSE;
01524 
01525   /* Now the top of the stack is the class.  */
01526 
01527   if (! pr_fix_visibility (info, visibility))
01528     return FALSE;
01529 
01530   return (append_type (info, method_type)
01531          && append_type (info, " /* ")
01532          && append_type (info, physname)
01533          && append_type (info, " */;\n")
01534          && indent_type (info));
01535 }
01536 
01537 /* Finish up a method.  */
01538 
01539 static bfd_boolean
01540 pr_class_end_method (void *p)
01541 {
01542   struct pr_handle *info = (struct pr_handle *) p;
01543 
01544   info->stack->method = NULL;
01545   return TRUE;
01546 }
01547 
01548 /* Finish up a class.  */
01549 
01550 static bfd_boolean
01551 pr_end_class_type (void *p)
01552 {
01553   return pr_end_struct_type (p);
01554 }
01555 
01556 /* Push a type on the stack using a typedef name.  */
01557 
01558 static bfd_boolean
01559 pr_typedef_type (void *p, const char *name)
01560 {
01561   struct pr_handle *info = (struct pr_handle *) p;
01562 
01563   return push_type (info, name);
01564 }
01565 
01566 /* Push a type on the stack using a tag name.  */
01567 
01568 static bfd_boolean
01569 pr_tag_type (void *p, const char *name, unsigned int id,
01570             enum debug_type_kind kind)
01571 {
01572   struct pr_handle *info = (struct pr_handle *) p;
01573   const char *t, *tag;
01574   char idbuf[20];
01575 
01576   switch (kind)
01577     {
01578     case DEBUG_KIND_STRUCT:
01579       t = "struct ";
01580       break;
01581     case DEBUG_KIND_UNION:
01582       t = "union ";
01583       break;
01584     case DEBUG_KIND_ENUM:
01585       t = "enum ";
01586       break;
01587     case DEBUG_KIND_CLASS:
01588       t = "class ";
01589       break;
01590     case DEBUG_KIND_UNION_CLASS:
01591       t = "union class ";
01592       break;
01593     default:
01594       abort ();
01595       return FALSE;
01596     }
01597 
01598   if (! push_type (info, t))
01599     return FALSE;
01600   if (name != NULL)
01601     tag = name;
01602   else
01603     {
01604       sprintf (idbuf, "%%anon%u", id);
01605       tag = idbuf;
01606     }
01607 
01608   if (! append_type (info, tag))
01609     return FALSE;
01610   if (name != NULL && kind != DEBUG_KIND_ENUM)
01611     {
01612       sprintf (idbuf, " /* id %u */", id);
01613       if (! append_type (info, idbuf))
01614        return FALSE;
01615     }
01616 
01617   return TRUE;
01618 }
01619 
01620 /* Output a typedef.  */
01621 
01622 static bfd_boolean
01623 pr_typdef (void *p, const char *name)
01624 {
01625   struct pr_handle *info = (struct pr_handle *) p;
01626   char *s;
01627 
01628   if (! substitute_type (info, name))
01629     return FALSE;
01630 
01631   s = pop_type (info);
01632   if (s == NULL)
01633     return FALSE;
01634 
01635   indent (info);
01636   fprintf (info->f, "typedef %s;\n", s);
01637 
01638   free (s);
01639 
01640   return TRUE;
01641 }
01642 
01643 /* Output a tag.  The tag should already be in the string on the
01644    stack, so all we have to do here is print it out.  */
01645 
01646 static bfd_boolean
01647 pr_tag (void *p, const char *name ATTRIBUTE_UNUSED)
01648 {
01649   struct pr_handle *info = (struct pr_handle *) p;
01650   char *t;
01651 
01652   t = pop_type (info);
01653   if (t == NULL)
01654     return FALSE;
01655 
01656   indent (info);
01657   fprintf (info->f, "%s;\n", t);
01658 
01659   free (t);
01660 
01661   return TRUE;
01662 }
01663 
01664 /* Output an integer constant.  */
01665 
01666 static bfd_boolean
01667 pr_int_constant (void *p, const char *name, bfd_vma val)
01668 {
01669   struct pr_handle *info = (struct pr_handle *) p;
01670   char ab[20];
01671 
01672   indent (info);
01673   print_vma (val, ab, FALSE, FALSE);
01674   fprintf (info->f, "const int %s = %s;\n", name, ab);
01675   return TRUE;
01676 }
01677 
01678 /* Output a floating point constant.  */
01679 
01680 static bfd_boolean
01681 pr_float_constant (void *p, const char *name, double val)
01682 {
01683   struct pr_handle *info = (struct pr_handle *) p;
01684 
01685   indent (info);
01686   fprintf (info->f, "const double %s = %g;\n", name, val);
01687   return TRUE;
01688 }
01689 
01690 /* Output a typed constant.  */
01691 
01692 static bfd_boolean
01693 pr_typed_constant (void *p, const char *name, bfd_vma val)
01694 {
01695   struct pr_handle *info = (struct pr_handle *) p;
01696   char *t;
01697   char ab[20];
01698 
01699   t = pop_type (info);
01700   if (t == NULL)
01701     return FALSE;
01702 
01703   indent (info);
01704   print_vma (val, ab, FALSE, FALSE);
01705   fprintf (info->f, "const %s %s = %s;\n", t, name, ab);
01706 
01707   free (t);
01708 
01709   return TRUE;
01710 }
01711 
01712 /* Output a variable.  */
01713 
01714 static bfd_boolean
01715 pr_variable (void *p, const char *name, enum debug_var_kind kind,
01716             bfd_vma val)
01717 {
01718   struct pr_handle *info = (struct pr_handle *) p;
01719   char *t;
01720   char ab[20];
01721 
01722   if (! substitute_type (info, name))
01723     return FALSE;
01724 
01725   t = pop_type (info);
01726   if (t == NULL)
01727     return FALSE;
01728 
01729   indent (info);
01730   switch (kind)
01731     {
01732     case DEBUG_STATIC:
01733     case DEBUG_LOCAL_STATIC:
01734       fprintf (info->f, "static ");
01735       break;
01736     case DEBUG_REGISTER:
01737       fprintf (info->f, "register ");
01738       break;
01739     default:
01740       break;
01741     }
01742   print_vma (val, ab, TRUE, TRUE);
01743   fprintf (info->f, "%s /* %s */;\n", t, ab);
01744 
01745   free (t);
01746 
01747   return TRUE;
01748 }
01749 
01750 /* Start outputting a function.  */
01751 
01752 static bfd_boolean
01753 pr_start_function (void *p, const char *name, bfd_boolean global)
01754 {
01755   struct pr_handle *info = (struct pr_handle *) p;
01756   char *t;
01757 
01758   if (! substitute_type (info, name))
01759     return FALSE;
01760 
01761   t = pop_type (info);
01762   if (t == NULL)
01763     return FALSE;
01764 
01765   indent (info);
01766   if (! global)
01767     fprintf (info->f, "static ");
01768   fprintf (info->f, "%s (", t);
01769 
01770   info->parameter = 1;
01771 
01772   return TRUE;
01773 }
01774 
01775 /* Output a function parameter.  */
01776 
01777 static bfd_boolean
01778 pr_function_parameter (void *p, const char *name,
01779                      enum debug_parm_kind kind, bfd_vma val)
01780 {
01781   struct pr_handle *info = (struct pr_handle *) p;
01782   char *t;
01783   char ab[20];
01784 
01785   if (kind == DEBUG_PARM_REFERENCE
01786       || kind == DEBUG_PARM_REF_REG)
01787     {
01788       if (! pr_reference_type (p))
01789        return FALSE;
01790     }
01791 
01792   if (! substitute_type (info, name))
01793     return FALSE;
01794 
01795   t = pop_type (info);
01796   if (t == NULL)
01797     return FALSE;
01798 
01799   if (info->parameter != 1)
01800     fprintf (info->f, ", ");
01801 
01802   if (kind == DEBUG_PARM_REG || kind == DEBUG_PARM_REF_REG)
01803     fprintf (info->f, "register ");
01804 
01805   print_vma (val, ab, TRUE, TRUE);
01806   fprintf (info->f, "%s /* %s */", t, ab);
01807 
01808   free (t);
01809 
01810   ++info->parameter;
01811 
01812   return TRUE;
01813 }
01814 
01815 /* Start writing out a block.  */
01816 
01817 static bfd_boolean
01818 pr_start_block (void *p, bfd_vma addr)
01819 {
01820   struct pr_handle *info = (struct pr_handle *) p;
01821   char ab[20];
01822 
01823   if (info->parameter > 0)
01824     {
01825       fprintf (info->f, ")\n");
01826       info->parameter = 0;
01827     }
01828 
01829   indent (info);
01830   print_vma (addr, ab, TRUE, TRUE);
01831   fprintf (info->f, "{ /* %s */\n", ab);
01832 
01833   info->indent += 2;
01834 
01835   return TRUE;
01836 }
01837 
01838 /* Write out line number information.  */
01839 
01840 static bfd_boolean
01841 pr_lineno (void *p, const char *filename, unsigned long lineno, bfd_vma addr)
01842 {
01843   struct pr_handle *info = (struct pr_handle *) p;
01844   char ab[20];
01845 
01846   indent (info);
01847   print_vma (addr, ab, TRUE, TRUE);
01848   fprintf (info->f, "/* file %s line %lu addr %s */\n", filename, lineno, ab);
01849 
01850   return TRUE;
01851 }
01852 
01853 /* Finish writing out a block.  */
01854 
01855 static bfd_boolean
01856 pr_end_block (void *p, bfd_vma addr)
01857 {
01858   struct pr_handle *info = (struct pr_handle *) p;
01859   char ab[20];
01860 
01861   info->indent -= 2;
01862 
01863   indent (info);
01864   print_vma (addr, ab, TRUE, TRUE);
01865   fprintf (info->f, "} /* %s */\n", ab);
01866 
01867   return TRUE;
01868 }
01869 
01870 /* Finish writing out a function.  */
01871 
01872 static bfd_boolean
01873 pr_end_function (void *p ATTRIBUTE_UNUSED)
01874 {
01875   return TRUE;
01876 }
01877 
01878 /* Tags style generation functions start here.  */
01879 
01880 /* Variables for address to line translation.  */
01881 static bfd_vma pc;
01882 static const char *filename;
01883 static const char *functionname;
01884 static unsigned int line;
01885 static bfd_boolean found;
01886 
01887 /* Look for an address in a section.  This is called via
01888    bfd_map_over_sections.  */
01889 
01890 static void
01891 find_address_in_section (bfd *abfd, asection *section, void *data)
01892 {
01893   bfd_vma vma;
01894   bfd_size_type size;
01895   asymbol **syms = (asymbol **) data;
01896 
01897   if (found)
01898     return;
01899 
01900   if ((bfd_get_section_flags (abfd, section) & SEC_ALLOC) == 0)
01901     return;
01902 
01903   vma = bfd_get_section_vma (abfd, section);
01904   if (pc < vma)
01905     return;
01906 
01907   size = bfd_get_section_size (section);
01908   if (pc >= vma + size)
01909     return;
01910 
01911   found = bfd_find_nearest_line (abfd, section, syms, pc - vma,
01912                              &filename, &functionname, &line);
01913 }
01914 
01915 static void
01916 translate_addresses (bfd *abfd, char *addr_hex, FILE *f, asymbol **syms)
01917 {
01918   pc = bfd_scan_vma (addr_hex, NULL, 16);
01919   found = FALSE;
01920   bfd_map_over_sections (abfd, find_address_in_section, syms);
01921 
01922   if (! found)
01923     fprintf (f, "??");
01924   else
01925     fprintf (f, "%u", line);
01926 }
01927 
01928 /* Start a new compilation unit.  */
01929 
01930 static bfd_boolean
01931 tg_start_compilation_unit (void * p, const char *filename ATTRIBUTE_UNUSED)
01932 {
01933   struct pr_handle *info = (struct pr_handle *) p;
01934 
01935   fprintf (stderr, "New compilation unit: %s\n", filename);
01936 
01937   free (info->filename);
01938   /* Should it be relative? best way to do it here?.  */
01939   info->filename = strdup (filename);
01940 
01941   return TRUE;
01942 }
01943 
01944 /* Start a source file within a compilation unit.  */
01945 
01946 static bfd_boolean
01947 tg_start_source (void *p, const char *filename)
01948 {
01949   struct pr_handle *info = (struct pr_handle *) p;
01950 
01951   free (info->filename);
01952   /* Should it be relative? best way to do it here?.  */
01953   info->filename = strdup (filename);
01954 
01955   return TRUE;
01956 }
01957 
01958 /* Push an enum type onto the type stack.  */
01959 
01960 static bfd_boolean
01961 tg_enum_type (void *p, const char *tag, const char **names,
01962              bfd_signed_vma *values)
01963 {
01964   struct pr_handle *info = (struct pr_handle *) p;
01965   unsigned int i;
01966   const char *name;
01967   char ab[20];
01968 
01969   if (! pr_enum_type (p, tag, names, values))
01970     return FALSE;
01971 
01972   name = tag ? tag : "unknown";
01973   /* Generate an entry for the enum.  */
01974   if (tag)
01975     fprintf (info->f, "%s\t%s\t0;\"\tkind:e\ttype:%s\n", tag,
01976             info->filename, info->stack->type);
01977 
01978   /* Generate entries for the values.  */
01979   if (names != NULL)
01980     {
01981       for (i = 0; names[i] != NULL; i++)
01982        {
01983          print_vma (values[i], ab, FALSE, FALSE);
01984          fprintf (info->f, "%s\t%s\t0;\"\tkind:g\tenum:%s\tvalue:%s\n",
01985                  names[i], info->filename, name, ab);
01986        }
01987     }
01988 
01989   return TRUE;
01990 }
01991 
01992 /* Start accumulating a struct type.  */
01993 
01994 static bfd_boolean
01995 tg_start_struct_type (void *p, const char *tag, unsigned int id,
01996                     bfd_boolean structp,
01997                     unsigned int size ATTRIBUTE_UNUSED)
01998 {
01999   struct pr_handle *info = (struct pr_handle *) p;
02000   const char *name;
02001   char idbuf[20];
02002 
02003   if (tag != NULL)
02004     name = tag;
02005   else
02006     {
02007       name = idbuf;
02008       sprintf (idbuf, "%%anon%u", id);
02009     }
02010 
02011   if (! push_type (info, name))
02012     return FALSE;
02013 
02014   info->stack->flavor = structp ? "struct" : "union";
02015 
02016   fprintf (info->f, "%s\t%s\t0;\"\tkind:%c\n", name, info->filename,
02017           info->stack->flavor[0]);
02018 
02019   info->stack->visibility = DEBUG_VISIBILITY_PUBLIC;
02020 
02021   return indent_type (info);
02022 }
02023 
02024 /* Output the visibility of a field in a struct.  */
02025 
02026 static bfd_boolean
02027 tg_fix_visibility (struct pr_handle *info, enum debug_visibility visibility)
02028 {
02029   assert (info->stack != NULL);
02030 
02031   if (info->stack->visibility == visibility)
02032     return TRUE;
02033 
02034   assert (info->stack->visibility != DEBUG_VISIBILITY_IGNORE);
02035 
02036   info->stack->visibility = visibility;
02037 
02038   return TRUE;
02039 }
02040 
02041 /* Add a field to a struct type.  */
02042 
02043 static bfd_boolean
02044 tg_struct_field (void *p, const char *name, bfd_vma bitpos ATTRIBUTE_UNUSED,
02045                bfd_vma bitsize ATTRIBUTE_UNUSED,
02046                enum debug_visibility visibility)
02047 {
02048   struct pr_handle *info = (struct pr_handle *) p;
02049   char *t;
02050 
02051   t = pop_type (info);
02052   if (t == NULL)
02053     return FALSE;
02054 
02055   if (! tg_fix_visibility (info, visibility))
02056     return FALSE;
02057 
02058   /* It happens, a bug? */
02059   if (! name[0])
02060     return TRUE;
02061 
02062   fprintf (info->f, "%s\t%s\t0;\"\tkind:m\ttype:%s\t%s:%s\taccess:%s\n",
02063           name, info->filename, t, info->stack->flavor, info->stack->type,
02064           visibility_name (visibility));
02065 
02066   return TRUE;
02067 }
02068 
02069 /* Finish a struct type.  */
02070 
02071 static bfd_boolean
02072 tg_end_struct_type (void *p ATTRIBUTE_UNUSED)
02073 {
02074   struct pr_handle *info = (struct pr_handle *) p;
02075   assert (info->stack != NULL);
02076 
02077   return TRUE;
02078 }
02079 
02080 /* Start a class type.  */
02081 
02082 static bfd_boolean
02083 tg_start_class_type (void *p, const char *tag, unsigned int id,
02084                    bfd_boolean structp, unsigned int size,
02085                    bfd_boolean vptr, bfd_boolean ownvptr)
02086 {
02087   struct pr_handle *info = (struct pr_handle *) p;
02088   char *tv = NULL;
02089   const char *name;
02090 
02091   info->indent += 2;
02092 
02093   if (vptr && ! ownvptr)
02094     {
02095       tv = pop_type (info);
02096       if (tv == NULL)
02097        return FALSE;
02098     }
02099 
02100   if (tag != NULL)
02101     name = tag;
02102   else
02103     {
02104       char idbuf[20];
02105 
02106       sprintf (idbuf, "%%anon%u", id);
02107       name = idbuf;
02108     }
02109 
02110   if (! push_type (info, name))
02111     return FALSE;
02112 
02113   info->stack->flavor = structp ? "class" : "union class";
02114   info->stack->parents = NULL;
02115   info->stack->num_parents = 0;
02116 
02117   if (size != 0 || vptr || ownvptr || tag != NULL)
02118     {
02119       if (vptr)
02120        {
02121          if (! append_type (info, " vtable "))
02122            return FALSE;
02123          if (ownvptr)
02124            {
02125              if (! append_type (info, "self "))
02126               return FALSE;
02127            }
02128          else
02129            {
02130              if (! append_type (info, tv)
02131                 || ! append_type (info, " "))
02132               return FALSE;
02133            }
02134        }
02135     }
02136 
02137   info->stack->visibility = DEBUG_VISIBILITY_PRIVATE;
02138 
02139   return TRUE;
02140 }
02141 
02142 /* Add a static member to a class.  */
02143 
02144 static bfd_boolean
02145 tg_class_static_member (void *p, const char *name,
02146                      const char *physname ATTRIBUTE_UNUSED,
02147                      enum debug_visibility visibility)
02148 {
02149   struct pr_handle *info = (struct pr_handle *) p;
02150   char *t;
02151   int len_var, len_class;
02152   char *full_name;
02153 
02154   len_var = strlen (name);
02155   len_class = strlen (info->stack->next->type);
02156   full_name = xmalloc (len_var + len_class + 3);
02157   if (! full_name)
02158     return FALSE;
02159   sprintf (full_name, "%s::%s", info->stack->next->type, name);
02160 
02161   if (! substitute_type (info, full_name))
02162     return FALSE;
02163 
02164   if (! prepend_type (info, "static "))
02165     return FALSE;
02166 
02167   t = pop_type (info);
02168   if (t == NULL)
02169     return FALSE;
02170 
02171   if (! tg_fix_visibility (info, visibility))
02172     return FALSE;
02173 
02174   fprintf (info->f, "%s\t%s\t0;\"\tkind:x\ttype:%s\tclass:%s\taccess:%s\n",
02175           name, info->filename, t, info->stack->type,
02176           visibility_name (visibility));
02177   free (t);
02178   free (full_name);
02179 
02180   return TRUE;
02181 }
02182 
02183 /* Add a base class to a class.  */
02184 
02185 static bfd_boolean
02186 tg_class_baseclass (void *p, bfd_vma bitpos ATTRIBUTE_UNUSED,
02187                   bfd_boolean virtual, enum debug_visibility visibility)
02188 {
02189   struct pr_handle *info = (struct pr_handle *) p;
02190   char *t;
02191   const char *prefix;
02192 
02193   assert (info->stack != NULL && info->stack->next != NULL);
02194 
02195   t = pop_type (info);
02196   if (t == NULL)
02197     return FALSE;
02198 
02199   if (CONST_STRNEQ (t, "class "))
02200     t += sizeof "class " - 1;
02201 
02202   /* Push it back on to take advantage of the prepend_type and
02203      append_type routines.  */
02204   if (! push_type (info, t))
02205     return FALSE;
02206 
02207   if (virtual)
02208     {
02209       if (! prepend_type (info, "virtual "))
02210        return FALSE;
02211     }
02212 
02213   switch (visibility)
02214     {
02215     case DEBUG_VISIBILITY_PUBLIC:
02216       prefix = "public ";
02217       break;
02218     case DEBUG_VISIBILITY_PROTECTED:
02219       prefix = "protected ";
02220       break;
02221     case DEBUG_VISIBILITY_PRIVATE:
02222       prefix = "private ";
02223       break;
02224     default:
02225       prefix = "/* unknown visibility */ ";
02226       break;
02227     }
02228 
02229   if (! prepend_type (info, prefix))
02230     return FALSE;
02231 
02232   t = pop_type (info);
02233   if (t == NULL)
02234     return FALSE;
02235 
02236   if (info->stack->num_parents && ! append_parent (info, ", "))
02237     return FALSE;
02238 
02239   if (! append_parent (info, t))
02240     return FALSE;
02241   info->stack->num_parents++;
02242 
02243   free (t);
02244 
02245   return TRUE;
02246 }
02247 
02248 /* Add a variant to a method.  */
02249 
02250 static bfd_boolean
02251 tg_class_method_variant (void *p, const char *physname ATTRIBUTE_UNUSED,
02252                       enum debug_visibility visibility,
02253                       bfd_boolean constp, bfd_boolean volatilep,
02254                       bfd_vma voffset ATTRIBUTE_UNUSED,
02255                       bfd_boolean context)
02256 {
02257   struct pr_handle *info = (struct pr_handle *) p;
02258   char *method_type;
02259   char *context_type;
02260   char *method_name;
02261 
02262   assert (info->stack != NULL);
02263   assert (info->stack->next != NULL);
02264 
02265   /* Put the const and volatile qualifiers on the type.  */
02266   if (volatilep)
02267     {
02268       if (! append_type (info, " volatile"))
02269        return FALSE;
02270     }
02271   if (constp)
02272     {
02273       if (! append_type (info, " const"))
02274        return FALSE;
02275     }
02276 
02277   method_name = strdup (context ? info->stack->next->next->method
02278                      : info->stack->next->method);
02279 
02280   /* Stick the name of the method into its type.  */
02281   if (! substitute_type (info, method_name))
02282     return FALSE;
02283 
02284   /* Get the type.  */
02285   method_type = pop_type (info);
02286   if (method_type == NULL)
02287     return FALSE;
02288 
02289   /* Pull off the context type if there is one.  */
02290   if (! context)
02291     context_type = NULL;
02292   else
02293     {
02294       context_type = pop_type (info);
02295       if (context_type == NULL)
02296        return FALSE;
02297     }
02298 
02299   /* Now the top of the stack is the class.  */
02300   if (! tg_fix_visibility (info, visibility))
02301     return FALSE;
02302 
02303   fprintf (info->f, "%s\t%s\t0;\"\tkind:p\ttype:%s\tclass:%s\n",
02304           method_name, info->filename, method_type, info->stack->type);
02305   free (method_type);
02306   free (method_name);
02307   free (context_type);
02308 
02309   return TRUE;
02310 }
02311 
02312 /* Add a static variant to a method.  */
02313 
02314 static bfd_boolean
02315 tg_class_static_method_variant (void *p,
02316                             const char *physname ATTRIBUTE_UNUSED,
02317                             enum debug_visibility visibility,
02318                             bfd_boolean constp, bfd_boolean volatilep)
02319 {
02320   struct pr_handle *info = (struct pr_handle *) p;
02321   char *method_type;
02322   char *method_name;
02323 
02324   assert (info->stack != NULL);
02325   assert (info->stack->next != NULL);
02326   assert (info->stack->next->method != NULL);
02327 
02328   /* Put the const and volatile qualifiers on the type.  */
02329   if (volatilep)
02330     {
02331       if (! append_type (info, " volatile"))
02332        return FALSE;
02333     }
02334   if (constp)
02335     {
02336       if (! append_type (info, " const"))
02337        return FALSE;
02338     }
02339 
02340   /* Mark it as static.  */
02341   if (! prepend_type (info, "static "))
02342     return FALSE;
02343 
02344   method_name = strdup (info->stack->next->method);
02345   /* Stick the name of the method into its type.  */
02346   if (! substitute_type (info, info->stack->next->method))
02347     return FALSE;
02348 
02349   /* Get the type.  */
02350   method_type = pop_type (info);
02351   if (method_type == NULL)
02352     return FALSE;
02353 
02354   /* Now the top of the stack is the class.  */
02355   if (! tg_fix_visibility (info, visibility))
02356     return FALSE;
02357 
02358   fprintf (info->f, "%s\t%s\t0;\"\tkind:p\ttype:%s\tclass:%s\taccess:%s\n",
02359           method_name, info->filename, method_type, info->stack->type,
02360           visibility_name (visibility));
02361   free (method_type);
02362   free (method_name);
02363 
02364   return TRUE;
02365 }
02366 
02367 /* Finish up a class.  */
02368 
02369 static bfd_boolean
02370 tg_end_class_type (void *p)
02371 {
02372   struct pr_handle *info = (struct pr_handle *) p;
02373 
02374   fprintf (info->f, "%s\t%s\t0;\"\tkind:c\ttype:%s", info->stack->type,
02375           info->filename, info->stack->flavor);
02376   if (info->stack->num_parents)
02377     {
02378       fprintf  (info->f, "\tinherits:%s", info->stack->parents);
02379       free (info->stack->parents);
02380     }
02381   fputc ('\n', info->f);
02382 
02383   return tg_end_struct_type (p);
02384 }
02385 
02386 /* Push a type on the stack using a tag name.  */
02387 
02388 static bfd_boolean
02389 tg_tag_type (void *p, const char *name, unsigned int id,
02390             enum debug_type_kind kind)
02391 {
02392   struct pr_handle *info = (struct pr_handle *) p;
02393   const char *t, *tag;
02394   char idbuf[20];
02395 
02396   switch (kind)
02397     {
02398     case DEBUG_KIND_STRUCT:
02399       t = "struct ";
02400       break;
02401     case DEBUG_KIND_UNION:
02402       t = "union ";
02403       break;
02404     case DEBUG_KIND_ENUM:
02405       t = "enum ";
02406       break;
02407     case DEBUG_KIND_CLASS:
02408       t = "class ";
02409       break;
02410     case DEBUG_KIND_UNION_CLASS:
02411       t = "union class ";
02412       break;
02413     default:
02414       abort ();
02415       return FALSE;
02416     }
02417 
02418   if (! push_type (info, t))
02419     return FALSE;
02420   if (name != NULL)
02421     tag = name;
02422   else
02423     {
02424       sprintf (idbuf, "%%anon%u", id);
02425       tag = idbuf;
02426     }
02427 
02428   if (! append_type (info, tag))
02429     return FALSE;
02430 
02431   return TRUE;
02432 }
02433 
02434 /* Output a typedef.  */
02435 
02436 static bfd_boolean
02437 tg_typdef (void *p, const char *name)
02438 {
02439   struct pr_handle *info = (struct pr_handle *) p;
02440   char *s;
02441 
02442   s = pop_type (info);
02443   if (s == NULL)
02444     return FALSE;
02445 
02446   fprintf (info->f, "%s\t%s\t0;\"\tkind:t\ttype:%s\n", name,
02447           info->filename, s);
02448 
02449   free (s);
02450 
02451   return TRUE;
02452 }
02453 
02454 /* Output a tag.  The tag should already be in the string on the
02455    stack, so all we have to do here is print it out.  */
02456 
02457 static bfd_boolean
02458 tg_tag (void *p ATTRIBUTE_UNUSED, const char *name ATTRIBUTE_UNUSED)
02459 {
02460   struct pr_handle *info = (struct pr_handle *) p;
02461   char *t;
02462 
02463   t = pop_type (info);
02464   if (t == NULL)
02465     return FALSE;
02466   free (t);
02467 
02468   return TRUE;
02469 }
02470 
02471 /* Output an integer constant.  */
02472 
02473 static bfd_boolean
02474 tg_int_constant (void *p, const char *name, bfd_vma val)
02475 {
02476   struct pr_handle *info = (struct pr_handle *) p;
02477   char ab[20];
02478 
02479   indent (info);
02480   print_vma (val, ab, FALSE, FALSE);
02481   fprintf (info->f, "%s\t%s\t0;\"\tkind:v\ttype:const int\tvalue:%s\n",
02482           name, info->filename, ab);
02483   return TRUE;
02484 }
02485 
02486 /* Output a floating point constant.  */
02487 
02488 static bfd_boolean
02489 tg_float_constant (void *p, const char *name, double val)
02490 {
02491   struct pr_handle *info = (struct pr_handle *) p;
02492 
02493   indent (info);
02494   fprintf (info->f, "%s\t%s\t0;\"\tkind:v\ttype:const double\tvalue:%g\n",
02495           name, info->filename, val);
02496   return TRUE;
02497 }
02498 
02499 /* Output a typed constant.  */
02500 
02501 static bfd_boolean
02502 tg_typed_constant (void *p, const char *name, bfd_vma val)
02503 {
02504   struct pr_handle *info = (struct pr_handle *) p;
02505   char *t;
02506   char ab[20];
02507 
02508   t = pop_type (info);
02509   if (t == NULL)
02510     return FALSE;
02511 
02512   indent (info);
02513   print_vma (val, ab, FALSE, FALSE);
02514   fprintf (info->f, "%s\t%s\t0;\"\tkind:v\ttype:const %s\tvalue:%s\n",
02515           name, info->filename, t, ab);
02516 
02517   free (t);
02518 
02519   return TRUE;
02520 }
02521 
02522 /* Output a variable.  */
02523 
02524 static bfd_boolean
02525 tg_variable (void *p, const char *name, enum debug_var_kind kind,
02526             bfd_vma val ATTRIBUTE_UNUSED)
02527 {
02528   struct pr_handle *info = (struct pr_handle *) p;
02529   char *t;
02530   const char *dname, *from_class;
02531 
02532   t = pop_type (info);
02533   if (t == NULL)
02534     return FALSE;
02535 
02536   dname = name;
02537   if (info->demangler)
02538     {
02539       dname = info->demangler (info->abfd, name);
02540       if (strcmp (name, dname) == 0)
02541        {
02542          free ((char *) dname);
02543          dname = name;
02544        }
02545     }
02546 
02547   if (dname != name)
02548     {
02549       char *sep;
02550       sep = strstr (dname, "::");
02551       if (sep)
02552        {
02553          *sep = 0;
02554          name = sep + 2;
02555          from_class = dname;
02556        }
02557       else
02558        {
02559          /* Obscure types as vts and type_info nodes.  */
02560          name = dname;
02561          from_class = NULL;
02562        }
02563     }
02564   else
02565     from_class = NULL;
02566 
02567   fprintf (info->f, "%s\t%s\t0;\"\tkind:v\ttype:%s", name, info->filename, t);
02568 
02569   switch (kind)
02570     {
02571     case DEBUG_STATIC:
02572     case DEBUG_LOCAL_STATIC:
02573       fprintf (info->f, "\tfile:");
02574       break;
02575     case DEBUG_REGISTER:
02576       fprintf (info->f, "\tregister:");
02577       break;
02578     default:
02579       break;
02580     }
02581 
02582   if (from_class)
02583     {
02584       fprintf (info->f, "\tclass:%s",from_class);
02585       free ((char *) dname);
02586     }
02587 
02588   fprintf (info->f, "\n");
02589 
02590   free (t);
02591 
02592   return TRUE;
02593 }
02594 
02595 /* Start outputting a function.  */
02596 
02597 static bfd_boolean
02598 tg_start_function (void *p, const char *name, bfd_boolean global)
02599 {
02600   struct pr_handle *info = (struct pr_handle *) p;
02601   const char *dname;
02602 
02603   if (! global)
02604     info->stack->flavor = "static";
02605   else
02606     info->stack->flavor = NULL;
02607 
02608   dname = name;
02609   if (info->demangler)
02610     {
02611       dname = info->demangler (info->abfd, name);
02612       if (strcmp (name, dname) == 0)
02613        {
02614          free ((char *) dname);
02615          dname = name;
02616        }
02617     }
02618 
02619   if (! substitute_type (info, dname))
02620     return FALSE;
02621 
02622   if (dname != name)
02623     {
02624       char *sep;
02625       sep = strstr (dname, "::");
02626       if (sep)
02627        {
02628          info->stack->method = dname;
02629          *sep = 0;
02630          name = sep + 2;
02631        }
02632       else
02633        {
02634          info->stack->method = "";
02635          name = dname;
02636        }
02637       sep = strchr (name, '(');
02638       if (sep)
02639        *sep = 0;
02640       /* Obscure functions as type_info function.  */
02641     }
02642   else
02643     info->stack->method = NULL;
02644 
02645   info->stack->parents = strdup (name);
02646 
02647   if (! info->stack->method && ! append_type (info, "("))
02648     return FALSE;
02649 
02650   info->parameter = 1;
02651 
02652   return TRUE;
02653 }
02654 
02655 /* Output a function parameter.  */
02656 
02657 static bfd_boolean
02658 tg_function_parameter (void *p, const char *name, enum debug_parm_kind kind,
02659                      bfd_vma val ATTRIBUTE_UNUSED)
02660 {
02661   struct pr_handle *info = (struct pr_handle *) p;
02662   char *t;
02663 
02664   if (kind == DEBUG_PARM_REFERENCE
02665       || kind == DEBUG_PARM_REF_REG)
02666     {
02667       if (! pr_reference_type (p))
02668        return FALSE;
02669     }
02670 
02671   if (! substitute_type (info, name))
02672     return FALSE;
02673 
02674   t = pop_type (info);
02675   if (t == NULL)
02676     return FALSE;
02677 
02678   if (! info->stack->method)
02679     {
02680       if (info->parameter != 1 && ! append_type (info, ", "))
02681        return FALSE;
02682 
02683       if (kind == DEBUG_PARM_REG || kind == DEBUG_PARM_REF_REG)
02684        if (! append_type (info, "register "))
02685          return FALSE;
02686 
02687       if (! append_type (info, t))
02688        return FALSE;
02689     }
02690 
02691   free (t);
02692 
02693   ++info->parameter;
02694 
02695   return TRUE;
02696 }
02697 
02698 /* Start writing out a block.  */
02699 
02700 static bfd_boolean
02701 tg_start_block (void *p, bfd_vma addr)
02702 {
02703   struct pr_handle *info = (struct pr_handle *) p;
02704   char ab[20], kind, *partof;
02705   char *t;
02706   bfd_boolean local;
02707 
02708   if (info->parameter > 0)
02709     {
02710       info->parameter = 0;
02711 
02712       /* Delayed name.  */
02713       fprintf (info->f, "%s\t%s\t", info->stack->parents, info->filename);
02714       free (info->stack->parents);
02715 
02716       print_vma (addr, ab, TRUE, TRUE);
02717       translate_addresses (info->abfd, ab, info->f, info->syms);
02718       local = info->stack->flavor != NULL;
02719       if (info->stack->method && *info->stack->method)
02720        {
02721          kind = 'm';
02722          partof = (char *) info->stack->method;
02723        }
02724       else
02725        {
02726          kind = 'f';
02727          partof = NULL;
02728          if (! info->stack->method && ! append_type (info, ")"))
02729            return FALSE;
02730        }
02731       t = pop_type (info);
02732       if (t == NULL)
02733        return FALSE;
02734       fprintf (info->f, ";\"\tkind:%c\ttype:%s", kind, t);
02735       if (local)
02736        fputs ("\tfile:", info->f);
02737       if (partof)
02738        {
02739          fprintf (info->f, "\tclass:%s", partof);
02740          free (partof);
02741        }
02742       fputc ('\n', info->f);
02743     }
02744 
02745   return TRUE;
02746 }
02747 
02748 /* Write out line number information.  */
02749 
02750 static bfd_boolean
02751 tg_lineno (void *p ATTRIBUTE_UNUSED, const char *filename ATTRIBUTE_UNUSED,
02752           unsigned long lineno ATTRIBUTE_UNUSED,
02753           bfd_vma addr ATTRIBUTE_UNUSED)
02754 {
02755   return TRUE;
02756 }
02757 
02758 /* Finish writing out a block.  */
02759 
02760 static bfd_boolean
02761 tg_end_block (void *p ATTRIBUTE_UNUSED, bfd_vma addr ATTRIBUTE_UNUSED)
02762 {
02763   return TRUE;
02764 }
02765 
02766 /* Convert the visibility value into a human readable name.  */
02767 
02768 static const char *
02769 visibility_name (enum debug_visibility visibility)
02770 {
02771   const char *s;
02772 
02773   switch (visibility)
02774     {
02775     case DEBUG_VISIBILITY_PUBLIC:
02776       s = "public";
02777       break;
02778     case DEBUG_VISIBILITY_PRIVATE:
02779       s = "private";
02780       break;
02781     case DEBUG_VISIBILITY_PROTECTED:
02782       s = "protected";
02783       break;
02784     case DEBUG_VISIBILITY_IGNORE:
02785       s = "/* ignore */";
02786       break;
02787     default:
02788       abort ();
02789       return FALSE;
02790     }
02791   return s;
02792 }