aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorJohn Gilmore <gnu@cygnus>1991-11-27 09:43:59 +0000
committerJohn Gilmore <gnu@cygnus>1991-11-27 09:43:59 +0000
commitf1d77e90532e9ac4a4362a4e55d7b975cb0be991 (patch)
tree2246c2f3fb742f008789481a8aa17ec0b69a3b27 /gdb
parent7d7ecbddb0308f987cd71ded534823539e719879 (diff)
downloadgdb-f1d77e90532e9ac4a4362a4e55d7b975cb0be991.zip
gdb-f1d77e90532e9ac4a4362a4e55d7b975cb0be991.tar.gz
gdb-f1d77e90532e9ac4a4362a4e55d7b975cb0be991.tar.bz2
Improve G++ debugging support.
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog33
-rw-r--r--gdb/buildsym.c50
-rw-r--r--gdb/coffread.c4
-rw-r--r--gdb/mipsread.c72
-rw-r--r--gdb/remote-vx.68.c3
-rw-r--r--gdb/symtab.c288
-rw-r--r--gdb/symtab.h26
-rw-r--r--gdb/values.c89
8 files changed, 213 insertions, 352 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 126f90f..43a2678 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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
diff --git a/gdb/buildsym.c b/gdb/buildsym.c
index 83e2608..5021bfe 100644
--- a/gdb/buildsym.c
+++ b/gdb/buildsym.c
@@ -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;
diff --git a/gdb/coffread.c b/gdb/coffread.c
index 6a9b82f..f3447a5 100644
--- a/gdb/coffread.c
+++ b/gdb/coffread.c
@@ -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;
diff --git a/gdb/mipsread.c b/gdb/mipsread.c
index 07e1a7c..1002dee 100644
--- a/gdb/mipsread.c
+++ b/gdb/mipsread.c
@@ -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); */
}
diff --git a/gdb/remote-vx.68.c b/gdb/remote-vx.68.c
index 4848ca2..3a46d21 100644
--- a/gdb/remote-vx.68.c
+++ b/gdb/remote-vx.68.c
@@ -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)
diff --git a/gdb/symtab.c b/gdb/symtab.c
index 488bc7e..3c5eea3 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -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;
+ 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;
{
- register struct type *mtype = TYPE_MAIN_VARIANT (type);
- struct type *main_type;
-
- main_type = mtype;
- while (mtype)
- {
- if (TYPE_DOMAIN_TYPE (mtype) == domain)
+ 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;
+
+ /* 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 **) 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)
{
- struct type **t1 = args;
- struct type **t2 = TYPE_ARG_TYPES (mtype);
- if (t2)
+ if (depth <= 0 && (*p == ',' || *p == ')'))
{
- 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;
+ argtypes[argcount] =
+ parse_and_eval_type (argtypetext, p - argtypetext);
+ argcount += 1;
+ argtypetext = p + 1;
}
- }
- 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));
+ if (*p == '(')
+ depth += 1;
+ else if (*p == ')')
+ depth -= 1;
- 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)
- struct type *type;
- int offset;
- int via_virtual, via_public;
-{
- register struct type *btype = TYPE_MAIN_VARIANT (type);
- struct type *main_type;
-
- if (offset != 0)
- {
- printf ("Internal error: type offset non-zero in lookup_basetype_type");
- offset = 0;
- }
-
- 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);
+ p += 1;
+ }
}
- /* 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;
}
diff --git a/gdb/symtab.h b/gdb/symtab.h
index 8675a76..801bc5f 100644
--- a/gdb/symtab.h
+++ b/gdb/symtab.h
@@ -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__
diff --git a/gdb/values.c b/gdb/values.c
index f141bc8..afc5f3c 100644
--- a/gdb/values.c
+++ b/gdb/values.c
@@ -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.... */