mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-27 14:39:09 +08:00
* debug.h (struct debug_write_fns): Add tag parameter to
enum_type, start_struct_type, and start_class_type. * debug.c (debug_write_type): Pass any tag name to start_struct_type, debug_write_class_type, and enum_type. If DEBUG_KIND_TAGGED, pass the name in the recursive call. (debug_write_class_type): Accept a new tag parameter, and pass it to start_class_type. * prdbg.c (pop_type): Don't remove '+' character. (pr_enum_type): Accept and use tag parameter. (pr_start_struct_type): Likewise. (pr_start_class_type): Likewise. (pr_class_baseclass): Adjust algorithm used to find where to put the baseclass name. (pr_tag): Don't bother to insert the tag name.
This commit is contained in:
111
binutils/debug.c
111
binutils/debug.c
@ -1,5 +1,5 @@
|
||||
/* debug.c -- Handle generic debugging information.
|
||||
Copyright (C) 1995 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
Written by Ian Lance Taylor <ian@cygnus.com>.
|
||||
|
||||
This file is part of GNU Binutils.
|
||||
@ -48,7 +48,7 @@ struct debug_handle
|
||||
struct debug_function *current_function;
|
||||
/* The current block. */
|
||||
struct debug_block *current_block;
|
||||
/* The current line number information for the current block. */
|
||||
/* The current line number information for the current unit. */
|
||||
struct debug_lineno *current_lineno;
|
||||
/* Mark. This is used by debug_write. */
|
||||
unsigned int mark;
|
||||
@ -66,6 +66,10 @@ struct debug_unit
|
||||
file is always the main one, and that is where the main file name
|
||||
is stored. */
|
||||
struct debug_file *files;
|
||||
/* Line number information for this compilation unit. This is not
|
||||
stored by function, because assembler code may have line number
|
||||
information without function information. */
|
||||
struct debug_lineno *linenos;
|
||||
};
|
||||
|
||||
/* Information kept for a single source file. */
|
||||
@ -394,12 +398,11 @@ struct debug_block
|
||||
bfd_vma end;
|
||||
/* Local variables. */
|
||||
struct debug_namespace *locals;
|
||||
/* Line number information. */
|
||||
struct debug_lineno *linenos;
|
||||
};
|
||||
|
||||
/* Line number information we keep for a function. FIXME: This
|
||||
structure is easy to create, but can be very space inefficient. */
|
||||
/* Line number information we keep for a compilation unit. FIXME:
|
||||
This structure is easy to create, but can be very space
|
||||
inefficient. */
|
||||
|
||||
struct debug_lineno
|
||||
{
|
||||
@ -511,7 +514,7 @@ static boolean debug_write_type
|
||||
struct debug_type *, struct debug_name *));
|
||||
static boolean debug_write_class_type
|
||||
PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
|
||||
struct debug_type *));
|
||||
struct debug_type *, const char *));
|
||||
static boolean debug_write_function
|
||||
PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
|
||||
const char *, enum debug_object_linkage, struct debug_function *));
|
||||
@ -769,7 +772,6 @@ debug_record_function (handle, name, return_type, global, addr)
|
||||
|
||||
info->current_function = f;
|
||||
info->current_block = b;
|
||||
info->current_lineno = NULL;
|
||||
|
||||
/* FIXME: If we could handle nested functions, this would be the
|
||||
place: we would want to use a different namespace. */
|
||||
@ -855,7 +857,6 @@ debug_end_function (handle, addr)
|
||||
|
||||
info->current_function = NULL;
|
||||
info->current_block = NULL;
|
||||
info->current_lineno = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -897,7 +898,6 @@ debug_start_block (handle, addr)
|
||||
*pb = b;
|
||||
|
||||
info->current_block = b;
|
||||
info->current_lineno = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -931,7 +931,6 @@ debug_end_block (handle, addr)
|
||||
info->current_block->end = addr;
|
||||
|
||||
info->current_block = parent;
|
||||
info->current_lineno = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -949,10 +948,9 @@ debug_record_line (handle, lineno, addr)
|
||||
struct debug_lineno *l;
|
||||
unsigned int i;
|
||||
|
||||
if (info->current_unit == NULL
|
||||
|| info->current_block == NULL)
|
||||
if (info->current_unit == NULL)
|
||||
{
|
||||
debug_error ("debug_record_line: no current block");
|
||||
debug_error ("debug_record_line: no current unit");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -971,11 +969,12 @@ debug_record_line (handle, lineno, addr)
|
||||
}
|
||||
|
||||
/* If we get here, then either 1) there is no current_lineno
|
||||
structure, which means this is the first line number since we got
|
||||
to this block, 2) the current_lineno structure is for a different
|
||||
file, or 3) the current_lineno structure is full. Regardless, we
|
||||
want to allocate a new debug_lineno structure, put it in the
|
||||
right place, and make it the new current_lineno structure. */
|
||||
structure, which means this is the first line number in this
|
||||
compilation unit, 2) the current_lineno structure is for a
|
||||
different file, or 3) the current_lineno structure is full.
|
||||
Regardless, we want to allocate a new debug_lineno structure, put
|
||||
it in the right place, and make it the new current_lineno
|
||||
structure. */
|
||||
|
||||
l = (struct debug_lineno *) xmalloc (sizeof *l);
|
||||
memset (l, 0, sizeof *l);
|
||||
@ -989,18 +988,7 @@ debug_record_line (handle, lineno, addr)
|
||||
if (info->current_lineno != NULL)
|
||||
info->current_lineno->next = l;
|
||||
else
|
||||
{
|
||||
struct debug_lineno **pl;
|
||||
|
||||
/* We may be back in this block after dealing with child blocks,
|
||||
which means we may have some line number information for this
|
||||
block even though current_lineno was NULL. */
|
||||
for (pl = &info->current_block->linenos;
|
||||
*pl != NULL;
|
||||
pl = &(*pl)->next)
|
||||
;
|
||||
*pl = l;
|
||||
}
|
||||
info->current_unit->linenos = l;
|
||||
|
||||
info->current_lineno = l;
|
||||
|
||||
@ -2098,6 +2086,7 @@ debug_write (handle, fns, fhandle)
|
||||
{
|
||||
struct debug_file *f;
|
||||
boolean first_file;
|
||||
struct debug_lineno *l;
|
||||
|
||||
if (! (*fns->start_compilation_unit) (fhandle, u->files->filename))
|
||||
return false;
|
||||
@ -2124,6 +2113,20 @@ debug_write (handle, fns, fhandle)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (l = u->linenos; l != NULL; l = l->next)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < DEBUG_LINENO_COUNT; i++)
|
||||
{
|
||||
if (l->linenos[i] == (unsigned long) -1)
|
||||
break;
|
||||
if (! (*fns->lineno) (fhandle, l->file->filename, l->linenos[i],
|
||||
l->addrs[i]))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -2179,7 +2182,11 @@ debug_write_name (info, fns, fhandle, n)
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/* Write out a type. */
|
||||
/* Write out a type. If the type is DEBUG_KIND_NAMED or
|
||||
DEBUG_KIND_TAGGED, then the name argument is the name for which we
|
||||
are about to call typedef or tag. If the type is anything else,
|
||||
then the name argument is a tag from a DEBUG_KIND_TAGGED type which
|
||||
points to this one. */
|
||||
|
||||
static boolean
|
||||
debug_write_type (info, fns, fhandle, type, name)
|
||||
@ -2190,6 +2197,7 @@ debug_write_type (info, fns, fhandle, type, name)
|
||||
struct debug_name *name;
|
||||
{
|
||||
unsigned int i;
|
||||
const char *tag;
|
||||
|
||||
/* If we have a name for this type, just output it. We only output
|
||||
typedef names after they have been defined. We output type tags
|
||||
@ -2214,6 +2222,15 @@ debug_write_type (info, fns, fhandle, type, name)
|
||||
if (name != NULL)
|
||||
name->mark = info->mark;
|
||||
|
||||
tag = NULL;
|
||||
if (name != NULL
|
||||
&& type->kind != DEBUG_KIND_NAMED
|
||||
&& type->kind != DEBUG_KIND_TAGGED)
|
||||
{
|
||||
assert (name->kind == DEBUG_OBJECT_TAG);
|
||||
tag = name->name;
|
||||
}
|
||||
|
||||
switch (type->kind)
|
||||
{
|
||||
case DEBUG_KIND_INDIRECT:
|
||||
@ -2241,7 +2258,7 @@ debug_write_type (info, fns, fhandle, type, name)
|
||||
}
|
||||
type->u.kclass->mark = info->class_mark;
|
||||
|
||||
if (! (*fns->start_struct_type) (fhandle,
|
||||
if (! (*fns->start_struct_type) (fhandle, tag,
|
||||
type->kind == DEBUG_KIND_STRUCT,
|
||||
type->size))
|
||||
return false;
|
||||
@ -2262,9 +2279,9 @@ debug_write_type (info, fns, fhandle, type, name)
|
||||
return (*fns->end_struct_type) (fhandle);
|
||||
case DEBUG_KIND_CLASS:
|
||||
case DEBUG_KIND_UNION_CLASS:
|
||||
return debug_write_class_type (info, fns, fhandle, type);
|
||||
return debug_write_class_type (info, fns, fhandle, type, tag);
|
||||
case DEBUG_KIND_ENUM:
|
||||
return (*fns->enum_type) (fhandle, type->u.kenum->names,
|
||||
return (*fns->enum_type) (fhandle, tag, type->u.kenum->names,
|
||||
type->u.kenum->values);
|
||||
case DEBUG_KIND_POINTER:
|
||||
if (! debug_write_type (info, fns, fhandle, type->u.kpointer,
|
||||
@ -2349,9 +2366,11 @@ debug_write_type (info, fns, fhandle, type, name)
|
||||
return false;
|
||||
return (*fns->volatile_type) (fhandle);
|
||||
case DEBUG_KIND_NAMED:
|
||||
case DEBUG_KIND_TAGGED:
|
||||
return debug_write_type (info, fns, fhandle, type->u.knamed->type,
|
||||
(struct debug_name *) NULL);
|
||||
case DEBUG_KIND_TAGGED:
|
||||
return debug_write_type (info, fns, fhandle, type->u.knamed->type,
|
||||
type->u.knamed->name);
|
||||
default:
|
||||
abort ();
|
||||
return false;
|
||||
@ -2361,11 +2380,12 @@ debug_write_type (info, fns, fhandle, type, name)
|
||||
/* Write out a class type. */
|
||||
|
||||
static boolean
|
||||
debug_write_class_type (info, fns, fhandle, type)
|
||||
debug_write_class_type (info, fns, fhandle, type, tag)
|
||||
struct debug_handle *info;
|
||||
const struct debug_write_fns *fns;
|
||||
PTR fhandle;
|
||||
struct debug_type *type;
|
||||
const char *tag;
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
@ -2385,7 +2405,7 @@ debug_write_class_type (info, fns, fhandle, type)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! (*fns->start_class_type) (fhandle,
|
||||
if (! (*fns->start_class_type) (fhandle, tag,
|
||||
type->kind == DEBUG_KIND_CLASS,
|
||||
type->size,
|
||||
type->u.kclass->vptrbase != NULL,
|
||||
@ -2533,7 +2553,6 @@ debug_write_block (info, fns, fhandle, block)
|
||||
struct debug_block *block;
|
||||
{
|
||||
struct debug_name *n;
|
||||
struct debug_lineno *l;
|
||||
struct debug_block *b;
|
||||
|
||||
if (! (*fns->start_block) (fhandle, block->start))
|
||||
@ -2548,20 +2567,6 @@ debug_write_block (info, fns, fhandle, block)
|
||||
}
|
||||
}
|
||||
|
||||
for (l = block->linenos; l != NULL; l = l->next)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < DEBUG_LINENO_COUNT; i++)
|
||||
{
|
||||
if (l->linenos[i] == (unsigned long) -1)
|
||||
break;
|
||||
if (! (*fns->lineno) (fhandle, l->file->filename, l->linenos[i],
|
||||
l->addrs[i]))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (b = block->children; b != NULL; b = b->next)
|
||||
{
|
||||
if (! debug_write_block (info, fns, fhandle, b))
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* debug.h -- Describe generic debugging information.
|
||||
Copyright (C) 1995 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
Written by Ian Lance Taylor <ian@cygnus.com>.
|
||||
|
||||
This file is part of GNU Binutils.
|
||||
@ -192,9 +192,11 @@ struct debug_write_fns
|
||||
/* Push a boolean type onto the type stack, given the size. */
|
||||
boolean (*bool_type) PARAMS ((PTR, unsigned int));
|
||||
|
||||
/* Push an enum type onto the type stack, given a NULL terminated
|
||||
array of names and the associated values. */
|
||||
boolean (*enum_type) PARAMS ((PTR, const char **, bfd_signed_vma *));
|
||||
/* Push an enum type onto the type stack, given the tag, a NULL
|
||||
terminated array of names and the associated values. If there is
|
||||
no tag, the tag argument will be NULL. */
|
||||
boolean (*enum_type) PARAMS ((PTR, const char *, const char **,
|
||||
bfd_signed_vma *));
|
||||
|
||||
/* Pop the top type on the type stack, and push a pointer to that
|
||||
type onto the type stack. */
|
||||
@ -240,8 +242,8 @@ struct debug_write_fns
|
||||
method). An argument type of -1 means that no argument in
|
||||
formation is available. The next type on the type stack below
|
||||
the domain and the argument types is the return type of the
|
||||
method. All these types must be poppsed, and then the method
|
||||
type must be pushed. */
|
||||
method. All these types must be popped, and then the method type
|
||||
must be pushed. */
|
||||
boolean (*method_type) PARAMS ((PTR, boolean, int));
|
||||
|
||||
/* Pop the top type off the type stack, and push a const qualified
|
||||
@ -254,10 +256,12 @@ struct debug_write_fns
|
||||
|
||||
/* Start building a struct. This is followed by calls to the
|
||||
struct_field function, and finished by a call to the
|
||||
end_struct_type function. The boolean argument is true for a
|
||||
struct, false for a union. The unsigned int argument is the
|
||||
size. */
|
||||
boolean (*start_struct_type) PARAMS ((PTR, boolean, unsigned int));
|
||||
end_struct_type function. The second argument is the tag; this
|
||||
will be NULL if there isn't one. The boolean argument is true
|
||||
for a struct, false for a union. The unsigned int argument is
|
||||
the size. */
|
||||
boolean (*start_struct_type) PARAMS ((PTR, const char *, boolean,
|
||||
unsigned int));
|
||||
|
||||
/* Add a field to the struct type currently being built. The type
|
||||
of the field should be popped off the type stack. The arguments
|
||||
@ -273,19 +277,20 @@ struct debug_write_fns
|
||||
functions: struct_field, class_static_member, class_baseclass,
|
||||
class_start_method, class_method_variant,
|
||||
class_static_method_variant, and class_end_method. The class is
|
||||
finished by a call to end_class_type. The boolean argument is
|
||||
true for a struct, false for a union. The next argument is the
|
||||
size. The next argument is true if there is a virtual function
|
||||
table; if there is, the next argument is true if the virtual
|
||||
function table can be found in the type itself, and is false if
|
||||
the type of the object holding the virtual function table should
|
||||
be popped from the type stack. */
|
||||
boolean (*start_class_type) PARAMS ((PTR, boolean, unsigned int,
|
||||
boolean, boolean));
|
||||
finished by a call to end_class_type. The second argument is the
|
||||
tag; this will be NULL if there isn't one. The boolean argument
|
||||
is true for a struct, false for a union. The next argument is
|
||||
the size. The next argument is true if there is a virtual
|
||||
function table; if there is, the next argument is true if the
|
||||
virtual function table can be found in the type itself, and is
|
||||
false if the type of the object holding the virtual function
|
||||
table should be popped from the type stack. */
|
||||
boolean (*start_class_type) PARAMS ((PTR, const char *, boolean,
|
||||
unsigned int, boolean, boolean));
|
||||
|
||||
/* Add a static member to the class currently being built. The
|
||||
arguments are the field name, the physical name, and the
|
||||
visibility. */
|
||||
visibility. The type must be popped off the type stack. */
|
||||
boolean (*class_static_member) PARAMS ((PTR, const char *, const char *,
|
||||
enum debug_visibility));
|
||||
|
||||
@ -319,7 +324,8 @@ struct debug_write_fns
|
||||
|
||||
/* Describe a static variant to the class method currently being
|
||||
built. The arguments are the same as for class_method_variant,
|
||||
except that the last two arguments are omitted. */
|
||||
except that the last two arguments are omitted. The type of the
|
||||
variant must be popped off the type stack. */
|
||||
boolean (*class_static_method_variant) PARAMS ((PTR, const char *,
|
||||
enum debug_visibility,
|
||||
boolean, boolean));
|
||||
@ -342,7 +348,9 @@ struct debug_write_fns
|
||||
boolean (*typdef) PARAMS ((PTR, const char *));
|
||||
|
||||
/* Pop the type stack, and declare it as a tagged struct or union or
|
||||
enum or whatever. */
|
||||
enum or whatever. The tag passed down here is redundant, since
|
||||
was also passed when enum_type, start_struct_type, or
|
||||
start_class_type was called. */
|
||||
boolean (*tag) PARAMS ((PTR, const char *));
|
||||
|
||||
/* This is called to record a named integer constant. */
|
||||
@ -376,15 +384,15 @@ struct debug_write_fns
|
||||
starting address of the block. */
|
||||
boolean (*start_block) PARAMS ((PTR, bfd_vma));
|
||||
|
||||
/* Record line number information for the current block. */
|
||||
boolean (*lineno) PARAMS ((PTR, const char *, unsigned long, bfd_vma));
|
||||
|
||||
/* Finish writing out a block. The argument is the ending address
|
||||
of the block. */
|
||||
boolean (*end_block) PARAMS ((PTR, bfd_vma));
|
||||
|
||||
/* Finish writing out a function. */
|
||||
boolean (*end_function) PARAMS ((PTR));
|
||||
|
||||
/* Record line number information for the current compilation unit. */
|
||||
boolean (*lineno) PARAMS ((PTR, const char *, unsigned long, bfd_vma));
|
||||
};
|
||||
|
||||
/* Exported functions. */
|
||||
@ -446,8 +454,8 @@ extern boolean debug_start_block PARAMS ((PTR, bfd_vma));
|
||||
|
||||
extern boolean debug_end_block PARAMS ((PTR, bfd_vma));
|
||||
|
||||
/* Associate a line number in the current source file and function
|
||||
with a given address. */
|
||||
/* Associate a line number in the current source file with a given
|
||||
address. */
|
||||
|
||||
extern boolean debug_record_line PARAMS ((PTR, unsigned long, bfd_vma));
|
||||
|
||||
|
128
binutils/prdbg.c
128
binutils/prdbg.c
@ -1,5 +1,5 @@
|
||||
/* prdbg.c -- Print out generic debugging information.
|
||||
Copyright (C) 1995 Free Software Foundation, Inc.
|
||||
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
|
||||
Written by Ian Lance Taylor <ian@cygnus.com>.
|
||||
|
||||
This file is part of GNU Binutils.
|
||||
@ -78,7 +78,8 @@ static boolean pr_int_type PARAMS ((PTR, unsigned int, boolean));
|
||||
static boolean pr_float_type PARAMS ((PTR, unsigned int));
|
||||
static boolean pr_complex_type PARAMS ((PTR, unsigned int));
|
||||
static boolean pr_bool_type PARAMS ((PTR, unsigned int));
|
||||
static boolean pr_enum_type PARAMS ((PTR, const char **, bfd_signed_vma *));
|
||||
static boolean pr_enum_type
|
||||
PARAMS ((PTR, const char *, const char **, bfd_signed_vma *));
|
||||
static boolean pr_pointer_type PARAMS ((PTR));
|
||||
static boolean pr_function_type PARAMS ((PTR));
|
||||
static boolean pr_reference_type PARAMS ((PTR));
|
||||
@ -90,12 +91,13 @@ static boolean pr_offset_type PARAMS ((PTR));
|
||||
static boolean pr_method_type PARAMS ((PTR, boolean, int));
|
||||
static boolean pr_const_type PARAMS ((PTR));
|
||||
static boolean pr_volatile_type PARAMS ((PTR));
|
||||
static boolean pr_start_struct_type PARAMS ((PTR, boolean, unsigned int));
|
||||
static boolean pr_start_struct_type
|
||||
PARAMS ((PTR, const char *, boolean, unsigned int));
|
||||
static boolean pr_struct_field
|
||||
PARAMS ((PTR, const char *, bfd_vma, bfd_vma, enum debug_visibility));
|
||||
static boolean pr_end_struct_type PARAMS ((PTR));
|
||||
static boolean pr_start_class_type
|
||||
PARAMS ((PTR, boolean, unsigned int, boolean, boolean));
|
||||
PARAMS ((PTR, const char *, boolean, unsigned int, boolean, boolean));
|
||||
static boolean pr_class_static_member
|
||||
PARAMS ((PTR, const char *, const char *, enum debug_visibility));
|
||||
static boolean pr_class_baseclass
|
||||
@ -121,9 +123,9 @@ static boolean pr_start_function PARAMS ((PTR, const char *, boolean));
|
||||
static boolean pr_function_parameter
|
||||
PARAMS ((PTR, const char *, enum debug_parm_kind, bfd_vma));
|
||||
static boolean pr_start_block PARAMS ((PTR, bfd_vma));
|
||||
static boolean pr_lineno PARAMS ((PTR, const char *, unsigned long, bfd_vma));
|
||||
static boolean pr_end_block PARAMS ((PTR, bfd_vma));
|
||||
static boolean pr_end_function PARAMS ((PTR));
|
||||
static boolean pr_lineno PARAMS ((PTR, const char *, unsigned long, bfd_vma));
|
||||
|
||||
static const struct debug_write_fns pr_fns =
|
||||
{
|
||||
@ -168,9 +170,9 @@ static const struct debug_write_fns pr_fns =
|
||||
pr_start_function,
|
||||
pr_function_parameter,
|
||||
pr_start_block,
|
||||
pr_lineno,
|
||||
pr_end_block,
|
||||
pr_end_function
|
||||
pr_end_function,
|
||||
pr_lineno
|
||||
};
|
||||
|
||||
/* Print out the generic debugging information recorded in dhandle. */
|
||||
@ -337,7 +339,7 @@ pop_type (info)
|
||||
struct pr_handle *info;
|
||||
{
|
||||
struct pr_stack *o;
|
||||
char *ret, *s;
|
||||
char *ret;
|
||||
|
||||
assert (info->stack != NULL);
|
||||
|
||||
@ -346,10 +348,6 @@ pop_type (info)
|
||||
ret = o->type;
|
||||
free (o);
|
||||
|
||||
s = strchr (ret, '+');
|
||||
if (s != NULL)
|
||||
memmove (s, s + 2, strlen (s + 2) + 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -500,8 +498,9 @@ pr_bool_type (p, size)
|
||||
/* Push an enum type onto the type stack. */
|
||||
|
||||
static boolean
|
||||
pr_enum_type (p, names, values)
|
||||
pr_enum_type (p, tag, names, values)
|
||||
PTR p;
|
||||
const char *tag;
|
||||
const char **names;
|
||||
bfd_signed_vma *values;
|
||||
{
|
||||
@ -509,8 +508,15 @@ pr_enum_type (p, names, values)
|
||||
unsigned int i;
|
||||
bfd_signed_vma val;
|
||||
|
||||
/* The + indicates where the tag goes, if there is one. */
|
||||
if (! push_type (info, "enum + { "))
|
||||
if (! push_type (info, "enum "))
|
||||
return false;
|
||||
if (tag != NULL)
|
||||
{
|
||||
if (! append_type (info, tag)
|
||||
|| ! append_type (info, " "))
|
||||
return false;
|
||||
}
|
||||
if (! append_type (info, "{ "))
|
||||
return false;
|
||||
|
||||
val = 0;
|
||||
@ -824,26 +830,30 @@ pr_volatile_type (p)
|
||||
/* Start accumulating a struct type. */
|
||||
|
||||
static boolean
|
||||
pr_start_struct_type (p, structp, size)
|
||||
pr_start_struct_type (p, tag, structp, size)
|
||||
PTR p;
|
||||
const char *tag;
|
||||
boolean structp;
|
||||
unsigned int size;
|
||||
{
|
||||
struct pr_handle *info = (struct pr_handle *) p;
|
||||
const char *t;
|
||||
char ab[30];
|
||||
|
||||
info->indent += 2;
|
||||
|
||||
if (structp)
|
||||
t = "struct";
|
||||
else
|
||||
t = "union";
|
||||
if (! push_type (info, structp ? "struct " : "union "))
|
||||
return false;
|
||||
if (tag != NULL)
|
||||
{
|
||||
if (! append_type (info, tag)
|
||||
|| ! append_type (info, " "))
|
||||
return false;
|
||||
}
|
||||
if (size != 0)
|
||||
sprintf (ab, "%s + { /* size %u */\n", t, size);
|
||||
sprintf (ab, "{ /* size %u */\n", size);
|
||||
else
|
||||
sprintf (ab, "%s + {\n", t);
|
||||
if (! push_type (info, ab))
|
||||
strcpy (ab, "{\n");
|
||||
if (! append_type (info, ab))
|
||||
return false;
|
||||
info->stack->visibility = DEBUG_VISIBILITY_PUBLIC;
|
||||
return indent_type (info);
|
||||
@ -977,8 +987,9 @@ pr_end_struct_type (p)
|
||||
/* Start a class type. */
|
||||
|
||||
static boolean
|
||||
pr_start_class_type (p, structp, size, vptr, ownvptr)
|
||||
pr_start_class_type (p, tag, structp, size, vptr, ownvptr)
|
||||
PTR p;
|
||||
const char *tag;
|
||||
boolean structp;
|
||||
unsigned int size;
|
||||
boolean vptr;
|
||||
@ -996,8 +1007,15 @@ pr_start_class_type (p, structp, size, vptr, ownvptr)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! push_type (info, structp ? "class" : "union class")
|
||||
|| ! append_type (info, " + {"))
|
||||
if (! push_type (info, structp ? "class " : "union class "))
|
||||
return false;
|
||||
if (tag != NULL)
|
||||
{
|
||||
if (! append_type (info, tag)
|
||||
|| ! append_type (info, " "))
|
||||
return false;
|
||||
}
|
||||
if (! append_type (info, "{"))
|
||||
return false;
|
||||
if (size != 0 || vptr || ownvptr)
|
||||
{
|
||||
@ -1079,7 +1097,7 @@ pr_class_baseclass (p, bitpos, virtual, visibility)
|
||||
char *t;
|
||||
const char *prefix;
|
||||
char ab[20];
|
||||
char *s, *n;
|
||||
char *s, *l, *n;
|
||||
|
||||
assert (info->stack != NULL && info->stack->next != NULL);
|
||||
|
||||
@ -1134,27 +1152,19 @@ pr_class_baseclass (p, bitpos, virtual, visibility)
|
||||
|
||||
/* Now the top of the stack is something like "public A / * bitpos
|
||||
10 * /". The next element on the stack is something like "class
|
||||
+ { / * size 8 * /\n...". We want to substitute the top of the
|
||||
stack in after the +. */
|
||||
s = strchr (info->stack->next->type, '+');
|
||||
xx { / * size 8 * /\n...". We want to substitute the top of the
|
||||
stack in before the {. */
|
||||
s = strchr (info->stack->next->type, '{');
|
||||
assert (s != NULL);
|
||||
--s;
|
||||
|
||||
if (s[2] != ':')
|
||||
{
|
||||
++s;
|
||||
assert (s[1] == '{');
|
||||
if (! prepend_type (info, " : "))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We already have a baseclass. Append this one after a comma. */
|
||||
s = strchr (s, '{');
|
||||
assert (s != NULL);
|
||||
--s;
|
||||
if (! prepend_type (info, ", "))
|
||||
return false;
|
||||
}
|
||||
/* If there is already a ':', then we already have a baseclass, and
|
||||
we must append this one after a comma. */
|
||||
for (l = info->stack->next->type; l != s; l++)
|
||||
if (*l == ':')
|
||||
break;
|
||||
if (! prepend_type (info, l == s ? " : " : ", "))
|
||||
return false;
|
||||
|
||||
t = pop_type (info);
|
||||
if (t == NULL)
|
||||
@ -1426,31 +1436,17 @@ pr_typdef (p, name)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Output a tag. */
|
||||
/* Output a tag. The tag should already be in the string on the
|
||||
stack, so all we have to do here is print it out. */
|
||||
|
||||
/*ARGSUSED*/
|
||||
static boolean
|
||||
pr_tag (p, name)
|
||||
PTR p;
|
||||
const char *name;
|
||||
{
|
||||
struct pr_handle *info = (struct pr_handle *) p;
|
||||
char *t, *s, *n;
|
||||
|
||||
assert (info->stack != NULL);
|
||||
|
||||
t = info->stack->type;
|
||||
|
||||
s = strchr (t, '+');
|
||||
assert (s != NULL);
|
||||
|
||||
n = (char *) xmalloc (strlen (t) + strlen (name));
|
||||
|
||||
memcpy (n, t, s - t);
|
||||
strcpy (n + (s - t), name);
|
||||
strcat (n, s + 1);
|
||||
|
||||
free (t);
|
||||
info->stack->type = n;
|
||||
char *t;
|
||||
|
||||
t = pop_type (info);
|
||||
if (t == NULL)
|
||||
@ -1459,7 +1455,7 @@ pr_tag (p, name)
|
||||
indent (info);
|
||||
fprintf (info->f, "%s;\n", t);
|
||||
|
||||
free (n);
|
||||
free (t);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
Reference in New Issue
Block a user