Improve G++ debugging support.

This commit is contained in:
John Gilmore 1991-11-27 09:43:59 +00:00
parent 7d7ecbddb0
commit f1d77e9053
8 changed files with 215 additions and 354 deletions

View File

@ -1,3 +1,36 @@
Wed Nov 27 01:23:41 1991 John Gilmore (gnu at cygnus.com)
Fix bugs in C++ debugging.
* symtab.h: target_type is not used in record types.
Eliminate TYPE_MAIN_VARIANT and TYPE_NEXT_VARIANT. Eliminate
lookup_method_type.
* symtab.c (lookup_member_type): Don't chain them up, just
allocate one in symbol_obstack when we need one.
(allocate_stub_method): Build stub in symbol_obstack.
(check_stub_method): Move here from values.c. Don't deallocate
stub; overwrite it.
(lookup_method_type): Gone now.
* buildsym.c: Handle g++ v1 stabs a little bit better.
Change some C++ parsing error()s to complain()ts.
* buildsym.c, findvar.c, printcmd.c, symtab.c: Make unions and
structs have the same representation and work the same as far as
C++ is concerned.
* buildsym.c, symtab.c, values.c: Remove all references to
TYPE_MAIN_VARIANT and TYPE_NEXT_VARIANT.
* valops.c: Improve comments and indentation. Only call
check_stub_method when the stub flag is on.
* valprint.c: Fix or mark minor bugs and unportabilities.
* coffread.c (anonymous unions): Allocate a cplus structure.
* mipsread.c: Eliminate "template" types. Build new, real
types whenever we need them. Allocate cplus structures as needed.
Bulletproof the type parsing a bit more. Mark storage leaks.
Fri Nov 22 16:39:57 1991 John Gilmore (gnu at cygnus.com)
* inflow.c (terminal_inferior): Check the results of ioctl's, and

View File

@ -93,8 +93,17 @@ You seem to have compiled your program with \
Therefore GDB will not know about your class variables", 0, 0};
#endif
struct complaint invalid_cpp_abbrev_complaint =
{"invalid C++ abbreviation `%s'", 0, 0};
struct complaint invalid_cpp_type_complaint =
{"C++ abbreviated type name unknown at symtab pos %d", 0, 0};
struct complaint member_fn_complaint =
{"member function type missing, got '%c'", 0, 0};
struct complaint const_vol_complaint =
{"const/volatile indicator missing (ok if using g++ v1.x), got '%c'", 0, 0};
{"const/volatile indicator missing, got '%c'", 0, 0};
struct complaint error_type_complaint =
{"debug info mismatch between compiler and debugger", 0, 0};
@ -1635,7 +1644,7 @@ read_type (pp)
type = dbx_alloc_type (typenums);
TYPE_CODE (type) = code;
TYPE_NAME (type) = type_name;
if (code == TYPE_CODE_STRUCT)
if (code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION)
{
TYPE_CPLUS_SPECIFIC (type)
= (struct cplus_struct_type *) obstack_alloc (symbol_obstack, sizeof (struct cplus_struct_type));
@ -1857,9 +1866,6 @@ read_struct_type (pp, type)
register struct next_fnfieldlist *mainlist = 0;
int nfn_fields = 0;
if (TYPE_MAIN_VARIANT (type) == 0)
TYPE_MAIN_VARIANT (type) = type;
TYPE_CODE (type) = TYPE_CODE_STRUCT;
TYPE_CPLUS_SPECIFIC (type)
= (struct cplus_struct_type *) obstack_alloc (symbol_obstack, sizeof (struct cplus_struct_type));
@ -1996,20 +2002,22 @@ read_struct_type (pp, type)
prefix = vb_name;
break;
default:
error ("invalid abbreviation at symtab pos %d.", symnum);
complain (&invalid_cpp_abbrev_complaint, *pp);
prefix = "INVALID_C++_ABBREV";
break;
}
*pp = p + 1;
context = read_type (pp);
name = type_name_no_tag (context);
if (name == 0)
{
error ("type name unknown at symtab pos %d.", symnum);
complain (&invalid_cpp_type_complaint, symnum);
TYPE_NAME (context) = name;
}
list->field.name = obconcat (prefix, name, "");
p = ++(*pp);
if (p[-1] != ':')
error ("invalid abbreviation at symtab pos %d.", symnum);
complain (&invalid_cpp_abbrev_complaint, *pp);
list->field.type = read_type (pp);
(*pp)++; /* Skip the comma. */
list->field.bitpos = read_number (pp, ';');
@ -2020,7 +2028,7 @@ read_struct_type (pp, type)
else if (*p == '_')
break;
else
error ("invalid abbreviation at symtab pos %d.", symnum);
complain (&invalid_cpp_abbrev_complaint, *pp);
nfields++;
continue;
@ -2192,14 +2200,17 @@ read_struct_type (pp, type)
/* read in the name. */
while (*p != ':') p++;
#if 0
if ((*pp)[0] == 'o' && (*pp)[1] == 'p' && (*pp)[2] == CPLUS_MARKER)
{
/* This is a completely wierd case. In order to stuff in the
names that might contain colons (the usual name delimiter),
Mike Tiemann defined a different name format which is
signalled if the identifier is "op$". In that case, the
format is "op$::XXXX." where XXXX is the name. This is
used for names like "+" or "=". YUUUUUUUK! FIXME! */
/* This lets the user type "break operator+".
We could just put in "+" as the name, but that wouldn't
work for "*". */
/* I don't understand what this is trying to do.
It seems completely bogus. -Per Bothner. */
static char opname[32] = {'o', 'p', CPLUS_MARKER};
char *o = opname + 3;
@ -2214,7 +2225,6 @@ read_struct_type (pp, type)
*pp = p + 1;
}
else
#endif
main_fn_name = savestring (*pp, p - *pp);
/* Skip past '::'. */
*pp = p + 2;
@ -2272,10 +2282,13 @@ read_struct_type (pp, type)
new_sublist->fn_field.is_volatile = 1;
(*pp)++;
break;
case '*': /* File compiled with g++ version 1 -- no info */
case '?':
case '.':
break;
default:
/* This probably just means we're processing a file compiled
with g++ version 1. */
complain(&const_vol_complaint, **pp);
break;
}
switch (*(*pp)++)
@ -2320,8 +2333,13 @@ read_struct_type (pp, type)
/* static member function. */
new_sublist->fn_field.voffset = VOFFSET_STATIC;
break;
default:
/* **pp == '.'. */
/* error */
complain (&member_fn_complaint, (*pp)[-1]);
/* Fall through into normal member function. */
case '.':
/* normal member function. */
new_sublist->fn_field.voffset = 0;
new_sublist->fn_field.fcontext = 0;

View File

@ -1816,6 +1816,10 @@ decode_base_type (cs, c_type, aux)
/* anonymous union type */
type = coff_alloc_type (cs->c_symnum);
TYPE_NAME (type) = concat ("union ", "<opaque>", NULL);
TYPE_CPLUS_SPECIFIC (type) = (struct cplus_struct_type *)
obstack_alloc (symbol_obstack, sizeof (struct cplus_struct_type));
bzero (TYPE_CPLUS_SPECIFIC (type), sizeof (struct cplus_struct_type));
TYPE_LENGTH (type) = 0;
TYPE_LENGTH (type) = 0;
TYPE_FIELDS (type) = 0;
TYPE_NFIELDS (type) = 0;

View File

@ -1,6 +1,6 @@
/* Read a symbol table in MIPS' format (Third-Eye).
Copyright (C) 1986, 1987, 1989-1991 Free Software Foundation, Inc.
Contributed by Alessandro Forin (af@cs.cmu.edu) at CMU
Copyright 1986, 1987, 1989, 1990, 1991 Free Software Foundation, Inc.
Contributed by Alessandro Forin (af@cs.cmu.edu) at CMU.
This file is part of GDB.
@ -161,15 +161,6 @@ struct type *builtin_type_fixed_dec;
struct type *builtin_type_float_dec;
struct type *builtin_type_string;
/* Template types */
static struct type *builtin_type_ptr;
static struct type *builtin_type_struct;
static struct type *builtin_type_union;
static struct type *builtin_type_enum;
static struct type *builtin_type_range;
static struct type *builtin_type_set;
/* Forward declarations */
static struct symbol *new_symbol();
@ -243,9 +234,6 @@ mipscoff_symfile_read(sf, addr, mainline)
int symtab_offset;
int stringtab_offset;
/* Initialize a variable that we couldn't do at _initialize_ time. */
builtin_type_ptr = lookup_pointer_type (builtin_type_void);
/* WARNING WILL ROBINSON! ACCESSING BFD-PRIVATE DATA HERE! FIXME! */
desc = fileno ((FILE *)(abfd->iostream)); /* Raw file descriptor */
/* End of warning */
@ -1066,7 +1054,7 @@ static struct type *parse_type(ax, sh, bs)
TIR *t;
struct type *tp = 0, *tp1;
char *fmt = "%s";
char *fmt;
/* Procedures start off by one */
if (sh->st == stProc || sh->st == stStaticProc)
@ -1079,38 +1067,43 @@ static struct type *parse_type(ax, sh, bs)
/* Use aux as a type information record, map its basic type */
t = &ax->ti;
if (t->bt > 26 || t->bt == btPicture) {
if (t->bt > (sizeof (map_bt)/sizeof (*map_bt))) {
complain (&basic_type_complaint, t->bt);
return builtin_type_int;
}
if (map_bt[t->bt])
tp = *map_bt[t->bt];
fmt = "%s";
else {
/* Cannot use builtin types, use templates */
tp = make_type(TYPE_CODE_VOID, 0, 0, 0);
/* Cannot use builtin types -- build our own */
switch (t->bt) {
case btAdr:
*tp = *builtin_type_ptr;
tp = lookup_pointer_type (builtin_type_void);
fmt = "%s";
break;
case btStruct:
*tp = *builtin_type_struct;
tp = make_struct_type(TYPE_CODE_STRUCT, 0, 0, 0);
fmt = "struct %s";
break;
case btUnion:
*tp = *builtin_type_union;
tp = make_struct_type(TYPE_CODE_UNION, 0, 0, 0);
fmt = "union %s";
break;
case btEnum:
*tp = *builtin_type_enum;
tp = make_type(TYPE_CODE_ENUM, 0, 0, 0);
fmt = "enum %s";
break;
case btRange:
*tp = *builtin_type_range;
tp = make_type(TYPE_CODE_RANGE, 0, 0, 0);
fmt = "%s";
break;
case btSet:
*tp = *builtin_type_set;
tp = make_type(TYPE_CODE_SET, 0, 0, 0);
fmt = "set %s";
break;
default:
complain (&basic_type_complaint, t->bt);
return builtin_type_int;
}
}
@ -2548,6 +2541,7 @@ make_type(code, length, uns, name)
{
register struct type *type;
/* FIXME, I don't think this ever gets freed. */
type = (struct type *) xzalloc(sizeof(struct type));
TYPE_CODE(type) = code;
TYPE_LENGTH(type) = length;
@ -2558,6 +2552,25 @@ make_type(code, length, uns, name)
return type;
}
/* Create and initialize a new struct or union type, a la make_type. */
static
struct type *
make_struct_type(code, length, uns, name)
enum type_code code;
int length, uns;
char *name;
{
register struct type *type;
type = make_type (code, length, uns, name);
/* FIXME, I don't think this ever gets freed. */
TYPE_CPLUS_SPECIFIC (type) = (struct cplus_struct_type *)
xzalloc (sizeof (struct cplus_struct_type));
return type;
}
/* Allocate a new field named NAME to the type TYPE */
static
@ -2795,15 +2808,4 @@ _initialize_mipsread ()
0, "fixed_decimal");
builtin_type_float_dec = make_type(TYPE_CODE_FLT, sizeof(double),
0, "floating_decimal");
/* Templates types */
builtin_type_struct = make_type(TYPE_CODE_STRUCT, 0, 0, 0);
builtin_type_union = make_type(TYPE_CODE_UNION, 0, 0, 0);
builtin_type_enum = make_type(TYPE_CODE_ENUM, 0, 0, 0);
builtin_type_range = make_type(TYPE_CODE_RANGE, 0, 0, 0);
builtin_type_set = make_type(TYPE_CODE_SET, 0, 0, 0);
/* We can't do this now because builtin_type_void may not
be set yet. Do it at symbol reading time. */
/* builtin_type_ptr = lookup_pointer_type (builtin_type_void); */
}

View File

@ -318,7 +318,8 @@ vx_call_function (function, nargs, args)
to the structure, not the structure itself. */
if (REG_STRUCT_HAS_ADDR (using_gcc))
for (i = nargs - 1; i >= 0; i--)
if (TYPE_CODE (VALUE_TYPE (args[i])) == TYPE_CODE_STRUCT)
if ( TYPE_CODE (VALUE_TYPE (args[i])) == TYPE_CODE_STRUCT
|| TYPE_CODE (VALUE_TYPE (args[i])) == TYPE_CODE_UNION)
{
CORE_ADDR addr;
#if !(1 INNER_THAN 2)

View File

@ -393,7 +393,7 @@ lookup_template_type (name, type, block)
strcpy(nam, name);
strcat(nam, "<");
strcat(nam, type->name);
strcat(nam, " >"); /* extra space still introduced in gcc? */
strcat(nam, " >"); /* FIXME, extra space still introduced in gcc? */
sym = lookup_symbol (nam, block, VAR_NAMESPACE, 0, (struct symtab **)NULL);
@ -416,7 +416,7 @@ lookup_struct_elt_type (type, name, noerr)
{
int i;
if (TYPE_CODE (type) != TYPE_CODE_STRUCT
if ( TYPE_CODE (type) != TYPE_CODE_STRUCT
&& TYPE_CODE (type) != TYPE_CODE_UNION)
{
target_terminal_ours ();
@ -524,212 +524,118 @@ struct type *
lookup_member_type (type, domain)
struct type *type, *domain;
{
register struct type *mtype = TYPE_MAIN_VARIANT (type);
struct type *main_type;
main_type = mtype;
while (mtype)
{
if (TYPE_DOMAIN_TYPE (mtype) == domain)
return mtype;
mtype = TYPE_NEXT_VARIANT (mtype);
}
/* This is the first time anyone wanted this member type. */
if (TYPE_FLAGS (type) & TYPE_FLAG_PERM)
mtype = (struct type *) xmalloc (sizeof (struct type));
else
mtype = (struct type *) obstack_alloc (symbol_obstack,
sizeof (struct type));
bzero (mtype, sizeof (struct type));
if (main_type == 0)
main_type = mtype;
else
{
TYPE_NEXT_VARIANT (mtype) = TYPE_NEXT_VARIANT (main_type);
TYPE_NEXT_VARIANT (main_type) = mtype;
}
TYPE_MAIN_VARIANT (mtype) = main_type;
TYPE_TARGET_TYPE (mtype) = type;
TYPE_DOMAIN_TYPE (mtype) = domain;
/* New type is permanent if type pointed to is permanent. */
if (TYPE_FLAGS (type) & TYPE_FLAG_PERM)
TYPE_FLAGS (mtype) |= TYPE_FLAG_PERM;
/* In practice, this is never used. */
TYPE_LENGTH (mtype) = 1;
TYPE_CODE (mtype) = TYPE_CODE_MEMBER;
#if 0
/* Now splice in the new member pointer type. */
if (main_type)
{
/* This type was not "smashed". */
TYPE_CHAIN (mtype) = TYPE_CHAIN (main_type);
TYPE_CHAIN (main_type) = mtype;
}
#endif
register struct type *mtype;
mtype = (struct type *) obstack_alloc (symbol_obstack,
sizeof (struct type));
smash_to_member_type (mtype, domain, type);
return mtype;
}
/* Allocate a stub method whose return type is
TYPE. We will fill in arguments later. This always
returns a fresh type. If we unify this type with
an existing type later, the storage allocated
here can be freed. */
/* Allocate a stub method whose return type is TYPE.
This apparently happens for speed of symbol reading, since parsing
out the arguments to the method is cpu-intensive, the way we are doing
it. So, we will fill in arguments later.
This always returns a fresh type. */
struct type *
allocate_stub_method (type)
struct type *type;
{
struct type *mtype = (struct type *)xmalloc (sizeof (struct type));
struct type *mtype = (struct type *) obstack_alloc (symbol_obstack,
sizeof (struct type));
bzero (mtype, sizeof (struct type));
TYPE_MAIN_VARIANT (mtype) = mtype;
TYPE_TARGET_TYPE (mtype) = type;
/* _DOMAIN_TYPE (mtype) = unknown yet */
/* _ARG_TYPES (mtype) = unknown yet */
TYPE_FLAGS (mtype) = TYPE_FLAG_STUB;
TYPE_CODE (mtype) = TYPE_CODE_METHOD;
TYPE_LENGTH (mtype) = 1;
return mtype;
}
/* Lookup a method type belonging to class DOMAIN, returning type TYPE,
and taking a list of arguments ARGS.
If one is not found, allocate a new one. */
/* Ugly hack to convert method stubs into method types.
struct type *
lookup_method_type (domain, type, args)
struct type *domain, *type, **args;
{
register struct type *mtype = TYPE_MAIN_VARIANT (type);
struct type *main_type;
main_type = mtype;
while (mtype)
{
if (TYPE_DOMAIN_TYPE (mtype) == domain)
{
struct type **t1 = args;
struct type **t2 = TYPE_ARG_TYPES (mtype);
if (t2)
{
int i;
for (i = 0; t1[i] != 0 && t1[i]->code != TYPE_CODE_VOID; i++)
if (t1[i] != t2[i])
break;
if (t1[i] == t2[i])
return mtype;
}
}
mtype = TYPE_NEXT_VARIANT (mtype);
}
/* This is the first time anyone wanted this member type. */
if (TYPE_FLAGS (type) & TYPE_FLAG_PERM)
mtype = (struct type *) xmalloc (sizeof (struct type));
else
mtype = (struct type *) obstack_alloc (symbol_obstack,
sizeof (struct type));
bzero (mtype, sizeof (struct type));
if (main_type == 0)
main_type = mtype;
else
{
TYPE_NEXT_VARIANT (mtype) = TYPE_NEXT_VARIANT (main_type);
TYPE_NEXT_VARIANT (main_type) = mtype;
}
TYPE_MAIN_VARIANT (mtype) = main_type;
TYPE_TARGET_TYPE (mtype) = type;
TYPE_DOMAIN_TYPE (mtype) = domain;
TYPE_ARG_TYPES (mtype) = args;
/* New type is permanent if type pointed to is permanent. */
if (TYPE_FLAGS (type) & TYPE_FLAG_PERM)
TYPE_FLAGS (mtype) |= TYPE_FLAG_PERM;
/* In practice, this is never used. */
TYPE_LENGTH (mtype) = 1;
TYPE_CODE (mtype) = TYPE_CODE_METHOD;
#if 0
/* Now splice in the new member pointer type. */
if (main_type)
{
/* This type was not "smashed". */
TYPE_CHAIN (mtype) = TYPE_CHAIN (main_type);
TYPE_CHAIN (main_type) = mtype;
}
#endif
return mtype;
}
#if 0
/* Given a type TYPE, return a type which has offset OFFSET,
via_virtual VIA_VIRTUAL, and via_public VIA_PUBLIC.
May need to construct such a type if none exists. */
struct type *
lookup_basetype_type (type, offset, via_virtual, via_public)
He ain't kiddin'. This demangles the name of the method into a string
including argument types, parses out each argument type, generates
a string casting a zero to that type, evaluates the string, and stuffs
the resulting type into an argtype vector!!! Then it knows the type
of the whole function (including argument types for overloading),
which info used to be in the stab's but was removed to hack back
the space required for them. */
void
check_stub_method (type, i, j)
struct type *type;
int offset;
int via_virtual, via_public;
int i, j;
{
register struct type *btype = TYPE_MAIN_VARIANT (type);
struct type *main_type;
extern char *gdb_mangle_name (), *strchr ();
struct fn_field *f;
char *mangled_name = gdb_mangle_name (type, i, j);
char *demangled_name = cplus_demangle (mangled_name, 0);
char *argtypetext, *p;
int depth = 0, argcount = 1;
struct type **argtypes;
struct type *mtype;
if (offset != 0)
/* Now, read in the parameters that define this type. */
argtypetext = strchr (demangled_name, '(') + 1;
p = argtypetext;
while (*p)
{
printf ("Internal error: type offset non-zero in lookup_basetype_type");
offset = 0;
if (*p == '(')
depth += 1;
else if (*p == ')')
depth -= 1;
else if (*p == ',' && depth == 0)
argcount += 1;
p += 1;
}
/* We need one more slot for the void [...] or NULL [end of arglist] */
argtypes = (struct type **) obstack_alloc (symbol_obstack,
(argcount+1) * sizeof (struct type *));
p = argtypetext;
argtypes[0] = lookup_pointer_type (type);
argcount = 1;
if (*p != ')') /* () means no args, skip while */
{
depth = 0;
while (*p)
{
if (depth <= 0 && (*p == ',' || *p == ')'))
{
argtypes[argcount] =
parse_and_eval_type (argtypetext, p - argtypetext);
argcount += 1;
argtypetext = p + 1;
}
if (*p == '(')
depth += 1;
else if (*p == ')')
depth -= 1;
p += 1;
}
}
main_type = btype;
while (btype)
{
if (/* TYPE_OFFSET (btype) == offset
&& */ TYPE_VIA_PUBLIC (btype) == via_public
&& TYPE_VIA_VIRTUAL (btype) == via_virtual)
return btype;
btype = TYPE_NEXT_VARIANT (btype);
}
/* This is the first time anyone wanted this member type. */
if (TYPE_FLAGS (type) & TYPE_FLAG_PERM)
btype = (struct type *) xmalloc (sizeof (struct type));
if (p[-2] != '.') /* ... */
argtypes[argcount] = builtin_type_void; /* Ellist terminator */
else
btype = (struct type *) obstack_alloc (symbol_obstack,
sizeof (struct type));
argtypes[argcount] = NULL; /* List terminator */
if (main_type == 0)
{
main_type = btype;
bzero (btype, sizeof (struct type));
TYPE_MAIN_VARIANT (btype) = main_type;
}
else
{
bcopy (main_type, btype, sizeof (struct type));
TYPE_NEXT_VARIANT (main_type) = btype;
}
/* TYPE_OFFSET (btype) = offset; */
if (via_public)
TYPE_FLAGS (btype) |= TYPE_FLAG_VIA_PUBLIC;
if (via_virtual)
TYPE_FLAGS (btype) |= TYPE_FLAG_VIA_VIRTUAL;
/* New type is permanent if type pointed to is permanent. */
if (TYPE_FLAGS (type) & TYPE_FLAG_PERM)
TYPE_FLAGS (btype) |= TYPE_FLAG_PERM;
free (demangled_name);
/* In practice, this is never used. */
TYPE_LENGTH (btype) = 1;
TYPE_CODE (btype) = TYPE_CODE_STRUCT;
TYPE_CPLUS_SPECIFIC (btype)
= (struct cplus_struct_type *) obstack_alloc (symbol_obstack, sizeof (struct cplus_struct_type)));
bzero (TYPE_CPLUS_SPECIFIC (btype), sizeof (struct cplus_struct_type));
f = TYPE_FN_FIELDLIST1 (type, i);
TYPE_FN_FIELD_PHYSNAME (f, j) = mangled_name;
return btype;
/* Now update the old "stub" type into a real type. */
mtype = TYPE_FN_FIELD_TYPE (f, j);
TYPE_DOMAIN_TYPE (mtype) = type;
TYPE_ARG_TYPES (mtype) = argtypes;
TYPE_FLAGS (mtype) &= ~TYPE_FLAG_STUB;
}
#endif
/* Given a type TYPE, return a type of functions that return that type.
May need to construct such a type if this is the first use. */
@ -813,7 +719,11 @@ create_array_type (element_type, number)
}
/* Smash TYPE to be a type of members of DOMAIN with type TO_TYPE. */
/* Smash TYPE to be a type of members of DOMAIN with type TO_TYPE.
A MEMBER is a wierd thing -- it amounts to a typed offset into
a struct, e.g. "an int at offset 8". A MEMBER TYPE doesn't
include the offset (that's the value of the MEMBER itself), but does
include the structure type into which it points (for some reason). */
void
smash_to_member_type (type, domain, to_type)
@ -822,15 +732,12 @@ smash_to_member_type (type, domain, to_type)
bzero (type, sizeof (struct type));
TYPE_TARGET_TYPE (type) = to_type;
TYPE_DOMAIN_TYPE (type) = domain;
/* In practice, this is never needed. */
TYPE_LENGTH (type) = 1;
TYPE_LENGTH (type) = 1; /* In practice, this is never needed. */
TYPE_CODE (type) = TYPE_CODE_MEMBER;
TYPE_MAIN_VARIANT (type) = lookup_member_type (domain, to_type);
}
/* Smash TYPE to be a type of method of DOMAIN with type TO_TYPE. */
/* Smash TYPE to be a type of method of DOMAIN with type TO_TYPE.
METHOD just means `function that gets an extra "this" argument'. */
void
smash_to_method_type (type, domain, to_type, args)
@ -840,12 +747,8 @@ smash_to_method_type (type, domain, to_type, args)
TYPE_TARGET_TYPE (type) = to_type;
TYPE_DOMAIN_TYPE (type) = domain;
TYPE_ARG_TYPES (type) = args;
/* In practice, this is never needed. */
TYPE_LENGTH (type) = 1;
TYPE_LENGTH (type) = 1; /* In practice, this is never needed. */
TYPE_CODE (type) = TYPE_CODE_METHOD;
TYPE_MAIN_VARIANT (type) = lookup_method_type (domain, to_type, args);
}
/* Find which partial symtab on the partial_symtab_list contains
@ -1988,7 +1891,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
(struct symtab **)NULL);
if (sym_class &&
(TYPE_CODE (SYMBOL_TYPE (sym_class)) == TYPE_CODE_STRUCT
( TYPE_CODE (SYMBOL_TYPE (sym_class)) == TYPE_CODE_STRUCT
|| TYPE_CODE (SYMBOL_TYPE (sym_class)) == TYPE_CODE_UNION))
{
/* Arg token is not digits => try it as a function name
@ -2772,11 +2675,10 @@ init_type (code, length, uns, name)
TYPE_NAME (type) = name;
/* C++ fancies. */
if (code == TYPE_CODE_STRUCT)
if (code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION)
{
TYPE_CPLUS_SPECIFIC (type)
= (struct cplus_struct_type *) xmalloc (sizeof (struct cplus_struct_type));
TYPE_MAIN_VARIANT (type) = type;
TYPE_NFN_FIELDS (type) = 0;
TYPE_N_BASECLASSES (type) = 0;
}

View File

@ -131,10 +131,9 @@ struct type
For an array type, describes the type of the elements.
For a function or method type, describes the type of the value.
For a range type, describes the type of the full range.
For a record type, it's the "main variant" of the record type,
used for computing pointers to members.
Unused otherwise. */
struct type *target_type;
/* Type that is a pointer to this type.
Zero if no such pointer-to type is known yet.
The debugger may add the address of such a type
@ -142,7 +141,6 @@ struct type
struct type *pointer_type;
/* C++: also need a reference type. */
struct type *reference_type;
/* Type that is a function returning this type.
Zero if no such function type is known here.
The debugger may add the address of such a type
@ -189,7 +187,7 @@ struct type
the field number of that pointer in the structure.
For types that are pointer to member types, VPTR_BASETYPE
ifs the type that this pointer is a member of.
is the type that this pointer is a member of.
Unused otherwise. */
struct type *vptr_basetype;
@ -204,23 +202,10 @@ struct type
} type_specific;
};
/* C++ language-specific information for TYPE_CODE_STRUCT nodes. */
/* C++ language-specific information for TYPE_CODE_STRUCT and TYPE_CODE_UNION
nodes. */
struct cplus_struct_type
{
/* Handling of pointers to members:
TYPE_MAIN_VARIANT is used for pointer and pointer
to member types. Normally it is the value of the address of its
containing type. However, for pointers to members, we must be
able to allocate pointer to member types and look them up
from some place of reference.
NEXT_VARIANT is the next element in the chain.
A long time ago (Jul 88; GDB 2.5) Tiemann said that
MAIN_VARIANT/NEXT_VARIANT may no longer be necessary and that he
might eliminate it. I don't know whether this is still true (or
ever was). */
struct type *next_variant;
B_TYPE *virtual_field_bits; /* if base class is virtual */
B_TYPE *private_field_bits;
B_TYPE *protected_field_bits;
@ -676,8 +661,6 @@ int current_source_line;
#define TYPE_POINTER_TYPE(thistype) (thistype)->pointer_type
#define TYPE_REFERENCE_TYPE(thistype) (thistype)->reference_type
#define TYPE_FUNCTION_TYPE(thistype) (thistype)->function_type
#define TYPE_MAIN_VARIANT(thistype) (thistype)->target_type
#define TYPE_NEXT_VARIANT(thistype) (TYPE_CPLUS_SPECIFIC (thistype))->next_variant
#define TYPE_LENGTH(thistype) (thistype)->length
#define TYPE_FLAGS(thistype) (thistype)->flags
#define TYPE_UNSIGNED(thistype) ((thistype)->flags & TYPE_FLAG_UNSIGNED)
@ -812,7 +795,6 @@ extern int contained_in();
extern struct type *lookup_template_type ();
extern struct type *lookup_reference_type ();
extern struct type *lookup_member_type ();
extern struct type *lookup_method_type ();
extern void smash_to_method_type ();
void smash_to_member_type (
#ifdef __STDC__

View File

@ -1147,7 +1147,7 @@ value_static_field (type, fieldname, fieldno)
}
/* Compute the address of the baseclass which is
the INDEXth baseclass of TYPE. The TYPE base
the INDEXth baseclass of class TYPE. The TYPE base
of the object is at VALADDR.
If ERRP is non-NULL, set *ERRP to be the errno code of any error,
@ -1175,9 +1175,6 @@ baseclass_addr (type, index, valaddr, valuep, errp)
register int n_baseclasses = TYPE_N_BASECLASSES (type);
char *vbase_name, *type_name = type_name_no_tag (basetype);
if (TYPE_MAIN_VARIANT (basetype))
basetype = TYPE_MAIN_VARIANT (basetype);
vbase_name = (char *)alloca (strlen (type_name) + 8);
sprintf (vbase_name, "_vb$%s", type_name);
/* First look for the virtual baseclass pointer
@ -1238,84 +1235,6 @@ baseclass_addr (type, index, valaddr, valuep, errp)
*valuep = 0;
return valaddr + TYPE_BASECLASS_BITPOS (type, index) / 8;
}
/* Ugly hack to convert method stubs into method types.
He ain't kiddin'. This demangles the name of the method into a string
including argument types, parses out each argument type, generates
a string casting a zero to that type, evaluates the string, and stuffs
the resulting type into an argtype vector!!! Then it knows the type
of the whole function (including argument types for overloading),
which info used to be in the stab's but was removed to hack back
the space required for them. */
void
check_stub_method (type, i, j)
struct type *type;
int i, j;
{
extern char *gdb_mangle_name (), *strchr ();
struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);
char *mangled_name = gdb_mangle_name (type, i, j);
char *demangled_name = cplus_demangle (mangled_name, 0);
char *argtypetext, *p;
int depth = 0, argcount = 1;
struct type **argtypes;
/* Now, read in the parameters that define this type. */
argtypetext = strchr (demangled_name, '(') + 1;
p = argtypetext;
while (*p)
{
if (*p == '(')
depth += 1;
else if (*p == ')')
depth -= 1;
else if (*p == ',' && depth == 0)
argcount += 1;
p += 1;
}
/* We need one more slot for the void [...] or NULL [end of arglist] */
argtypes = (struct type **)xmalloc ((argcount+1) * sizeof (struct type *));
p = argtypetext;
argtypes[0] = lookup_pointer_type (type);
argcount = 1;
if (*p != ')') /* () means no args, skip while */
{
depth = 0;
while (*p)
{
if (depth <= 0 && (*p == ',' || *p == ')'))
{
argtypes[argcount] =
parse_and_eval_type (argtypetext, p - argtypetext);
argcount += 1;
argtypetext = p + 1;
}
if (*p == '(')
depth += 1;
else if (*p == ')')
depth -= 1;
p += 1;
}
}
if (p[-2] != '.') /* ... */
argtypes[argcount] = builtin_type_void; /* Ellist terminator */
else
argtypes[argcount] = NULL; /* List terminator */
free (demangled_name);
type = lookup_method_type (type, TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)), argtypes);
/* Free the stub type...it's no longer needed. */
free (TYPE_FN_FIELD_TYPE (f, j));
TYPE_FN_FIELD_PHYSNAME (f, j) = mangled_name;
TYPE_FN_FIELD_TYPE (f, j) = type;
}
long
unpack_field_as_long (type, valaddr, fieldno)
@ -1548,9 +1467,9 @@ set_return_value (val)
if (code == TYPE_CODE_ERROR)
error ("Function return type unknown.");
if (code == TYPE_CODE_STRUCT
|| code == TYPE_CODE_UNION)
error ("Specifying a struct or union return value is not supported.");
if ( code == TYPE_CODE_STRUCT
|| code == TYPE_CODE_UNION) /* FIXME, implement struct return. */
error ("GDB does not support specifying a struct or union return value.");
/* FIXME, this is bogus. We don't know what the return conventions
are, or how values should be promoted.... */