aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--binutils/debug.c317
-rw-r--r--binutils/debug.h109
-rw-r--r--binutils/ieee.c48
-rw-r--r--binutils/prdbg.c169
4 files changed, 500 insertions, 143 deletions
diff --git a/binutils/debug.c b/binutils/debug.c
index 02a80ae..edb5835 100644
--- a/binutils/debug.c
+++ b/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;
@@ -2361,10 +2583,18 @@ debug_write_type (info, fns, fhandle, type, name)
{
for (i = 0; type->u.kmethod->arg_types[i] != NULL; i++)
{
- if (! debug_write_type (info, fns, fhandle,
- type->u.kmethod->arg_types[i],
- (struct debug_name *) NULL))
- return false;
+ 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],
+ (struct debug_name *) NULL))
+ return false;
+ }
}
}
if (type->u.kmethod->domain_type != NULL)
@@ -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
+ {
+ if (info->class_mark == type->u.kclass->mark
+ || type->u.kclass->id > info->base_id)
{
- /* 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);
+ /* 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))
diff --git a/binutils/debug.h b/binutils/debug.h
index 0c3a692..d40679b 100644
--- a/binutils/debug.h
+++ b/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
diff --git a/binutils/ieee.c b/binutils/ieee.c
index ac85f73..0006460 100644
--- a/binutils/ieee.c
+++ b/binutils/ieee.c
@@ -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;
diff --git a/binutils/prdbg.c b/binutils/prdbg.c
index 133973c..f7383bb 100644
--- a/binutils/prdbg.c
+++ b/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,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;
+ }
+ 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);
+ sprintf (ab, " { /* size %u */\n", size);
else
- strcpy (ab, "{\n");
+ 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;
+ char *t;
- if (! pr_fix_visibility (info, visibility))
+ if (! substitute_type (info, name))
return false;
- if (! substitute_type (info, name))
+ if (! prepend_type (info, "static ")
+ || ! append_type (info, "; /* ")
+ || ! append_type (info, physname)
+ || ! append_type (info, " */\n")
+ || ! indent_type (info))
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)));
+ 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. */