* debug.h (enum debug_type_kind): Add DEBUG_KIND_ILLEGAL.
(struct debug_write_fns): Add field ellipsis_type. Add id parameter to start_struct_type, start_class_type, and tag_type. (debug_make_ellipsis_type): Declare. (debug_find_named_type): Declare. (debug_get_type_kind): Declare. (debug_get_return_type): Declare. (debug_get_parameter_types): Declare. (debug_get_fields): Declare. (debug_get_field_type): Declare. * debug.c (struct debug_handle): Add fields class_id and base_id. (struct debug_class_type): Add field id. (struct debug_method_variant): Rename argtypes to physname. Change all uses. (debug_ellipsis_type): New static variable. (ELLIPSIS_P): New macro. (debug_make_ellipsis_type): New function. (debug_make_method_variant): Rename argtypes to physname. (debug_make_static_method_variant): Likewise. (debug_name_type): Always put types in the global namespace. (debug_find_named_type): New function. (debug_find_tagged_type): Treat DEBUG_KIND_ILLEGAL specially, rather than DEBUG_KIND_VOID. (debug_get_real_type): New static function. (debug_get_type_kind): New function. (debug_get_return_type): New function. (debug_get_parameter_types): New function. (debug_get_fields): New function. (debug_get_field_type): New function. (debug_write): Initialize base_id. (debug_write_type): Pass new id argument to tag_type. Handle DEBUG_KIND_ILLEGAL. Use id for DEBUG_KIND_STRUCT and DEBUG_KIND_UNION. Handle ellipsis for method arguments. (debug_write_class_type): Don't dereference kclass if it is NULL. Use id. * prdbg.c (pr_fns): Add pr_ellipsis_type. (pr_ellipsis_type): New static function. (pr_pointer_type): If this is a pointer to an array, parenthesize it correctly. (pr_start_struct_type): Add id parameter. (pr_start_class_type): Likewise. (pr_tag_type): Likewise. (pr_fix_visibility): Add the visibility to the top of the stack, not the second element on the stack. (pr_struct_field): Pop the stack before calling pr_fix_visibility. (pr_class_static_member): Likewise. (pr_class_start_method): Don't push a type, just set the method name in the type on the top of the stack. (pr_class_end_method): Don't pop the stack. (pr_class_method_variant): Rename argtypes parameter to physname. Append const and volatile rather than prepending them. Add a space after the physname. (pr_class_static_method_variant): Likewise. * ieee.c (ieee_fns): Add ieee_ellipsis_type. (ieee_define_named_type): Use DEBUG_KIND_ILLEGAL rather than DEBUG_KIND_VOID. (write_ieee_debugging_info): Likewise. (ieee_typdef): Likewise. (ieee_ellipsis_type): New static function. (ieee_start_struct_type): Add id parameter. (ieee_start_class_type): Likewise. (ieee_tag_type): Likewise. (ieee_class_method_variant): Rename name to physname. (ieee_class_static_method_variant): Likewise.
This commit is contained in:
parent
8c038399b5
commit
07aa1e1b7a
4 changed files with 502 additions and 145 deletions
309
binutils/debug.c
309
binutils/debug.c
|
@ -54,6 +54,10 @@ struct debug_handle
|
|||
unsigned int mark;
|
||||
/* Another mark used by debug_write. */
|
||||
unsigned int class_mark;
|
||||
/* A struct/class ID used by debug_write. */
|
||||
unsigned int class_id;
|
||||
/* The base for class_id for this call to debug_write. */
|
||||
unsigned int base_id;
|
||||
};
|
||||
|
||||
/* Information we keep for a single compilation unit. */
|
||||
|
@ -150,6 +154,8 @@ struct debug_class_type
|
|||
debug_field *fields;
|
||||
/* A mark field used to avoid recursively printing out structs. */
|
||||
unsigned int mark;
|
||||
/* This is used to uniquely identify unnamed structs when printing. */
|
||||
unsigned int id;
|
||||
/* The remaining fields are only used for DEBUG_KIND_CLASS and
|
||||
DEBUG_KIND_UNION_CLASS. */
|
||||
/* NULL terminated array of base classes. */
|
||||
|
@ -309,8 +315,8 @@ struct debug_method
|
|||
|
||||
struct debug_method_variant
|
||||
{
|
||||
/* The argument types of the function. */
|
||||
const char *argtypes;
|
||||
/* The physical name of the function. */
|
||||
const char *physname;
|
||||
/* The type of the function. */
|
||||
struct debug_type *type;
|
||||
/* The visibility of the function. */
|
||||
|
@ -497,6 +503,17 @@ struct debug_name
|
|||
} u;
|
||||
};
|
||||
|
||||
/* This variable is an ellipsis type. The contents are not used; its
|
||||
address is returned by debug_make_ellipsis_type, and anything which
|
||||
needs to know whether it is dealing with an ellipsis compares
|
||||
addresses. */
|
||||
|
||||
static const struct debug_type debug_ellipsis_type;
|
||||
|
||||
#define ELLIPSIS_P(t) ((t) == &debug_ellipsis_type)
|
||||
|
||||
/* Local functions. */
|
||||
|
||||
static void debug_error PARAMS ((const char *));
|
||||
static struct debug_name *debug_add_to_namespace
|
||||
PARAMS ((struct debug_handle *, struct debug_namespace **, const char *,
|
||||
|
@ -506,6 +523,7 @@ static struct debug_name *debug_add_to_current_namespace
|
|||
enum debug_object_linkage));
|
||||
static struct debug_type *debug_make_type
|
||||
PARAMS ((struct debug_handle *, enum debug_type_kind, unsigned int));
|
||||
static struct debug_type *debug_get_real_type PARAMS ((PTR, debug_type));
|
||||
static boolean debug_write_name
|
||||
PARAMS ((struct debug_handle *, const struct debug_write_fns *, PTR,
|
||||
struct debug_name *));
|
||||
|
@ -1223,6 +1241,18 @@ debug_make_indirect_type (handle, slot, tag)
|
|||
return t;
|
||||
}
|
||||
|
||||
/* Make an ellipsis type. This is not a type at all, but is a marker
|
||||
suitable for appearing in the list of argument types passed to
|
||||
debug_make_method_type. It should be used to indicate a method
|
||||
which takes a variable number of arguments. */
|
||||
|
||||
debug_type
|
||||
debug_make_ellipsis_type (handle)
|
||||
PTR handle;
|
||||
{
|
||||
return (debug_type) &debug_ellipsis_type;
|
||||
}
|
||||
|
||||
/* Make a void type. There is only one of these. */
|
||||
|
||||
debug_type
|
||||
|
@ -1847,10 +1877,10 @@ debug_make_method (handle, name, variants)
|
|||
|
||||
/*ARGSUSED*/
|
||||
debug_method_variant
|
||||
debug_make_method_variant (handle, argtypes, type, visibility, constp,
|
||||
debug_make_method_variant (handle, physname, type, visibility, constp,
|
||||
volatilep, voffset, context)
|
||||
PTR handle;
|
||||
const char *argtypes;
|
||||
const char *physname;
|
||||
debug_type type;
|
||||
enum debug_visibility visibility;
|
||||
boolean constp;
|
||||
|
@ -1863,7 +1893,7 @@ debug_make_method_variant (handle, argtypes, type, visibility, constp,
|
|||
m = (struct debug_method_variant *) xmalloc (sizeof *m);
|
||||
memset (m, 0, sizeof *m);
|
||||
|
||||
m->argtypes = argtypes;
|
||||
m->physname = physname;
|
||||
m->type = type;
|
||||
m->visibility = visibility;
|
||||
m->constp = constp;
|
||||
|
@ -1879,10 +1909,10 @@ debug_make_method_variant (handle, argtypes, type, visibility, constp,
|
|||
since a static method can not also be virtual. */
|
||||
|
||||
debug_method_variant
|
||||
debug_make_static_method_variant (handle, argtypes, type, visibility,
|
||||
debug_make_static_method_variant (handle, physname, type, visibility,
|
||||
constp, volatilep)
|
||||
PTR handle;
|
||||
const char *argtypes;
|
||||
const char *physname;
|
||||
debug_type type;
|
||||
enum debug_visibility visibility;
|
||||
boolean constp;
|
||||
|
@ -1893,7 +1923,7 @@ debug_make_static_method_variant (handle, argtypes, type, visibility,
|
|||
m = (struct debug_method_variant *) xmalloc (sizeof *m);
|
||||
memset (m, 0, sizeof *m);
|
||||
|
||||
m->argtypes = argtypes;
|
||||
m->physname = physname;
|
||||
m->type = type;
|
||||
m->visibility = visibility;
|
||||
m->constp = constp;
|
||||
|
@ -1919,6 +1949,13 @@ debug_name_type (handle, name, type)
|
|||
if (name == NULL || type == NULL)
|
||||
return DEBUG_TYPE_NULL;
|
||||
|
||||
if (info->current_unit == NULL
|
||||
|| info->current_file == NULL)
|
||||
{
|
||||
debug_error ("debug_record_variable: no current file");
|
||||
return false;
|
||||
}
|
||||
|
||||
t = debug_make_type (info, DEBUG_KIND_NAMED, 0);
|
||||
if (t == NULL)
|
||||
return DEBUG_TYPE_NULL;
|
||||
|
@ -1930,10 +1967,11 @@ debug_name_type (handle, name, type)
|
|||
|
||||
t->u.knamed = n;
|
||||
|
||||
/* We also need to add the name to the current namespace. */
|
||||
/* We always add the name to the global namespace. This is probably
|
||||
wrong in some cases, but it seems to be right for stabs. FIXME. */
|
||||
|
||||
nm = debug_add_to_current_namespace (info, name, DEBUG_OBJECT_TYPE,
|
||||
DEBUG_LINKAGE_NONE);
|
||||
nm = debug_add_to_namespace (info, &info->current_file->globals, name,
|
||||
DEBUG_OBJECT_TYPE, DEBUG_LINKAGE_NONE);
|
||||
if (nm == NULL)
|
||||
return false;
|
||||
|
||||
|
@ -2018,6 +2056,61 @@ debug_record_type_size (handle, type, size)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* Find a named type. */
|
||||
|
||||
debug_type
|
||||
debug_find_named_type (handle, name)
|
||||
PTR handle;
|
||||
const char *name;
|
||||
{
|
||||
struct debug_handle *info = (struct debug_handle *) handle;
|
||||
struct debug_block *b;
|
||||
struct debug_file *f;
|
||||
|
||||
/* We only search the current compilation unit. I don't know if
|
||||
this is right or not. */
|
||||
|
||||
if (info->current_unit == NULL)
|
||||
{
|
||||
debug_error ("debug_find_named_type: no current compilation unit");
|
||||
return DEBUG_TYPE_NULL;
|
||||
}
|
||||
|
||||
for (b = info->current_block; b != NULL; b = b->parent)
|
||||
{
|
||||
if (b->locals != NULL)
|
||||
{
|
||||
struct debug_name *n;
|
||||
|
||||
for (n = b->locals->list; n != NULL; n = n->next)
|
||||
{
|
||||
if (n->kind == DEBUG_OBJECT_TYPE
|
||||
&& n->name[0] == name[0]
|
||||
&& strcmp (n->name, name) == 0)
|
||||
return n->u.type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (f = info->current_unit->files; f != NULL; f = f->next)
|
||||
{
|
||||
if (f->globals != NULL)
|
||||
{
|
||||
struct debug_name *n;
|
||||
|
||||
for (n = f->globals->list; n != NULL; n = n->next)
|
||||
{
|
||||
if (n->kind == DEBUG_OBJECT_TYPE
|
||||
&& n->name[0] == name[0]
|
||||
&& strcmp (n->name, name) == 0)
|
||||
return n->u.type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return DEBUG_TYPE_NULL;
|
||||
}
|
||||
|
||||
/* Find a tagged type. */
|
||||
|
||||
debug_type
|
||||
|
@ -2045,7 +2138,7 @@ debug_find_tagged_type (handle, name, kind)
|
|||
for (n = f->globals->list; n != NULL; n = n->next)
|
||||
{
|
||||
if (n->kind == DEBUG_OBJECT_TAG
|
||||
&& (kind == DEBUG_KIND_VOID
|
||||
&& (kind == DEBUG_KIND_ILLEGAL
|
||||
|| n->u.tag->kind == kind)
|
||||
&& n->name[0] == name[0]
|
||||
&& strcmp (n->name, name) == 0)
|
||||
|
@ -2058,9 +2151,42 @@ debug_find_tagged_type (handle, name, kind)
|
|||
return DEBUG_TYPE_NULL;
|
||||
}
|
||||
|
||||
/* Get a base type. */
|
||||
|
||||
static struct debug_type *
|
||||
debug_get_real_type (handle, type)
|
||||
PTR handle;
|
||||
debug_type type;
|
||||
{
|
||||
switch (type->kind)
|
||||
{
|
||||
default:
|
||||
return type;
|
||||
case DEBUG_KIND_INDIRECT:
|
||||
if (*type->u.kindirect->slot != NULL)
|
||||
return debug_get_real_type (handle, *type->u.kindirect->slot);
|
||||
return type;
|
||||
case DEBUG_KIND_NAMED:
|
||||
return debug_get_real_type (handle, type->u.knamed->type);
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/* Get the kind of a type. */
|
||||
|
||||
enum debug_type_kind
|
||||
debug_get_type_kind (handle, type)
|
||||
PTR handle;
|
||||
debug_type type;
|
||||
{
|
||||
if (type == NULL)
|
||||
return DEBUG_KIND_ILLEGAL;
|
||||
type = debug_get_real_type (handle, type);
|
||||
return type->kind;
|
||||
}
|
||||
|
||||
/* Get the name of a type. */
|
||||
|
||||
/*ARGSUSED*/
|
||||
const char *
|
||||
debug_get_type_name (handle, type)
|
||||
PTR handle;
|
||||
|
@ -2077,6 +2203,86 @@ debug_get_type_name (handle, type)
|
|||
return type->u.knamed->name->name;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get the return type of a function or method type. */
|
||||
|
||||
debug_type
|
||||
debug_get_return_type (handle, type)
|
||||
PTR handle;
|
||||
debug_type type;
|
||||
{
|
||||
if (type == NULL)
|
||||
return DEBUG_TYPE_NULL;
|
||||
type = debug_get_real_type (handle, type);
|
||||
switch (type->kind)
|
||||
{
|
||||
default:
|
||||
return DEBUG_TYPE_NULL;
|
||||
case DEBUG_KIND_FUNCTION:
|
||||
return type->u.kfunction->return_type;
|
||||
case DEBUG_KIND_METHOD:
|
||||
return type->u.kmethod->return_type;
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/* Get the parameter types of a function or method type (except that
|
||||
we don't currently store the parameter types of a function). */
|
||||
|
||||
const debug_type *
|
||||
debug_get_parameter_types (handle, type)
|
||||
PTR handle;
|
||||
debug_type type;
|
||||
{
|
||||
if (type == NULL)
|
||||
return NULL;
|
||||
type = debug_get_real_type (handle, type);
|
||||
switch (type->kind)
|
||||
{
|
||||
default:
|
||||
return NULL;
|
||||
case DEBUG_KIND_METHOD:
|
||||
return type->u.kmethod->arg_types;
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/* Get the NULL terminated array of fields for a struct, union, or
|
||||
class. */
|
||||
|
||||
const debug_field *
|
||||
debug_get_fields (handle, type)
|
||||
PTR handle;
|
||||
debug_type type;
|
||||
{
|
||||
if (type == NULL)
|
||||
return NULL;
|
||||
type = debug_get_real_type (handle, type);
|
||||
switch (type->kind)
|
||||
{
|
||||
default:
|
||||
return NULL;
|
||||
case DEBUG_KIND_STRUCT:
|
||||
case DEBUG_KIND_UNION:
|
||||
case DEBUG_KIND_CLASS:
|
||||
case DEBUG_KIND_UNION_CLASS:
|
||||
return type->u.kclass->fields;
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/* Get the type of a field. */
|
||||
|
||||
/*ARGSUSED*/
|
||||
debug_type
|
||||
debug_get_field_type (handle, field)
|
||||
PTR handle;
|
||||
debug_field field;
|
||||
{
|
||||
if (field == NULL)
|
||||
return NULL;
|
||||
return field->type;
|
||||
}
|
||||
|
||||
/* Write out the debugging information. This is given a handle to
|
||||
debugging information, and a set of function pointers to call. */
|
||||
|
@ -2096,6 +2302,11 @@ debug_write (handle, fns, fhandle)
|
|||
information more than once. */
|
||||
++info->mark;
|
||||
|
||||
/* The base_id field holds an ID value which will never be used, so
|
||||
that we can tell whether we have assigned an ID during this call
|
||||
to debug_write. */
|
||||
info->base_id = info->class_id;
|
||||
|
||||
for (u = info->units; u != NULL; u = u->next)
|
||||
{
|
||||
struct debug_file *f;
|
||||
|
@ -2225,7 +2436,7 @@ debug_write_type (info, fns, fhandle, type, name)
|
|||
if (type->kind == DEBUG_KIND_NAMED)
|
||||
return (*fns->typedef_type) (fhandle, type->u.knamed->name->name);
|
||||
else
|
||||
return (*fns->tag_type) (fhandle, type->u.knamed->name->name,
|
||||
return (*fns->tag_type) (fhandle, type->u.knamed->name->name, 0,
|
||||
type->u.knamed->type->kind);
|
||||
}
|
||||
|
||||
|
@ -2247,6 +2458,9 @@ debug_write_type (info, fns, fhandle, type, name)
|
|||
|
||||
switch (type->kind)
|
||||
{
|
||||
case DEBUG_KIND_ILLEGAL:
|
||||
debug_error ("debug_write_type: illegal type encountered");
|
||||
return false;
|
||||
case DEBUG_KIND_INDIRECT:
|
||||
if (*type->u.kindirect->slot == DEBUG_TYPE_NULL)
|
||||
return (*fns->empty_type) (fhandle);
|
||||
|
@ -2266,17 +2480,25 @@ debug_write_type (info, fns, fhandle, type, name)
|
|||
case DEBUG_KIND_UNION:
|
||||
if (type->u.kclass != NULL)
|
||||
{
|
||||
if (info->class_mark == type->u.kclass->mark)
|
||||
if (info->class_mark == type->u.kclass->mark
|
||||
|| type->u.kclass->id > info->base_id)
|
||||
{
|
||||
/* We are currently outputting this struct. I don't
|
||||
know if this can happen, but it can happen for a
|
||||
class. */
|
||||
return (*fns->tag_type) (fhandle, "?defining?", type->kind);
|
||||
/* We are currently outputting this struct, or we have
|
||||
already output it. I don't know if this can happen,
|
||||
but it can happen for a class. */
|
||||
assert (type->u.kclass->id > info->base_id);
|
||||
return (*fns->tag_type) (fhandle, tag, type->u.kclass->id,
|
||||
type->kind);
|
||||
}
|
||||
type->u.kclass->mark = info->class_mark;
|
||||
++info->class_id;
|
||||
type->u.kclass->id = info->class_id;
|
||||
}
|
||||
|
||||
if (! (*fns->start_struct_type) (fhandle, tag,
|
||||
(type->u.kclass != NULL
|
||||
? type->u.kclass->id
|
||||
: 0),
|
||||
type->kind == DEBUG_KIND_STRUCT,
|
||||
type->size))
|
||||
return false;
|
||||
|
@ -2360,6 +2582,13 @@ debug_write_type (info, fns, fhandle, type, name)
|
|||
else
|
||||
{
|
||||
for (i = 0; type->u.kmethod->arg_types[i] != NULL; i++)
|
||||
{
|
||||
if (ELLIPSIS_P (type->u.kmethod->arg_types[i]))
|
||||
{
|
||||
if (! (*fns->ellipsis_type) (fhandle))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (! debug_write_type (info, fns, fhandle,
|
||||
type->u.kmethod->arg_types[i],
|
||||
|
@ -2367,6 +2596,7 @@ debug_write_type (info, fns, fhandle, type, name)
|
|||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (type->u.kmethod->domain_type != NULL)
|
||||
{
|
||||
if (! debug_write_type (info, fns, fhandle,
|
||||
|
@ -2410,32 +2640,45 @@ debug_write_class_type (info, fns, fhandle, type, tag)
|
|||
const char *tag;
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned int id;
|
||||
struct debug_type *vptrbase;
|
||||
|
||||
if (type->u.kclass != NULL)
|
||||
if (type->u.kclass == NULL)
|
||||
{
|
||||
if (info->class_mark == type->u.kclass->mark)
|
||||
id = 0;
|
||||
vptrbase = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We are currently outputting this class. This can happen
|
||||
when there are methods for an anonymous class. */
|
||||
return (*fns->tag_type) (fhandle, "?defining?", type->kind);
|
||||
if (info->class_mark == type->u.kclass->mark
|
||||
|| type->u.kclass->id > info->base_id)
|
||||
{
|
||||
/* We are currently outputting this class, or we have
|
||||
already output it. This can happen when there are
|
||||
methods for an anonymous class. */
|
||||
assert (type->u.kclass->id > info->base_id);
|
||||
return (*fns->tag_type) (fhandle, tag, type->u.kclass->id,
|
||||
type->kind);
|
||||
}
|
||||
type->u.kclass->mark = info->class_mark;
|
||||
++info->class_id;
|
||||
id = info->class_id;
|
||||
type->u.kclass->id = id;
|
||||
|
||||
if (type->u.kclass->vptrbase != NULL
|
||||
&& type->u.kclass->vptrbase != type)
|
||||
vptrbase = type->u.kclass->vptrbase;
|
||||
if (vptrbase != NULL && vptrbase != type)
|
||||
{
|
||||
if (! debug_write_type (info, fns, fhandle,
|
||||
type->u.kclass->vptrbase,
|
||||
if (! debug_write_type (info, fns, fhandle, vptrbase,
|
||||
(struct debug_name *) NULL))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (! (*fns->start_class_type) (fhandle, tag,
|
||||
if (! (*fns->start_class_type) (fhandle, tag, id,
|
||||
type->kind == DEBUG_KIND_CLASS,
|
||||
type->size,
|
||||
type->u.kclass->vptrbase != NULL,
|
||||
type->u.kclass->vptrbase == type))
|
||||
vptrbase != NULL,
|
||||
vptrbase == type))
|
||||
return false;
|
||||
|
||||
if (type->u.kclass != NULL)
|
||||
|
@ -2508,7 +2751,7 @@ debug_write_class_type (info, fns, fhandle, type, tag)
|
|||
return false;
|
||||
if (v->voffset != VOFFSET_STATIC_METHOD)
|
||||
{
|
||||
if (! (*fns->class_method_variant) (fhandle, v->argtypes,
|
||||
if (! (*fns->class_method_variant) (fhandle, v->physname,
|
||||
v->visibility,
|
||||
v->constp,
|
||||
v->volatilep,
|
||||
|
@ -2519,7 +2762,7 @@ debug_write_class_type (info, fns, fhandle, type, tag)
|
|||
else
|
||||
{
|
||||
if (! (*fns->class_static_method_variant) (fhandle,
|
||||
v->argtypes,
|
||||
v->physname,
|
||||
v->visibility,
|
||||
v->constp,
|
||||
v->volatilep))
|
||||
|
|
109
binutils/debug.h
109
binutils/debug.h
|
@ -32,6 +32,8 @@
|
|||
|
||||
enum debug_type_kind
|
||||
{
|
||||
/* Not used. */
|
||||
DEBUG_KIND_ILLEGAL,
|
||||
/* Indirect via a pointer. */
|
||||
DEBUG_KIND_INDIRECT,
|
||||
/* Void. */
|
||||
|
@ -172,6 +174,11 @@ struct debug_write_fns
|
|||
|
||||
/* Each writer must keep a stack of types. */
|
||||
|
||||
/* Push an ellipsis type onto the type stack. This is not a real
|
||||
type, but is used when a method takes a variable number of
|
||||
arguments. */
|
||||
boolean (*ellipsis_type) PARAMS ((PTR));
|
||||
|
||||
/* Push an empty type onto the type stack. This type can appear if
|
||||
there is a reference to a type which is never defined. */
|
||||
boolean (*empty_type) PARAMS ((PTR));
|
||||
|
@ -258,13 +265,14 @@ 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 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. If this is an undefined struct or union, the size will
|
||||
be 0 and struct_field will not be called before end_struct_type
|
||||
is called. */
|
||||
boolean (*start_struct_type) PARAMS ((PTR, const char *, boolean,
|
||||
unsigned int));
|
||||
will be NULL if there isn't one. If the second argument is NULL,
|
||||
the third argument is a constant identifying this struct for use
|
||||
with tag_type. The fourth argument is true for a struct, false
|
||||
for a union. The fifth argument is the size. If this is an
|
||||
undefined struct or union, the size will be 0 and struct_field
|
||||
will not be called before end_struct_type is called. */
|
||||
boolean (*start_struct_type) PARAMS ((PTR, const char *, unsigned int,
|
||||
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
|
||||
|
@ -280,16 +288,16 @@ 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 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));
|
||||
finished by a call to end_class_type. The first five arguments
|
||||
are the same as for start_struct_type. The sixth argument is
|
||||
true if there is a virtual function table; if there is, the
|
||||
seventh 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 *, unsigned int,
|
||||
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
|
||||
|
@ -314,12 +322,11 @@ struct debug_write_fns
|
|||
|
||||
/* Describe a variant to the class method currently being built.
|
||||
The type of the variant must be popped off the type stack. The
|
||||
second argument is a string which is either the physical name of
|
||||
the function or describes the argument types; see the comment for
|
||||
debug_make_method variant. The following arguments are the
|
||||
visibility, whether the variant is const, whether the variant is
|
||||
volatile, the offset in the virtual function table, and whether
|
||||
the context is on the type stack (below the variant type). */
|
||||
second argument is the physical name of the function. The
|
||||
following arguments are the visibility, whether the variant is
|
||||
const, whether the variant is volatile, the offset in the virtual
|
||||
function table, and whether the context is on the type stack
|
||||
(below the variant type). */
|
||||
boolean (*class_method_variant) PARAMS ((PTR, const char *,
|
||||
enum debug_visibility,
|
||||
boolean, boolean,
|
||||
|
@ -343,9 +350,17 @@ struct debug_write_fns
|
|||
call to typdef. */
|
||||
boolean (*typedef_type) PARAMS ((PTR, const char *));
|
||||
|
||||
/* Push a type on the stack which was given a name by an earlier
|
||||
call to tag. */
|
||||
boolean (*tag_type) PARAMS ((PTR, const char *, enum debug_type_kind));
|
||||
/* Push a tagged type on the stack which was defined earlier. If
|
||||
the second argument is not NULL, the type was defined by a call
|
||||
to tag. If the second argument is NULL, the type was defined by
|
||||
a call to start_struct_type or start_class_type with a tag of
|
||||
NULL and the number of the third argument. Either way, the
|
||||
fourth argument is the tag kind. Note that this may be called
|
||||
for a struct (class) being defined, in between the call to
|
||||
start_struct_type (start_class_type) and the call to
|
||||
end_struct_type (end_class_type). */
|
||||
boolean (*tag_type) PARAMS ((PTR, const char *, unsigned int,
|
||||
enum debug_type_kind));
|
||||
|
||||
/* Pop the type stack, and typedef it to the given name. */
|
||||
boolean (*typdef) PARAMS ((PTR, const char *));
|
||||
|
@ -504,6 +519,13 @@ extern boolean debug_record_variable
|
|||
extern debug_type debug_make_indirect_type
|
||||
PARAMS ((PTR, debug_type *, const char *));
|
||||
|
||||
/* Make an ellipsis type. This is not a type at all, but is a marker
|
||||
suitable for appearing in the list of argument types passed to
|
||||
debug_make_method_type. It should be used to indicate a method
|
||||
which takes a variable number of arguments. */
|
||||
|
||||
extern debug_type debug_make_ellipsis_type PARAMS ((PTR));
|
||||
|
||||
/* Make a void type. */
|
||||
|
||||
extern debug_type debug_make_void_type PARAMS ((PTR));
|
||||
|
@ -656,10 +678,9 @@ extern debug_field debug_make_static_member
|
|||
extern debug_method debug_make_method
|
||||
PARAMS ((PTR, const char *, debug_method_variant *));
|
||||
|
||||
/* Make a method variant. The second argument is either the physical
|
||||
name of the function, or the encoded argument types, depending upon
|
||||
whether the third argument specifies the argument types or not.
|
||||
The third argument is the type of the function. The fourth
|
||||
/* Make a method variant. The second argument is the physical name of
|
||||
the function. The third argument is the type of the function,
|
||||
probably constructed by debug_make_method_type. The fourth
|
||||
argument is the visibility. The fifth argument is whether this is
|
||||
a const function. The sixth argument is whether this is a volatile
|
||||
function. The seventh argument is the offset in the virtual
|
||||
|
@ -693,15 +714,43 @@ extern debug_type debug_tag_type PARAMS ((PTR, const char *, debug_type));
|
|||
|
||||
extern boolean debug_record_type_size PARAMS ((PTR, debug_type, unsigned int));
|
||||
|
||||
/* Find a named type. */
|
||||
|
||||
extern debug_type debug_find_named_type PARAMS ((PTR, const char *));
|
||||
|
||||
/* Find a tagged type. */
|
||||
|
||||
extern debug_type debug_find_tagged_type
|
||||
PARAMS ((PTR, const char *, enum debug_type_kind));
|
||||
|
||||
/* Get the kind of a type. */
|
||||
|
||||
extern enum debug_type_kind debug_get_type_kind PARAMS ((PTR, debug_type));
|
||||
|
||||
/* Get the name of a type. */
|
||||
|
||||
extern const char *debug_get_type_name PARAMS ((PTR, debug_type));
|
||||
|
||||
/* Get the return type of a function or method type. */
|
||||
|
||||
extern debug_type debug_get_return_type PARAMS ((PTR, debug_type));
|
||||
|
||||
/* Get the NULL terminated array of parameter types for a function or
|
||||
method type (actually, parameter types are not currently stored for
|
||||
function types). This may be used to determine whether a method
|
||||
type is a stub method or not. */
|
||||
|
||||
extern const debug_type *debug_get_parameter_types PARAMS ((PTR, debug_type));
|
||||
|
||||
/* Get the NULL terminated array of fields for a struct, union, or
|
||||
class. */
|
||||
|
||||
extern const debug_field *debug_get_fields PARAMS ((PTR, debug_type));
|
||||
|
||||
/* Get the type of a field. */
|
||||
|
||||
extern debug_type debug_get_field_type PARAMS ((PTR, debug_field));
|
||||
|
||||
/* Write out the recorded debugging information. This takes a set of
|
||||
function pointers which are called to do the actual writing. The
|
||||
first PTR is the debugging handle. The second PTR is a handle
|
||||
|
|
|
@ -2267,7 +2267,7 @@ struct ieee_name_type
|
|||
/* Type. */
|
||||
struct ieee_write_type type;
|
||||
/* If this is a tag which has not yet been defined, this is the
|
||||
kind. If the tag has been defined, this is DEBUG_KIND_VOID. */
|
||||
kind. If the tag has been defined, this is DEBUG_KIND_ILLEGAL. */
|
||||
enum debug_type_kind kind;
|
||||
};
|
||||
|
||||
|
@ -2357,6 +2357,7 @@ static boolean ieee_output_pending_parms PARAMS ((struct ieee_handle *));
|
|||
|
||||
static boolean ieee_start_compilation_unit PARAMS ((PTR, const char *));
|
||||
static boolean ieee_start_source PARAMS ((PTR, const char *));
|
||||
static boolean ieee_ellipsis_type PARAMS ((PTR));
|
||||
static boolean ieee_empty_type PARAMS ((PTR));
|
||||
static boolean ieee_void_type PARAMS ((PTR));
|
||||
static boolean ieee_int_type PARAMS ((PTR, unsigned int, boolean));
|
||||
|
@ -2377,12 +2378,13 @@ static boolean ieee_method_type PARAMS ((PTR, boolean, int));
|
|||
static boolean ieee_const_type PARAMS ((PTR));
|
||||
static boolean ieee_volatile_type PARAMS ((PTR));
|
||||
static boolean ieee_start_struct_type
|
||||
PARAMS ((PTR, const char *, boolean, unsigned int));
|
||||
PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int));
|
||||
static boolean ieee_struct_field
|
||||
PARAMS ((PTR, const char *, bfd_vma, bfd_vma, enum debug_visibility));
|
||||
static boolean ieee_end_struct_type PARAMS ((PTR));
|
||||
static boolean ieee_start_class_type
|
||||
PARAMS ((PTR, const char *, boolean, unsigned int, boolean, boolean));
|
||||
PARAMS ((PTR, const char *, unsigned int, boolean, unsigned int, boolean,
|
||||
boolean));
|
||||
static boolean ieee_class_static_member
|
||||
PARAMS ((PTR, const char *, const char *, enum debug_visibility));
|
||||
static boolean ieee_class_baseclass
|
||||
|
@ -2397,7 +2399,7 @@ static boolean ieee_class_end_method PARAMS ((PTR));
|
|||
static boolean ieee_end_class_type PARAMS ((PTR));
|
||||
static boolean ieee_typedef_type PARAMS ((PTR, const char *));
|
||||
static boolean ieee_tag_type
|
||||
PARAMS ((PTR, const char *, enum debug_type_kind));
|
||||
PARAMS ((PTR, const char *, unsigned int, enum debug_type_kind));
|
||||
static boolean ieee_typdef PARAMS ((PTR, const char *));
|
||||
static boolean ieee_tag PARAMS ((PTR, const char *));
|
||||
static boolean ieee_int_constant PARAMS ((PTR, const char *, bfd_vma));
|
||||
|
@ -2418,6 +2420,7 @@ static const struct debug_write_fns ieee_fns =
|
|||
{
|
||||
ieee_start_compilation_unit,
|
||||
ieee_start_source,
|
||||
ieee_ellipsis_type,
|
||||
ieee_empty_type,
|
||||
ieee_void_type,
|
||||
ieee_int_type,
|
||||
|
@ -2797,7 +2800,7 @@ ieee_define_named_type (info, name, tagp, size, unsignedp, ppbuf)
|
|||
|
||||
nt->type.size = size;
|
||||
nt->type.unsignedp = unsignedp;
|
||||
nt->kind = DEBUG_KIND_VOID;
|
||||
nt->kind = DEBUG_KIND_ILLEGAL;
|
||||
|
||||
type_indx = nt->type.indx;
|
||||
}
|
||||
|
@ -2878,7 +2881,7 @@ write_ieee_debugging_info (abfd, dhandle)
|
|||
unsigned int name_indx;
|
||||
char code;
|
||||
|
||||
if (nt->kind == DEBUG_KIND_VOID)
|
||||
if (nt->kind == DEBUG_KIND_ILLEGAL)
|
||||
continue;
|
||||
if (tags == NULL)
|
||||
{
|
||||
|
@ -3158,6 +3161,15 @@ ieee_start_source (p, filename)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* Make an ellipsis type. */
|
||||
|
||||
static boolean
|
||||
ieee_ellipsis_type (p)
|
||||
PTR p;
|
||||
{
|
||||
abort ();
|
||||
}
|
||||
|
||||
/* Make an empty type. */
|
||||
|
||||
static boolean
|
||||
|
@ -3598,9 +3610,10 @@ ieee_volatile_type (p)
|
|||
fields with the struct type itself. */
|
||||
|
||||
static boolean
|
||||
ieee_start_struct_type (p, tag, structp, size)
|
||||
ieee_start_struct_type (p, tag, id, structp, size)
|
||||
PTR p;
|
||||
const char *tag;
|
||||
unsigned int id;
|
||||
boolean structp;
|
||||
unsigned int size;
|
||||
{
|
||||
|
@ -3699,9 +3712,10 @@ ieee_end_struct_type (p)
|
|||
/* Start a class type. */
|
||||
|
||||
static boolean
|
||||
ieee_start_class_type (p, tag, structp, size, vptr, ownvptr)
|
||||
ieee_start_class_type (p, tag, id, structp, size, vptr, ownvptr)
|
||||
PTR p;
|
||||
const char *tag;
|
||||
unsigned int id;
|
||||
boolean structp;
|
||||
unsigned int size;
|
||||
boolean vptr;
|
||||
|
@ -3712,7 +3726,7 @@ ieee_start_class_type (p, tag, structp, size, vptr, ownvptr)
|
|||
/* FIXME. */
|
||||
if (vptr && ! ownvptr)
|
||||
(void) ieee_pop_type (info);
|
||||
return ieee_start_struct_type (p, tag, structp, size);
|
||||
return ieee_start_struct_type (p, tag, id, structp, size);
|
||||
}
|
||||
|
||||
/* Add a static member to a class. */
|
||||
|
@ -3761,10 +3775,10 @@ ieee_class_start_method (p, name)
|
|||
/* Define a new method variant. */
|
||||
|
||||
static boolean
|
||||
ieee_class_method_variant (p, name, visibility, constp, volatilep,
|
||||
ieee_class_method_variant (p, physname, visibility, constp, volatilep,
|
||||
voffset, context)
|
||||
PTR p;
|
||||
const char *name;
|
||||
const char *physname;
|
||||
enum debug_visibility visibility;
|
||||
boolean constp;
|
||||
boolean volatilep;
|
||||
|
@ -3783,9 +3797,9 @@ ieee_class_method_variant (p, name, visibility, constp, volatilep,
|
|||
/* Define a new static method variant. */
|
||||
|
||||
static boolean
|
||||
ieee_class_static_method_variant (p, name, visibility, constp, volatilep)
|
||||
ieee_class_static_method_variant (p, physname, visibility, constp, volatilep)
|
||||
PTR p;
|
||||
const char *name;
|
||||
const char *physname;
|
||||
enum debug_visibility visibility;
|
||||
boolean constp;
|
||||
boolean volatilep;
|
||||
|
@ -3846,14 +3860,18 @@ ieee_typedef_type (p, name)
|
|||
/* Push a tagged type onto the type stack. */
|
||||
|
||||
static boolean
|
||||
ieee_tag_type (p, name, kind)
|
||||
ieee_tag_type (p, name, id, kind)
|
||||
PTR p;
|
||||
const char *name;
|
||||
unsigned int id;
|
||||
enum debug_type_kind kind;
|
||||
{
|
||||
struct ieee_handle *info = (struct ieee_handle *) p;
|
||||
register struct ieee_name_type *nt;
|
||||
|
||||
if (name == NULL)
|
||||
return true;
|
||||
|
||||
for (nt = info->tags; nt != NULL; nt = nt->next)
|
||||
{
|
||||
if (nt->name[0] == name[0]
|
||||
|
@ -3899,7 +3917,7 @@ ieee_typdef (p, name)
|
|||
memset (nt, 0, sizeof *nt);
|
||||
nt->name = name;
|
||||
nt->type = info->type_stack->type;
|
||||
nt->kind = DEBUG_KIND_VOID;
|
||||
nt->kind = DEBUG_KIND_ILLEGAL;
|
||||
|
||||
nt->next = info->typedefs;
|
||||
info->typedefs = nt;
|
||||
|
|
165
binutils/prdbg.c
165
binutils/prdbg.c
|
@ -72,6 +72,7 @@ static boolean pr_fix_visibility
|
|||
|
||||
static boolean pr_start_compilation_unit PARAMS ((PTR, const char *));
|
||||
static boolean pr_start_source PARAMS ((PTR, const char *));
|
||||
static boolean pr_ellipsis_type PARAMS ((PTR));
|
||||
static boolean pr_empty_type PARAMS ((PTR));
|
||||
static boolean pr_void_type PARAMS ((PTR));
|
||||
static boolean pr_int_type PARAMS ((PTR, unsigned int, boolean));
|
||||
|
@ -92,12 +93,13 @@ 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, const char *, boolean, unsigned int));
|
||||
PARAMS ((PTR, const char *, unsigned int, 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, const char *, boolean, unsigned int, boolean, boolean));
|
||||
PARAMS ((PTR, const char *, unsigned int, 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
|
||||
|
@ -111,7 +113,8 @@ static boolean pr_class_static_method_variant
|
|||
static boolean pr_class_end_method PARAMS ((PTR));
|
||||
static boolean pr_end_class_type PARAMS ((PTR));
|
||||
static boolean pr_typedef_type PARAMS ((PTR, const char *));
|
||||
static boolean pr_tag_type PARAMS ((PTR, const char *, enum debug_type_kind));
|
||||
static boolean pr_tag_type
|
||||
PARAMS ((PTR, const char *, unsigned int, enum debug_type_kind));
|
||||
static boolean pr_typdef PARAMS ((PTR, const char *));
|
||||
static boolean pr_tag PARAMS ((PTR, const char *));
|
||||
static boolean pr_int_constant PARAMS ((PTR, const char *, bfd_vma));
|
||||
|
@ -131,6 +134,7 @@ static const struct debug_write_fns pr_fns =
|
|||
{
|
||||
pr_start_compilation_unit,
|
||||
pr_start_source,
|
||||
pr_ellipsis_type,
|
||||
pr_empty_type,
|
||||
pr_void_type,
|
||||
pr_int_type,
|
||||
|
@ -409,6 +413,17 @@ pr_start_source (p, filename)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* Push an ellipsis type onto the type stack. */
|
||||
|
||||
static boolean
|
||||
pr_ellipsis_type (p)
|
||||
PTR p;
|
||||
{
|
||||
struct pr_handle *info = (struct pr_handle *) p;
|
||||
|
||||
return push_type (info, "...");
|
||||
}
|
||||
|
||||
/* Push an empty type onto the type stack. */
|
||||
|
||||
static boolean
|
||||
|
@ -563,9 +578,13 @@ pr_pointer_type (p)
|
|||
PTR p;
|
||||
{
|
||||
struct pr_handle *info = (struct pr_handle *) p;
|
||||
char *s;
|
||||
|
||||
assert (info->stack != NULL);
|
||||
|
||||
s = strchr (info->stack->type, '|');
|
||||
if (s != NULL && s[1] == '[')
|
||||
return substitute_type (info, "(*|)");
|
||||
return substitute_type (info, "*|");
|
||||
}
|
||||
|
||||
|
@ -838,9 +857,10 @@ pr_volatile_type (p)
|
|||
/* Start accumulating a struct type. */
|
||||
|
||||
static boolean
|
||||
pr_start_struct_type (p, tag, structp, size)
|
||||
pr_start_struct_type (p, tag, id, structp, size)
|
||||
PTR p;
|
||||
const char *tag;
|
||||
unsigned int id;
|
||||
boolean structp;
|
||||
unsigned int size;
|
||||
{
|
||||
|
@ -853,10 +873,18 @@ pr_start_struct_type (p, tag, structp, size)
|
|||
return false;
|
||||
if (tag != NULL)
|
||||
{
|
||||
if (! append_type (info, tag)
|
||||
|| ! append_type (info, " "))
|
||||
if (! append_type (info, tag))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
char idbuf[20];
|
||||
|
||||
sprintf (idbuf, "%%anon%u", id);
|
||||
if (! append_type (info, idbuf))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (size != 0)
|
||||
sprintf (ab, " { /* size %u */\n", size);
|
||||
else
|
||||
|
@ -875,16 +903,15 @@ pr_fix_visibility (info, visibility)
|
|||
enum debug_visibility visibility;
|
||||
{
|
||||
const char *s;
|
||||
struct pr_stack *top;
|
||||
char *t;
|
||||
unsigned int len;
|
||||
|
||||
assert (info->stack != NULL && info->stack->next != NULL);
|
||||
assert (info->stack != NULL);
|
||||
|
||||
if (info->stack->next->visibility == visibility)
|
||||
if (info->stack->visibility == visibility)
|
||||
return true;
|
||||
|
||||
assert (info->stack->next->visibility != DEBUG_VISIBILITY_IGNORE);
|
||||
assert (info->stack->visibility != DEBUG_VISIBILITY_IGNORE);
|
||||
|
||||
switch (visibility)
|
||||
{
|
||||
|
@ -903,12 +930,7 @@ pr_fix_visibility (info, visibility)
|
|||
}
|
||||
|
||||
/* Trim off a trailing space in the struct string, to make the
|
||||
output look a bit better, then stick on the visibility string.
|
||||
Pop the stack temporarily to make the string manipulation
|
||||
simpler. */
|
||||
|
||||
top = info->stack;
|
||||
info->stack = top->next;
|
||||
output look a bit better, then stick on the visibility string. */
|
||||
|
||||
t = info->stack->type;
|
||||
len = strlen (t);
|
||||
|
@ -922,8 +944,6 @@ pr_fix_visibility (info, visibility)
|
|||
|
||||
info->stack->visibility = visibility;
|
||||
|
||||
info->stack = top;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -939,9 +959,7 @@ pr_struct_field (p, name, bitpos, bitsize, visibility)
|
|||
{
|
||||
struct pr_handle *info = (struct pr_handle *) p;
|
||||
char ab[20];
|
||||
|
||||
if (! pr_fix_visibility (info, visibility))
|
||||
return false;
|
||||
char *t;
|
||||
|
||||
if (! substitute_type (info, name))
|
||||
return false;
|
||||
|
@ -965,7 +983,14 @@ pr_struct_field (p, name, bitpos, bitsize, visibility)
|
|||
|| ! indent_type (info))
|
||||
return false;
|
||||
|
||||
return append_type (info, pop_type (info));
|
||||
t = pop_type (info);
|
||||
if (t == NULL)
|
||||
return false;
|
||||
|
||||
if (! pr_fix_visibility (info, visibility))
|
||||
return false;
|
||||
|
||||
return append_type (info, t);
|
||||
}
|
||||
|
||||
/* Finish a struct type. */
|
||||
|
@ -995,9 +1020,10 @@ pr_end_struct_type (p)
|
|||
/* Start a class type. */
|
||||
|
||||
static boolean
|
||||
pr_start_class_type (p, tag, structp, size, vptr, ownvptr)
|
||||
pr_start_class_type (p, tag, id, structp, size, vptr, ownvptr)
|
||||
PTR p;
|
||||
const char *tag;
|
||||
unsigned int id;
|
||||
boolean structp;
|
||||
unsigned int size;
|
||||
boolean vptr;
|
||||
|
@ -1019,10 +1045,18 @@ pr_start_class_type (p, tag, structp, size, vptr, ownvptr)
|
|||
return false;
|
||||
if (tag != NULL)
|
||||
{
|
||||
if (! append_type (info, tag)
|
||||
|| ! append_type (info, " "))
|
||||
if (! append_type (info, tag))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
char idbuf[20];
|
||||
|
||||
sprintf (idbuf, "%%anon%u", id);
|
||||
if (! append_type (info, idbuf))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! append_type (info, " {"))
|
||||
return false;
|
||||
if (size != 0 || vptr || ownvptr)
|
||||
|
@ -1077,19 +1111,26 @@ pr_class_static_member (p, name, physname, visibility)
|
|||
enum debug_visibility visibility;
|
||||
{
|
||||
struct pr_handle *info = (struct pr_handle *) p;
|
||||
|
||||
if (! pr_fix_visibility (info, visibility))
|
||||
return false;
|
||||
char *t;
|
||||
|
||||
if (! substitute_type (info, name))
|
||||
return false;
|
||||
|
||||
return (prepend_type (info, "static ")
|
||||
&& append_type (info, "; /* physname ")
|
||||
&& append_type (info, physname)
|
||||
&& append_type (info, " */\n")
|
||||
&& indent_type (info)
|
||||
&& append_type (info, pop_type (info)));
|
||||
if (! prepend_type (info, "static ")
|
||||
|| ! append_type (info, "; /* ")
|
||||
|| ! append_type (info, physname)
|
||||
|| ! append_type (info, " */\n")
|
||||
|| ! indent_type (info))
|
||||
return false;
|
||||
|
||||
t = pop_type (info);
|
||||
if (t == NULL)
|
||||
return false;
|
||||
|
||||
if (! pr_fix_visibility (info, visibility))
|
||||
return false;
|
||||
|
||||
return append_type (info, t);
|
||||
}
|
||||
|
||||
/* Add a base class to a class. */
|
||||
|
@ -1200,8 +1241,7 @@ pr_class_start_method (p, name)
|
|||
{
|
||||
struct pr_handle *info = (struct pr_handle *) p;
|
||||
|
||||
if (! push_type (info, ""))
|
||||
return false;
|
||||
assert (info->stack != NULL);
|
||||
info->stack->method = name;
|
||||
return true;
|
||||
}
|
||||
|
@ -1209,10 +1249,10 @@ pr_class_start_method (p, name)
|
|||
/* Add a variant to a method. */
|
||||
|
||||
static boolean
|
||||
pr_class_method_variant (p, argtypes, visibility, constp, volatilep, voffset,
|
||||
pr_class_method_variant (p, physname, visibility, constp, volatilep, voffset,
|
||||
context)
|
||||
PTR p;
|
||||
const char *argtypes;
|
||||
const char *physname;
|
||||
enum debug_visibility visibility;
|
||||
boolean constp;
|
||||
boolean volatilep;
|
||||
|
@ -1229,12 +1269,12 @@ pr_class_method_variant (p, argtypes, visibility, constp, volatilep, voffset,
|
|||
/* Put the const and volatile qualifiers on the type. */
|
||||
if (volatilep)
|
||||
{
|
||||
if (! prepend_type (info, "volatile "))
|
||||
if (! append_type (info, " volatile"))
|
||||
return false;
|
||||
}
|
||||
if (constp)
|
||||
{
|
||||
if (! prepend_type (info, "const "))
|
||||
if (! append_type (info, " const"))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1260,15 +1300,15 @@ pr_class_method_variant (p, argtypes, visibility, constp, volatilep, voffset,
|
|||
return false;
|
||||
}
|
||||
|
||||
/* Now the top of the stack is the holder for the method, and the
|
||||
second element on the stack is the class. */
|
||||
/* Now the top of the stack is the class. */
|
||||
|
||||
if (! pr_fix_visibility (info, visibility))
|
||||
return false;
|
||||
|
||||
if (! append_type (info, method_type)
|
||||
|| ! append_type (info, " /* ")
|
||||
|| ! append_type (info, argtypes))
|
||||
|| ! append_type (info, physname)
|
||||
|| ! append_type (info, " "))
|
||||
return false;
|
||||
if (context || voffset != 0)
|
||||
{
|
||||
|
@ -1294,9 +1334,9 @@ pr_class_method_variant (p, argtypes, visibility, constp, volatilep, voffset,
|
|||
/* Add a static variant to a method. */
|
||||
|
||||
static boolean
|
||||
pr_class_static_method_variant (p, argtypes, visibility, constp, volatilep)
|
||||
pr_class_static_method_variant (p, physname, visibility, constp, volatilep)
|
||||
PTR p;
|
||||
const char *argtypes;
|
||||
const char *physname;
|
||||
enum debug_visibility visibility;
|
||||
boolean constp;
|
||||
boolean volatilep;
|
||||
|
@ -1311,12 +1351,12 @@ pr_class_static_method_variant (p, argtypes, visibility, constp, volatilep)
|
|||
/* Put the const and volatile qualifiers on the type. */
|
||||
if (volatilep)
|
||||
{
|
||||
if (! prepend_type (info, "volatile "))
|
||||
if (! append_type (info, " volatile"))
|
||||
return false;
|
||||
}
|
||||
if (constp)
|
||||
{
|
||||
if (! prepend_type (info, "const "))
|
||||
if (! append_type (info, " const"))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1333,15 +1373,14 @@ pr_class_static_method_variant (p, argtypes, visibility, constp, volatilep)
|
|||
if (method_type == NULL)
|
||||
return false;
|
||||
|
||||
/* Now the top of the stack is the holder for the method, and the
|
||||
second element on the stack is the class. */
|
||||
/* Now the top of the stack is the class. */
|
||||
|
||||
if (! pr_fix_visibility (info, visibility))
|
||||
return false;
|
||||
|
||||
return (append_type (info, method_type)
|
||||
&& append_type (info, " /* ")
|
||||
&& append_type (info, argtypes)
|
||||
&& append_type (info, physname)
|
||||
&& append_type (info, " */;\n")
|
||||
&& indent_type (info));
|
||||
}
|
||||
|
@ -1354,11 +1393,8 @@ pr_class_end_method (p)
|
|||
{
|
||||
struct pr_handle *info = (struct pr_handle *) p;
|
||||
|
||||
/* The method variants have been appended to the string on top of
|
||||
the stack with the correct indentation. We just need the append
|
||||
the string on top of the stack to the class string that is second
|
||||
on the stack. */
|
||||
return append_type (info, pop_type (info));
|
||||
info->stack->method = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Finish up a class. */
|
||||
|
@ -1385,13 +1421,15 @@ pr_typedef_type (p, name)
|
|||
/* Push a type on the stack using a tag name. */
|
||||
|
||||
static boolean
|
||||
pr_tag_type (p, name, kind)
|
||||
pr_tag_type (p, name, id, kind)
|
||||
PTR p;
|
||||
const char *name;
|
||||
unsigned int id;
|
||||
enum debug_type_kind kind;
|
||||
{
|
||||
struct pr_handle *info = (struct pr_handle *) p;
|
||||
const char *t;
|
||||
const char *t, *tag;
|
||||
char idbuf[20];
|
||||
|
||||
switch (kind)
|
||||
{
|
||||
|
@ -1415,8 +1453,17 @@ pr_tag_type (p, name, kind)
|
|||
return false;
|
||||
}
|
||||
|
||||
return (push_type (info, t)
|
||||
&& append_type (info, name));
|
||||
if (! push_type (info, t))
|
||||
return false;
|
||||
if (name != NULL)
|
||||
tag = name;
|
||||
else
|
||||
{
|
||||
sprintf (idbuf, "%%anon%u", id);
|
||||
tag = idbuf;
|
||||
}
|
||||
|
||||
return append_type (info, tag);
|
||||
}
|
||||
|
||||
/* Output a typedef. */
|
||||
|
|
Loading…
Reference in a new issue