* debug.c (debug_make_undefined_tagged_type): Make sure we are
given a kind of type we can handle. (debug_write_type): Handle undefined enums and structs. (debug_write_class_type): Handle undefined classes. * prdbg.c (pr_enum_type): Handle an undefined enum. Also comment changes to debug.h.
This commit is contained in:
parent
761f377fec
commit
36302909f2
4 changed files with 161 additions and 111 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
Thu Jan 11 11:45:34 1996 Ian Lance Taylor <ian@cygnus.com>
|
||||||
|
|
||||||
|
* debug.c (debug_make_undefined_tagged_type): Make sure we are
|
||||||
|
given a kind of type we can handle.
|
||||||
|
(debug_write_type): Handle undefined enums and structs.
|
||||||
|
(debug_write_class_type): Handle undefined classes.
|
||||||
|
* prdbg.c (pr_enum_type): Handle an undefined enum.
|
||||||
|
|
||||||
Wed Jan 10 15:33:18 1996 Ian Lance Taylor <ian@cygnus.com>
|
Wed Jan 10 15:33:18 1996 Ian Lance Taylor <ian@cygnus.com>
|
||||||
|
|
||||||
* Makefile.in: Updated dependencies.
|
* Makefile.in: Updated dependencies.
|
||||||
|
|
213
binutils/debug.c
213
binutils/debug.c
|
@ -1706,6 +1706,20 @@ debug_make_undefined_tagged_type (handle, name, kind)
|
||||||
if (name == NULL)
|
if (name == NULL)
|
||||||
return DEBUG_TYPE_NULL;
|
return DEBUG_TYPE_NULL;
|
||||||
|
|
||||||
|
switch (kind)
|
||||||
|
{
|
||||||
|
case DEBUG_KIND_STRUCT:
|
||||||
|
case DEBUG_KIND_UNION:
|
||||||
|
case DEBUG_KIND_CLASS:
|
||||||
|
case DEBUG_KIND_UNION_CLASS:
|
||||||
|
case DEBUG_KIND_ENUM:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
debug_error ("debug_make_undefined_type: unsupported kind");
|
||||||
|
return DEBUG_TYPE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
t = debug_make_type (info, kind, 0);
|
t = debug_make_type (info, kind, 0);
|
||||||
if (t == NULL)
|
if (t == NULL)
|
||||||
return DEBUG_TYPE_NULL;
|
return DEBUG_TYPE_NULL;
|
||||||
|
@ -2250,19 +2264,24 @@ debug_write_type (info, fns, fhandle, type, name)
|
||||||
return (*fns->bool_type) (fhandle, type->size);
|
return (*fns->bool_type) (fhandle, type->size);
|
||||||
case DEBUG_KIND_STRUCT:
|
case DEBUG_KIND_STRUCT:
|
||||||
case DEBUG_KIND_UNION:
|
case DEBUG_KIND_UNION:
|
||||||
if (info->class_mark == type->u.kclass->mark)
|
if (type->u.kclass != NULL)
|
||||||
{
|
{
|
||||||
/* We are currently outputting this struct. I don't know if
|
if (info->class_mark == type->u.kclass->mark)
|
||||||
this can happen, but it can happen for a class. */
|
{
|
||||||
return (*fns->tag_type) (fhandle, "?defining?", type->kind);
|
/* 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);
|
||||||
|
}
|
||||||
|
type->u.kclass->mark = info->class_mark;
|
||||||
}
|
}
|
||||||
type->u.kclass->mark = info->class_mark;
|
|
||||||
|
|
||||||
if (! (*fns->start_struct_type) (fhandle, tag,
|
if (! (*fns->start_struct_type) (fhandle, tag,
|
||||||
type->kind == DEBUG_KIND_STRUCT,
|
type->kind == DEBUG_KIND_STRUCT,
|
||||||
type->size))
|
type->size))
|
||||||
return false;
|
return false;
|
||||||
if (type->u.kclass->fields != NULL)
|
if (type->u.kclass != NULL
|
||||||
|
&& type->u.kclass->fields != NULL)
|
||||||
{
|
{
|
||||||
for (i = 0; type->u.kclass->fields[i] != NULL; i++)
|
for (i = 0; type->u.kclass->fields[i] != NULL; i++)
|
||||||
{
|
{
|
||||||
|
@ -2281,6 +2300,9 @@ debug_write_type (info, fns, fhandle, type, name)
|
||||||
case DEBUG_KIND_UNION_CLASS:
|
case DEBUG_KIND_UNION_CLASS:
|
||||||
return debug_write_class_type (info, fns, fhandle, type, tag);
|
return debug_write_class_type (info, fns, fhandle, type, tag);
|
||||||
case DEBUG_KIND_ENUM:
|
case DEBUG_KIND_ENUM:
|
||||||
|
if (type->u.kenum == NULL)
|
||||||
|
return (*fns->enum_type) (fhandle, tag, (const char **) NULL,
|
||||||
|
(bfd_signed_vma *) NULL);
|
||||||
return (*fns->enum_type) (fhandle, tag, type->u.kenum->names,
|
return (*fns->enum_type) (fhandle, tag, type->u.kenum->names,
|
||||||
type->u.kenum->values);
|
type->u.kenum->values);
|
||||||
case DEBUG_KIND_POINTER:
|
case DEBUG_KIND_POINTER:
|
||||||
|
@ -2389,20 +2411,24 @@ debug_write_class_type (info, fns, fhandle, type, tag)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
if (info->class_mark == type->u.kclass->mark)
|
if (type->u.kclass != NULL)
|
||||||
{
|
{
|
||||||
/* We are currently outputting this class. This can happen when
|
if (info->class_mark == type->u.kclass->mark)
|
||||||
there are methods for an anonymous class. */
|
{
|
||||||
return (*fns->tag_type) (fhandle, "?defining?", type->kind);
|
/* We are currently outputting this class. This can happen
|
||||||
}
|
when there are methods for an anonymous class. */
|
||||||
type->u.kclass->mark = info->class_mark;
|
return (*fns->tag_type) (fhandle, "?defining?", type->kind);
|
||||||
|
}
|
||||||
|
type->u.kclass->mark = info->class_mark;
|
||||||
|
|
||||||
if (type->u.kclass->vptrbase != NULL
|
if (type->u.kclass->vptrbase != NULL
|
||||||
&& type->u.kclass->vptrbase != type)
|
&& type->u.kclass->vptrbase != type)
|
||||||
{
|
{
|
||||||
if (! debug_write_type (info, fns, fhandle, type->u.kclass->vptrbase,
|
if (! debug_write_type (info, fns, fhandle,
|
||||||
(struct debug_name *) NULL))
|
type->u.kclass->vptrbase,
|
||||||
return false;
|
(struct debug_name *) NULL))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! (*fns->start_class_type) (fhandle, tag,
|
if (! (*fns->start_class_type) (fhandle, tag,
|
||||||
|
@ -2411,93 +2437,98 @@ debug_write_class_type (info, fns, fhandle, type, tag)
|
||||||
type->u.kclass->vptrbase != NULL,
|
type->u.kclass->vptrbase != NULL,
|
||||||
type->u.kclass->vptrbase == type))
|
type->u.kclass->vptrbase == type))
|
||||||
return false;
|
return false;
|
||||||
if (type->u.kclass->fields != NULL)
|
|
||||||
|
if (type->u.kclass != NULL)
|
||||||
{
|
{
|
||||||
for (i = 0; type->u.kclass->fields[i] != NULL; i++)
|
if (type->u.kclass->fields != NULL)
|
||||||
{
|
{
|
||||||
struct debug_field *f;
|
for (i = 0; type->u.kclass->fields[i] != NULL; i++)
|
||||||
|
|
||||||
f = type->u.kclass->fields[i];
|
|
||||||
if (! debug_write_type (info, fns, fhandle, f->type,
|
|
||||||
(struct debug_name *) NULL))
|
|
||||||
return false;
|
|
||||||
if (f->static_member)
|
|
||||||
{
|
{
|
||||||
if (! (*fns->class_static_member) (fhandle, f->name,
|
struct debug_field *f;
|
||||||
f->u.s.physname,
|
|
||||||
f->visibility))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (! (*fns->struct_field) (fhandle, f->name, f->u.f.bitpos,
|
|
||||||
f->u.f.bitsize, f->visibility))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type->u.kclass->baseclasses != NULL)
|
f = type->u.kclass->fields[i];
|
||||||
{
|
if (! debug_write_type (info, fns, fhandle, f->type,
|
||||||
for (i = 0; type->u.kclass->baseclasses[i] != NULL; i++)
|
|
||||||
{
|
|
||||||
struct debug_baseclass *b;
|
|
||||||
|
|
||||||
b = type->u.kclass->baseclasses[i];
|
|
||||||
if (! debug_write_type (info, fns, fhandle, b->type,
|
|
||||||
(struct debug_name *) NULL))
|
|
||||||
return false;
|
|
||||||
if (! (*fns->class_baseclass) (fhandle, b->bitpos, b->virtual,
|
|
||||||
b->visibility))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type->u.kclass->methods != NULL)
|
|
||||||
{
|
|
||||||
for (i = 0; type->u.kclass->methods[i] != NULL; i++)
|
|
||||||
{
|
|
||||||
struct debug_method *m;
|
|
||||||
unsigned int j;
|
|
||||||
|
|
||||||
m = type->u.kclass->methods[i];
|
|
||||||
if (! (*fns->class_start_method) (fhandle, m->name))
|
|
||||||
return false;
|
|
||||||
for (j = 0; m->variants[j] != NULL; j++)
|
|
||||||
{
|
|
||||||
struct debug_method_variant *v;
|
|
||||||
|
|
||||||
v = m->variants[j];
|
|
||||||
if (v->context != NULL)
|
|
||||||
{
|
|
||||||
if (! debug_write_type (info, fns, fhandle, v->context,
|
|
||||||
(struct debug_name *) NULL))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (! debug_write_type (info, fns, fhandle, v->type,
|
|
||||||
(struct debug_name *) NULL))
|
(struct debug_name *) NULL))
|
||||||
return false;
|
return false;
|
||||||
if (v->voffset != VOFFSET_STATIC_METHOD)
|
if (f->static_member)
|
||||||
{
|
{
|
||||||
if (! (*fns->class_method_variant) (fhandle, v->argtypes,
|
if (! (*fns->class_static_member) (fhandle, f->name,
|
||||||
v->visibility,
|
f->u.s.physname,
|
||||||
v->constp, v->volatilep,
|
f->visibility))
|
||||||
v->voffset,
|
|
||||||
v->context != NULL))
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (! (*fns->class_static_method_variant) (fhandle,
|
if (! (*fns->struct_field) (fhandle, f->name, f->u.f.bitpos,
|
||||||
v->argtypes,
|
f->u.f.bitsize, f->visibility))
|
||||||
v->visibility,
|
|
||||||
v->constp,
|
|
||||||
v->volatilep))
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (! (*fns->class_end_method) (fhandle))
|
}
|
||||||
return false;
|
|
||||||
|
if (type->u.kclass->baseclasses != NULL)
|
||||||
|
{
|
||||||
|
for (i = 0; type->u.kclass->baseclasses[i] != NULL; i++)
|
||||||
|
{
|
||||||
|
struct debug_baseclass *b;
|
||||||
|
|
||||||
|
b = type->u.kclass->baseclasses[i];
|
||||||
|
if (! debug_write_type (info, fns, fhandle, b->type,
|
||||||
|
(struct debug_name *) NULL))
|
||||||
|
return false;
|
||||||
|
if (! (*fns->class_baseclass) (fhandle, b->bitpos, b->virtual,
|
||||||
|
b->visibility))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type->u.kclass->methods != NULL)
|
||||||
|
{
|
||||||
|
for (i = 0; type->u.kclass->methods[i] != NULL; i++)
|
||||||
|
{
|
||||||
|
struct debug_method *m;
|
||||||
|
unsigned int j;
|
||||||
|
|
||||||
|
m = type->u.kclass->methods[i];
|
||||||
|
if (! (*fns->class_start_method) (fhandle, m->name))
|
||||||
|
return false;
|
||||||
|
for (j = 0; m->variants[j] != NULL; j++)
|
||||||
|
{
|
||||||
|
struct debug_method_variant *v;
|
||||||
|
|
||||||
|
v = m->variants[j];
|
||||||
|
if (v->context != NULL)
|
||||||
|
{
|
||||||
|
if (! debug_write_type (info, fns, fhandle, v->context,
|
||||||
|
(struct debug_name *) NULL))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (! debug_write_type (info, fns, fhandle, v->type,
|
||||||
|
(struct debug_name *) NULL))
|
||||||
|
return false;
|
||||||
|
if (v->voffset != VOFFSET_STATIC_METHOD)
|
||||||
|
{
|
||||||
|
if (! (*fns->class_method_variant) (fhandle, v->argtypes,
|
||||||
|
v->visibility,
|
||||||
|
v->constp,
|
||||||
|
v->volatilep,
|
||||||
|
v->voffset,
|
||||||
|
v->context != NULL))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (! (*fns->class_static_method_variant) (fhandle,
|
||||||
|
v->argtypes,
|
||||||
|
v->visibility,
|
||||||
|
v->constp,
|
||||||
|
v->volatilep))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (! (*fns->class_end_method) (fhandle))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -194,7 +194,8 @@ struct debug_write_fns
|
||||||
|
|
||||||
/* Push an enum type onto the type stack, given the tag, a NULL
|
/* Push an enum type onto the type stack, given the tag, a NULL
|
||||||
terminated array of names and the associated values. If there is
|
terminated array of names and the associated values. If there is
|
||||||
no tag, the tag argument will be NULL. */
|
no tag, the tag argument will be NULL. If this is an undefined
|
||||||
|
enum, the names and values arguments will be NULL. */
|
||||||
boolean (*enum_type) PARAMS ((PTR, const char *, const char **,
|
boolean (*enum_type) PARAMS ((PTR, const char *, const char **,
|
||||||
bfd_signed_vma *));
|
bfd_signed_vma *));
|
||||||
|
|
||||||
|
@ -259,7 +260,9 @@ struct debug_write_fns
|
||||||
end_struct_type function. The second argument is the tag; this
|
end_struct_type function. The second argument is the tag; this
|
||||||
will be NULL if there isn't one. The boolean argument is true
|
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
|
for a struct, false for a union. The unsigned int argument is
|
||||||
the size. */
|
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,
|
boolean (*start_struct_type) PARAMS ((PTR, const char *, boolean,
|
||||||
unsigned int));
|
unsigned int));
|
||||||
|
|
||||||
|
|
|
@ -519,30 +519,38 @@ pr_enum_type (p, tag, names, values)
|
||||||
if (! append_type (info, "{ "))
|
if (! append_type (info, "{ "))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
val = 0;
|
if (names == NULL)
|
||||||
for (i = 0; names[i] != NULL; i++)
|
|
||||||
{
|
{
|
||||||
if (i > 0)
|
if (! append_type (info, "/* undefined */"))
|
||||||
{
|
|
||||||
if (! append_type (info, ", "))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! append_type (info, names[i]))
|
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
if (values[i] != val)
|
else
|
||||||
|
{
|
||||||
|
val = 0;
|
||||||
|
for (i = 0; names[i] != NULL; i++)
|
||||||
{
|
{
|
||||||
char ab[20];
|
if (i > 0)
|
||||||
|
{
|
||||||
|
if (! append_type (info, ", "))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
print_vma (values[i], ab, false, false);
|
if (! append_type (info, names[i]))
|
||||||
if (! append_type (info, " = ")
|
|
||||||
|| ! append_type (info, ab))
|
|
||||||
return false;
|
return false;
|
||||||
val = values[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
++val;
|
if (values[i] != val)
|
||||||
|
{
|
||||||
|
char ab[20];
|
||||||
|
|
||||||
|
print_vma (values[i], ab, false, false);
|
||||||
|
if (! append_type (info, " = ")
|
||||||
|
|| ! append_type (info, ab))
|
||||||
|
return false;
|
||||||
|
val = values[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
++val;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return append_type (info, " }");
|
return append_type (info, " }");
|
||||||
|
|
Loading…
Add table
Reference in a new issue