* 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:
Ian Lance Taylor 1996-01-19 18:03:04 +00:00
parent 8c038399b5
commit 07aa1e1b7a
4 changed files with 502 additions and 145 deletions

View file

@ -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))

View file

@ -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

View file

@ -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;

View file

@ -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,14 +873,22 @@ 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;
}
if (size != 0)
sprintf (ab, "{ /* size %u */\n", size);
else
strcpy (ab, "{\n");
{
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
strcpy (ab, " {\n");
if (! append_type (info, ab))
return false;
info->stack->visibility = DEBUG_VISIBILITY_PUBLIC;
@ -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,11 +1045,19 @@ 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;
}
if (! append_type (info, "{"))
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. */