From f1d77e90532e9ac4a4362a4e55d7b975cb0be991 Mon Sep 17 00:00:00 2001 From: John Gilmore Date: Wed, 27 Nov 1991 09:43:59 +0000 Subject: [PATCH] Improve G++ debugging support. --- gdb/ChangeLog | 33 ++++++ gdb/buildsym.c | 50 +++++--- gdb/coffread.c | 4 + gdb/mipsread.c | 72 ++++++------ gdb/remote-vx.68.c | 3 +- gdb/symtab.c | 288 +++++++++++++++------------------------------ gdb/symtab.h | 26 +--- gdb/values.c | 89 +------------- 8 files changed, 213 insertions(+), 352 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 126f90f481a..43a2678e627 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 83e2608e8eb..5021bfeffc0 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 6a9b82fbc5c..f3447a5513a 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 ", "", 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 07e1a7c74d4..1002dee5873 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 4848ca2d6d0..3a46d213561 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 488bc7ece9a..3c5eea35691 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 8675a760117..801bc5f12fb 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 f141bc8cb02..afc5f3cccbf 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.... */ -- 2.30.2