* ieee.c: Various changes to write out types for functions and

references, and to not write out unnecessary function types.
This commit is contained in:
Ian Lance Taylor 1996-01-24 19:40:21 +00:00
parent a837b8fc96
commit 2466210755
2 changed files with 474 additions and 162 deletions

View File

@ -1,5 +1,8 @@
Wed Jan 24 12:06:05 1996 Ian Lance Taylor <ian@cygnus.com>
* ieee.c: Various changes to write out types for functions and
references, and to not write out unnecessary function types.
* ieee.c (struct ieee_var): Remove variable field. Add kind
field, and define some enum constants for it.
(parse_ieee_ty): Set kind field of variable for 'x' and 'X' types.

View File

@ -3505,6 +3505,8 @@ struct ieee_type_class
bfd_vma voffset;
/* The current method. */
const char *method;
/* Additional pmisc records used to record fields of reference type. */
struct ieee_buf *refs;
};
/* This is how we store types for the writing routines. Most types
@ -3516,6 +3518,9 @@ struct ieee_write_type
unsigned int indx;
/* The size of the type, if known. */
unsigned int size;
/* If this is a function or method type, we build the type here, and
only add it to the output buffers if we need it. */
struct ieee_buf *fndef;
/* If this is a struct, this is where the struct definition is
built. */
struct ieee_buf *strdef;
@ -3566,6 +3571,8 @@ struct ieee_pending_parm
const char *name;
/* Type index. */
unsigned int type;
/* Whether the type is a reference. */
boolean referencep;
/* Kind. */
enum debug_parm_kind kind;
/* Value. */
@ -3613,6 +3620,16 @@ struct ieee_handle
/* The depth of block nesting. This is 0 outside a function, and 1
just after start_function is called. */
unsigned int block_depth;
/* The name of the current function. */
const char *fnname;
/* List of buffers for the type of the function we are currently
writing out. */
struct ieee_buf *fntype;
/* List of buffers for the parameters of the function we are
currently writing out. */
struct ieee_buf *fnargs;
/* Number of arguments written to fnargs. */
unsigned int fnargcount;
/* Pending function parameters. */
struct ieee_pending_parm *pending_parms;
/* Current line number filename. */
@ -3625,13 +3642,6 @@ struct ieee_handle
static boolean ieee_change_buffer
PARAMS ((struct ieee_handle *, struct ieee_buf **));
static boolean ieee_push_type
PARAMS ((struct ieee_handle *, unsigned int, unsigned int, boolean));
static unsigned int ieee_pop_type PARAMS ((struct ieee_handle *));
static boolean ieee_add_range
PARAMS ((struct ieee_handle *, bfd_vma, bfd_vma));
static boolean ieee_start_range PARAMS ((struct ieee_handle *, bfd_vma));
static boolean ieee_end_range PARAMS ((struct ieee_handle *, bfd_vma));
static boolean ieee_real_write_byte PARAMS ((struct ieee_handle *, int));
static boolean ieee_write_2bytes PARAMS ((struct ieee_handle *, int));
static boolean ieee_write_number PARAMS ((struct ieee_handle *, bfd_vma));
@ -3640,6 +3650,16 @@ static boolean ieee_write_asn
PARAMS ((struct ieee_handle *, unsigned int, bfd_vma));
static boolean ieee_write_atn65
PARAMS ((struct ieee_handle *, unsigned int, const char *));
static boolean ieee_push_type
PARAMS ((struct ieee_handle *, unsigned int, unsigned int, boolean));
static unsigned int ieee_pop_type PARAMS ((struct ieee_handle *));
static void ieee_pop_unused_type PARAMS ((struct ieee_handle *));
static unsigned int ieee_pop_type_used
PARAMS ((struct ieee_handle *, boolean));
static boolean ieee_add_range
PARAMS ((struct ieee_handle *, bfd_vma, bfd_vma));
static boolean ieee_start_range PARAMS ((struct ieee_handle *, bfd_vma));
static boolean ieee_end_range PARAMS ((struct ieee_handle *, bfd_vma));
static boolean ieee_define_type
PARAMS ((struct ieee_handle *, unsigned int, boolean));
static boolean ieee_define_named_type
@ -3786,135 +3806,6 @@ ieee_change_buffer (info, ppbuf)
return true;
}
/* Push a type index onto the type stack. */
static boolean
ieee_push_type (info, indx, size, unsignedp)
struct ieee_handle *info;
unsigned int indx;
unsigned int size;
boolean unsignedp;
{
struct ieee_type_stack *ts;
ts = (struct ieee_type_stack *) xmalloc (sizeof *ts);
memset (ts, 0, sizeof *ts);
ts->type.indx = indx;
ts->type.size = size;
ts->type.unsignedp = unsignedp;
ts->next = info->type_stack;
info->type_stack = ts;
return true;
}
/* Pop a type index off the type stack. */
static unsigned int
ieee_pop_type (info)
struct ieee_handle *info;
{
struct ieee_type_stack *ts;
unsigned int ret;
ts = info->type_stack;
assert (ts != NULL);
ret = ts->type.indx;
info->type_stack = ts->next;
free (ts);
return ret;
}
/* Add a range of bytes included in the current compilation unit. */
static boolean
ieee_add_range (info, low, high)
struct ieee_handle *info;
bfd_vma low;
bfd_vma high;
{
struct ieee_range *r, **pr;
if (low == (bfd_vma) -1 || high == (bfd_vma) -1)
return true;
for (r = info->ranges; r != NULL; r = r->next)
{
if (high >= r->low && low <= r->high)
{
/* The new range overlaps r. */
if (low < r->low)
r->low = low;
if (high > r->high)
r->high = high;
pr = &r->next;
while (*pr != NULL && (*pr)->low <= r->high)
{
struct ieee_range *n;
if ((*pr)->high > r->high)
r->high = (*pr)->high;
n = (*pr)->next;
free (*pr);
*pr = n;
}
return true;
}
}
r = (struct ieee_range *) xmalloc (sizeof *r);
memset (r, 0, sizeof *r);
r->low = low;
r->high = high;
/* Store the ranges sorted by address. */
for (pr = &info->ranges; *pr != NULL; pr = &(*pr)->next)
if ((*pr)->next != NULL && (*pr)->next->low > high)
break;
r->next = *pr;
*pr = r;
return true;
}
/* Start a new range for which we only have the low address. */
static boolean
ieee_start_range (info, low)
struct ieee_handle *info;
bfd_vma low;
{
struct ieee_range *r;
r = (struct ieee_range *) xmalloc (sizeof *r);
memset (r, 0, sizeof *r);
r->low = low;
r->next = info->pending_ranges;
info->pending_ranges = r;
return true;
}
/* Finish a range started by ieee_start_range. */
static boolean
ieee_end_range (info, high)
struct ieee_handle *info;
bfd_vma high;
{
struct ieee_range *r;
bfd_vma low;
assert (info->pending_ranges != NULL);
r = info->pending_ranges;
low = r->low;
info->pending_ranges = r->next;
free (r);
return ieee_add_range (info, low, high);
}
/* Write a byte into the buffer. We use a macro for speed and a
function for the complex cases. */
@ -4068,6 +3959,177 @@ ieee_write_atn65 (info, indx, s)
&& ieee_write_id (info, s));
}
/* Push a type index onto the type stack. */
static boolean
ieee_push_type (info, indx, size, unsignedp)
struct ieee_handle *info;
unsigned int indx;
unsigned int size;
boolean unsignedp;
{
struct ieee_type_stack *ts;
ts = (struct ieee_type_stack *) xmalloc (sizeof *ts);
memset (ts, 0, sizeof *ts);
ts->type.indx = indx;
ts->type.size = size;
ts->type.unsignedp = unsignedp;
ts->next = info->type_stack;
info->type_stack = ts;
return true;
}
/* Pop a type index off the type stack. */
static unsigned int
ieee_pop_type (info)
struct ieee_handle *info;
{
return ieee_pop_type_used (info, true);
}
/* Pop an unused type index off the type stack. */
static void
ieee_pop_unused_type (info)
struct ieee_handle *info;
{
(void) ieee_pop_type_used (info, false);
}
/* Pop a used or unused type index off the type stack. */
static unsigned int
ieee_pop_type_used (info, used)
struct ieee_handle *info;
boolean used;
{
struct ieee_type_stack *ts;
unsigned int ret;
ts = info->type_stack;
assert (ts != NULL);
/* If this is a function type, and we need it, we need to append the
actual definition to the typedef block now. */
if (ts->type.fndef != NULL && used)
{
struct ieee_buf **pb;
/* Make sure we have started the types block. */
if (info->types == NULL)
{
if (! ieee_change_buffer (info, &info->types)
|| ! ieee_write_byte (info, (int) ieee_bb_record_enum)
|| ! ieee_write_byte (info, 1)
|| ! ieee_write_number (info, 0)
|| ! ieee_write_id (info, info->modname))
return false;
}
for (pb = &info->types; *pb != NULL; pb = &(*pb)->next)
;
*pb = ts->type.fndef;
}
ret = ts->type.indx;
info->type_stack = ts->next;
free (ts);
return ret;
}
/* Add a range of bytes included in the current compilation unit. */
static boolean
ieee_add_range (info, low, high)
struct ieee_handle *info;
bfd_vma low;
bfd_vma high;
{
struct ieee_range *r, **pr;
if (low == (bfd_vma) -1 || high == (bfd_vma) -1)
return true;
for (r = info->ranges; r != NULL; r = r->next)
{
if (high >= r->low && low <= r->high)
{
/* The new range overlaps r. */
if (low < r->low)
r->low = low;
if (high > r->high)
r->high = high;
pr = &r->next;
while (*pr != NULL && (*pr)->low <= r->high)
{
struct ieee_range *n;
if ((*pr)->high > r->high)
r->high = (*pr)->high;
n = (*pr)->next;
free (*pr);
*pr = n;
}
return true;
}
}
r = (struct ieee_range *) xmalloc (sizeof *r);
memset (r, 0, sizeof *r);
r->low = low;
r->high = high;
/* Store the ranges sorted by address. */
for (pr = &info->ranges; *pr != NULL; pr = &(*pr)->next)
if ((*pr)->next != NULL && (*pr)->next->low > high)
break;
r->next = *pr;
*pr = r;
return true;
}
/* Start a new range for which we only have the low address. */
static boolean
ieee_start_range (info, low)
struct ieee_handle *info;
bfd_vma low;
{
struct ieee_range *r;
r = (struct ieee_range *) xmalloc (sizeof *r);
memset (r, 0, sizeof *r);
r->low = low;
r->next = info->pending_ranges;
info->pending_ranges = r;
return true;
}
/* Finish a range started by ieee_start_range. */
static boolean
ieee_end_range (info, high)
struct ieee_handle *info;
bfd_vma high;
{
struct ieee_range *r;
bfd_vma low;
assert (info->pending_ranges != NULL);
r = info->pending_ranges;
low = r->low;
info->pending_ranges = r->next;
free (r);
return ieee_add_range (info, low, high);
}
/* Start defining a type. */
static boolean
@ -4748,7 +4810,10 @@ ieee_pointer_type (p)
&& ieee_write_number (info, indx));
}
/* Make a function type. */
/* Make a function type. This will be called for a method, but we
don't want to actually add it to the type table in that case. We
handle this by defining the type in a private buffer, and only
adding that buffer to the typedef block if we are going to use it. */
static boolean
ieee_function_type (p, argcount, varargs)
@ -4760,6 +4825,7 @@ ieee_function_type (p, argcount, varargs)
unsigned int *args = NULL;
int i;
unsigned int retindx;
struct ieee_buf *fndef;
if (argcount > 0)
{
@ -4774,7 +4840,9 @@ ieee_function_type (p, argcount, varargs)
/* An attribute of 0x41 means that the frame and push mask are
unknown. */
if (! ieee_define_type (info, 0, true)
fndef = NULL;
if (! ieee_define_named_type (info, (const char *) NULL, false, 0, 0,
true, &fndef)
|| ! ieee_write_number (info, 'x')
|| ! ieee_write_number (info, 0x41)
|| ! ieee_write_number (info, 0)
@ -4797,7 +4865,14 @@ ieee_function_type (p, argcount, varargs)
return false;
}
return ieee_write_number (info, 0);
if (! ieee_write_number (info, 0))
return false;
/* We wrote the information into fndef, in case we don't need it.
It will be appended to info->types by ieee_pop_type. */
info->type_stack->type.fndef = fndef;
return true;
}
/* Make a reference type. */
@ -4831,7 +4906,7 @@ ieee_range_type (p, low, high)
size = info->type_stack->type.size;
unsignedp = info->type_stack->type.unsignedp;
(void) ieee_pop_type (info);
ieee_pop_unused_type (info);
return (ieee_define_type (info, size, unsignedp)
&& ieee_write_number (info, 'R')
&& ieee_write_number (info, (bfd_vma) low)
@ -4854,7 +4929,7 @@ ieee_array_type (p, low, high, stringp)
unsigned int eleindx;
/* IEEE does not store the range, so we just ignore it. */
(void) ieee_pop_type (info);
ieee_pop_unused_type (info);
eleindx = ieee_pop_type (info);
if (! ieee_define_type (info, 0, false)
@ -4928,7 +5003,7 @@ ieee_method_type (p, domain, argcount, varargs)
type. */
if (domain)
(void) ieee_pop_type (info);
ieee_pop_unused_type (info);
return ieee_function_type (p, argcount, varargs);
}
@ -5032,11 +5107,13 @@ ieee_struct_field (p, name, bitpos, bitsize, visibility)
struct ieee_handle *info = (struct ieee_handle *) p;
unsigned int size;
boolean unsignedp;
boolean referencep;
unsigned int indx;
bfd_vma offset;
size = info->type_stack->type.size;
unsignedp = info->type_stack->type.unsignedp;
referencep = info->type_stack->type.referencep;
indx = ieee_pop_type (info);
assert (info->type_stack != NULL && info->type_stack->type.strdef != NULL);
@ -5059,6 +5136,37 @@ ieee_struct_field (p, name, bitpos, bitsize, visibility)
|| ! ieee_write_atn65 (info, nindx, name))
return false;
info->type_stack->type.classdef->pmisccount += 4;
if (referencep)
{
unsigned int nindx;
/* We need to output a record recording that this field is
really of reference type. We put this on the refs field
of classdef, so that it can be appended to the C++
records after the class is defined. */
nindx = info->name_indx;
++info->name_indx;
if (! ieee_change_buffer (info,
&info->type_stack->type.classdef->refs)
|| ! ieee_write_byte (info, (int) ieee_nn_record)
|| ! ieee_write_number (info, nindx)
|| ! ieee_write_id (info, "")
|| ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
|| ! ieee_write_number (info, nindx)
|| ! ieee_write_number (info, 0)
|| ! ieee_write_number (info, 62)
|| ! ieee_write_number (info, 80)
|| ! ieee_write_number (info, 4)
|| ! ieee_write_asn (info, nindx, 'R')
|| ! ieee_write_asn (info, nindx, 3)
|| ! ieee_write_atn65 (info, nindx,
info->type_stack->type.classdef->name)
|| ! ieee_write_atn65 (info, nindx, name))
return false;
}
}
/* If the bitsize doesn't match the expected size, we need to output
@ -5158,6 +5266,8 @@ ieee_start_class_type (p, tag, id, structp, size, vptr, ownvptr)
{
assert (info->type_stack->type.classdef != NULL);
vclass = info->type_stack->type.classdef->name;
/* We don't call ieee_pop_unused_type, since the class should
get defined. */
(void) ieee_pop_type (info);
}
@ -5214,10 +5324,10 @@ ieee_class_static_member (p, name, physname, visibility)
unsigned int flags;
unsigned int nindx;
/* We don't care about the type. Hopefully there will be a call
/* We don't care about the type. Hopefully there will be a call to
ieee_variable declaring the physical name and the type, since
that is where an IEEE consumer must get the type. */
(void) ieee_pop_type (info);
ieee_pop_unused_type (info);
assert (info->type_stack != NULL
&& info->type_stack->type.classdef != NULL);
@ -5345,12 +5455,12 @@ ieee_class_method_var (info, physname, visibility, staticp, constp,
/* We don't need the type of the method. An IEEE consumer which
wants the type must track down the function by the physical name
and get the type from that. */
(void) ieee_pop_type (info);
ieee_pop_unused_type (info);
/* We don't use the context. FIXME: We probably ought to use it to
adjust the voffset somehow, but I don't really know how. */
if (context)
(void) ieee_pop_type (info);
ieee_pop_unused_type (info);
assert (info->type_stack != NULL
&& info->type_stack->type.classdef != NULL
@ -5518,6 +5628,12 @@ ieee_end_class_type (p)
for (pb = &info->cxx; *pb != NULL; pb = &(*pb)->next)
;
*pb = info->type_stack->type.classdef->pmiscbuf;
if (info->type_stack->type.classdef->refs != NULL)
{
for (; *pb != NULL; pb = &(*pb)->next)
;
*pb = info->type_stack->type.classdef->refs;
}
return ieee_end_struct_type (p);
}
@ -5790,7 +5906,9 @@ ieee_typdef (p, name)
|| ! ieee_write_number (info, indx))
return false;
/* Remove the type we just added to the type stack. */
/* Remove the type we just added to the type stack. This should not
be ieee_pop_unused_type, since the type is used, we just don't
need it now. */
(void) ieee_pop_type (info);
return true;
@ -5805,6 +5923,8 @@ ieee_tag (p, name)
{
struct ieee_handle *info = (struct ieee_handle *) p;
/* This should not be ieee_pop_unused_type, since we want the type
to be defined. */
(void) ieee_pop_type (info);
return true;
}
@ -5844,7 +5964,7 @@ ieee_typed_constant (p, name, val)
struct ieee_handle *info = (struct ieee_handle *) p;
/* FIXME. */
(void) ieee_pop_type (info);
ieee_pop_unused_type (info);
return true;
}
@ -5860,8 +5980,14 @@ ieee_variable (p, name, kind, val)
struct ieee_handle *info = (struct ieee_handle *) p;
unsigned int name_indx;
unsigned int size;
boolean referencep;
unsigned int type_indx;
boolean asn;
int refflag;
size = info->type_stack->type.size;
referencep = info->type_stack->type.referencep;
type_indx = ieee_pop_type (info);
/* Make sure the variable section is started. */
if (info->vars != NULL)
@ -5882,9 +6008,6 @@ ieee_variable (p, name, kind, val)
name_indx = info->name_indx;
++info->name_indx;
size = info->type_stack->type.size;
type_indx = ieee_pop_type (info);
/* Write out an NN and an ATN record for this variable. */
if (! ieee_write_byte (info, (int) ieee_nn_record)
|| ! ieee_write_number (info, name_indx)
@ -5902,19 +6025,28 @@ ieee_variable (p, name, kind, val)
if (! ieee_write_number (info, 8)
|| ! ieee_add_range (info, val, val + size))
return false;
refflag = 0;
asn = true;
break;
case DEBUG_STATIC:
if (! ieee_write_number (info, 3)
|| ! ieee_add_range (info, val, val + size))
return false;
refflag = 1;
asn = true;
break;
case DEBUG_LOCAL_STATIC:
if (! ieee_write_number (info, 3)
|| ! ieee_add_range (info, val, val + size))
return false;
refflag = 2;
asn = true;
break;
case DEBUG_LOCAL:
if (! ieee_write_number (info, 1)
|| ! ieee_write_number (info, val))
return false;
refflag = 2;
asn = false;
break;
case DEBUG_REGISTER:
@ -5922,6 +6054,7 @@ ieee_variable (p, name, kind, val)
|| ! ieee_write_number (info,
ieee_genreg_to_regno (info->abfd, val)))
return false;
refflag = 2;
asn = false;
break;
}
@ -5932,6 +6065,41 @@ ieee_variable (p, name, kind, val)
return false;
}
/* If this is really a reference type, then we just output it with
pointer type, and must now output a C++ record indicating that it
is really reference type. */
if (referencep)
{
unsigned int nindx;
nindx = info->name_indx;
++info->name_indx;
/* If this is a global variable, we want to output the misc
record in the C++ misc record block. Otherwise, we want to
output it just after the variable definition, which is where
the current buffer is. */
if (refflag != 2)
{
if (! ieee_change_buffer (info, &info->cxx))
return false;
}
if (! ieee_write_byte (info, (int) ieee_nn_record)
|| ! ieee_write_number (info, nindx)
|| ! ieee_write_id (info, "")
|| ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
|| ! ieee_write_number (info, nindx)
|| ! ieee_write_number (info, 0)
|| ! ieee_write_number (info, 62)
|| ! ieee_write_number (info, 80)
|| ! ieee_write_number (info, 3)
|| ! ieee_write_asn (info, nindx, 'R')
|| ! ieee_write_asn (info, nindx, refflag)
|| ! ieee_write_atn65 (info, nindx, name))
return false;
}
return true;
}
@ -5944,7 +6112,63 @@ ieee_start_function (p, name, global)
boolean global;
{
struct ieee_handle *info = (struct ieee_handle *) p;
unsigned int indx;
boolean referencep;
unsigned int retindx, typeindx;
referencep = info->type_stack->type.referencep;
retindx = ieee_pop_type (info);
/* Besides recording a BB4 or BB6 block, we record the type of the
function in the BB1 typedef block. We can't write out the full
type until we have seen all the parameters, so we accumulate it
in info->fntype and info->fnargs. */
if (info->fntype != NULL)
{
/* FIXME: This might happen someday if we support nested
functions. */
abort ();
}
info->fnname = name;
/* An attribute of 0x41 means that the frame and push mask are
unknown. */
if (! ieee_define_named_type (info, name, false, 0, 0, false, &info->fntype)
|| ! ieee_write_number (info, 'x')
|| ! ieee_write_number (info, 0x41)
|| ! ieee_write_number (info, 0)
|| ! ieee_write_number (info, 0)
|| ! ieee_write_number (info, retindx))
return false;
typeindx = ieee_pop_type (info);
info->fnargs = NULL;
info->fnargcount = 0;
/* If the function return value is actually a reference type, we
must add a record indicating that. */
if (referencep)
{
unsigned int nindx;
nindx = info->name_indx;
++info->name_indx;
if (! ieee_change_buffer (info, &info->cxx)
|| ! ieee_write_byte (info, (int) ieee_nn_record)
|| ! ieee_write_number (info, nindx)
|| ! ieee_write_id (info, "")
|| ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
|| ! ieee_write_number (info, nindx)
|| ! ieee_write_number (info, 0)
|| ! ieee_write_number (info, 62)
|| ! ieee_write_number (info, 80)
|| ! ieee_write_number (info, 3)
|| ! ieee_write_asn (info, nindx, 'R')
|| ! ieee_write_asn (info, nindx, global ? 0 : 1)
|| ! ieee_write_atn65 (info, nindx, name))
return false;
}
/* Make sure the variable section is started. */
if (info->vars != NULL)
@ -5962,8 +6186,6 @@ ieee_start_function (p, name, global)
return false;
}
indx = ieee_pop_type (info);
/* The address is written out as the first block. */
++info->block_depth;
@ -5973,7 +6195,7 @@ ieee_start_function (p, name, global)
&& ieee_write_number (info, 0)
&& ieee_write_id (info, name)
&& ieee_write_number (info, 0)
&& ieee_write_number (info, indx));
&& ieee_write_number (info, typeindx));
}
/* Add a function parameter. This will normally be called before the
@ -5996,6 +6218,7 @@ ieee_function_parameter (p, name, kind, val)
m->next = NULL;
m->name = name;
m->referencep = info->type_stack->type.referencep;
m->type = ieee_pop_type (info);
m->kind = kind;
m->val = val;
@ -6004,6 +6227,12 @@ ieee_function_parameter (p, name, kind, val)
;
*pm = m;
/* Add the type to the fnargs list. */
if (! ieee_change_buffer (info, &info->fnargs)
|| ! ieee_write_number (info, m->type))
return false;
++info->fnargcount;
return true;
}
@ -6014,11 +6243,11 @@ ieee_output_pending_parms (info)
struct ieee_handle *info;
{
struct ieee_pending_parm *m;
unsigned int refcount;
m = info->pending_parms;
while (m != NULL)
refcount = 0;
for (m = info->pending_parms; m != NULL; m = m->next)
{
struct ieee_pending_parm *next;
enum debug_var_kind vkind;
switch (m->kind)
@ -6036,17 +6265,61 @@ ieee_output_pending_parms (info)
break;
}
if (! ieee_push_type (info, m->type, 0, false)
|| ! ieee_variable ((PTR) info, m->name, vkind, m->val))
if (! ieee_push_type (info, m->type, 0, false))
return false;
info->type_stack->type.referencep = m->referencep;
if (m->referencep)
++refcount;
if (! ieee_variable ((PTR) info, m->name, vkind, m->val))
return false;
}
/* FIXME: We should output a pmisc note here for reference
parameters. */
/* If there are any reference parameters, we need to output a
miscellaneous record indicating them. */
if (refcount > 0)
{
unsigned int nindx, varindx;
/* FIXME: The MRI compiler outputs the demangled function name
here, but we are outputting the mangled name. */
nindx = info->name_indx;
++info->name_indx;
if (! ieee_change_buffer (info, &info->vars)
|| ! ieee_write_byte (info, (int) ieee_nn_record)
|| ! ieee_write_number (info, nindx)
|| ! ieee_write_id (info, "")
|| ! ieee_write_2bytes (info, (int) ieee_atn_record_enum)
|| ! ieee_write_number (info, nindx)
|| ! ieee_write_number (info, 0)
|| ! ieee_write_number (info, 62)
|| ! ieee_write_number (info, 80)
|| ! ieee_write_number (info, refcount + 3)
|| ! ieee_write_asn (info, nindx, 'B')
|| ! ieee_write_atn65 (info, nindx, info->fnname)
|| ! ieee_write_asn (info, nindx, 0))
return false;
for (m = info->pending_parms, varindx = 1;
m != NULL;
m = m->next, varindx++)
{
if (m->referencep)
{
if (! ieee_write_asn (info, nindx, varindx))
return false;
}
}
}
m = info->pending_parms;
while (m != NULL)
{
struct ieee_pending_parm *next;
next = m->next;
free (m);
m = next;
}
info->pending_parms = NULL;
return true;
@ -6123,11 +6396,47 @@ ieee_end_function (p)
PTR p;
{
struct ieee_handle *info = (struct ieee_handle *) p;
struct ieee_buf **pb;
assert (info->block_depth == 1);
--info->block_depth;
/* Now we can finish up fntype, and add it to the typdef section.
At this point, fntype is the 'x' type up to the argument count,
and fnargs is the argument types. We must add the argument
count, and we must add the level. FIXME: We don't record varargs
functions correctly. In fact, stabs debugging does not give us
enough information to do so. */
if (! ieee_change_buffer (info, &info->fntype)
|| ! ieee_write_number (info, info->fnargcount)
|| ! ieee_change_buffer (info, &info->fnargs)
|| ! ieee_write_number (info, 0))
return false;
/* Make sure the typdef block has been started. */
if (info->types == NULL)
{
if (! ieee_change_buffer (info, &info->types)
|| ! ieee_write_byte (info, (int) ieee_bb_record_enum)
|| ! ieee_write_byte (info, 1)
|| ! ieee_write_number (info, 0)
|| ! ieee_write_id (info, info->modname))
return false;
}
for (pb = &info->types; *pb != NULL; pb = &(*pb)->next)
;
*pb = info->fntype;
for (; *pb != NULL; pb = &(*pb)->next)
;
*pb = info->fnargs;
info->fnname = NULL;
info->fntype = NULL;
info->fnargs = NULL;
info->fnargcount = 0;
return true;
}