Article View: gnu.gdb.bug
Article #9964Gdb patches for g++ users
From: bothner
Date: Mon, 13 Aug 1990 18:58
Date: Mon, 13 Aug 1990 18:58
1465 lines
41791 bytes
41791 bytes
Here are the promised gdb patches which fix a number of g++-related
problems. The patches are relative to Tiemann's recently-announced
version 3.6- from labrea.
The major changes provide better support for multiple inheritance
(though I haven't fixed all the problems). There are a number of other
changes. E.g., before, practically *all* output would be demangled
(including source code!). Now it only demangles what I think is reasonable.
I also changed gdb's output in various places to what I think is
more reasonable. (E.g. printing a struct should not print static
members. Less verboseness in general.)
The changes work best with my just-proposed change to g++
(global function names in debugger stabs should not be mangled,
only the assembler-level name), but even without that change,
I don't think these patches should harm anything.
--Per Bothner
bothner@cs.wisc.edu Computer Sciences Dept, U. of Wisconsin-Madison
breakpoint.c:
In breakpoint_1, use new print_address_symbolic instead
of find_pc_partial_function. (This forces use of assembler-level
addresses, and avoids misleading non-mamgled source-level names.)
cplus-dem.c:
Generalize ansi argument such that -1 means skip arglist totally.
Removed global variable print_ansi_qualifiers (which made
code non-reentrant), in favor of extra explicit arguments
to internal routines.
printcmd.c:
Add new helper function print_address_symbolic.
Use find_pc_misc_function instead of find_pc_partial_function
(since we want assembler-level symbols here).
stack.c:
Print unknown function as just "f (...)", not "f (...) (...)".
Use new fputs_demangled explicitly.
symtab.c:
Fixed a typing violation (problem: value.h cannot be imported
without renaming many variable in this file).
lookup_symbol: If no matching misc_func, look for a C++-mangled name.
decode_line_1: Moved forward some never-reached code.
Made decode_line_2 skip function prologues correctly.
utils.c:
fputs_filtered should not demangle by default.
Add new fputs_demangled to demangle on demand..
valops.c:
Change value_struct_elt to use value_primitive_field (using recursive
utility function search_struct_field). This allows foo.bar to work
for multiple inheritance (so far only for data fields).
Change check_field in the same way (recursive helper function
to support multiple inheritance).
(Note: there are more of these problems that I haven't fixed.
Any code that says TYPE_BASECLASS (t, 1) is probably wrong.)
value_of_this: 'this' symbol name is now just "this", note "$this".
valprint.c:
Don't print static members.
Avoid printing "members of <type>" if there are none.
Simplified type_print_derivation_info by merging duplicate code.
Remove useless blank lines in type_print_base (ptype command).
value.h:
Added declaration of new routine value_primitive_field.
values.c:
Added value_primitive_field which is generalized version of
value_field that can handle multiple inheritance (non-zero offsets etc).
Re-implemented value_field to call value_primitive_field.
diff -c old/breakpoint.c new/breakpoint.c
*** old/breakpoint.c Sat Jun 30 08:03:19 1990
- --- new/breakpoint.c Sat Aug 11 21:10:59 1990
***************
*** 436,442 ****
ALL_BREAKPOINTS (b)
if (bnum == -1 || bnum == b->number)
{
! printf_filtered ("#%-3d %c 0x%08x ", b->number,
"nyod"[(int) b->enable],
b->address);
last_addr = b->address;
- --- 436,442 ----
ALL_BREAKPOINTS (b)
if (bnum == -1 || bnum == b->number)
{
! printf_filtered ("#%-3d %c 0x%08x", b->number,
"nyod"[(int) b->enable],
b->address);
last_addr = b->address;
***************
*** 444,467 ****
{
sym = find_pc_function (b->address);
if (sym)
- - printf_filtered (" in %s (%s line %d)", SYMBOL_NAME (sym),
- - b->symtab->filename, b->line_number);
- - else
- - printf_filtered ("%s line %d", b->symtab->filename, b->line_number);
- - }
- - else
- - {
- - char *name;
- - int addr;
- -
- - if (find_pc_partial_function (b->address, &name, &addr))
{
! if (b->address - addr)
! printf_filtered ("<%s+%d>", name, b->address - addr);
! else
! printf_filtered ("<%s>", name);
}
}
printf_filtered ("\n");
- --- 444,460 ----
{
sym = find_pc_function (b->address);
if (sym)
{
! fputs_filtered (" in ", stdout);
! fputs_demangled (SYMBOL_NAME (sym), stdout, 1);
! fputs_filtered (" (", stdout);
}
+ fputs_filtered (b->symtab->filename, stdout);
+ printf_filtered (" line %d", b->line_number);
+ if (sym) fputs_filtered(")", stdout);
}
+ else
+ print_address_symbolic (b->address, stdout);
printf_filtered ("\n");
diff -c old/cplus-dem.c new/cplus-dem.c
*** old/cplus-dem.c Tue Jun 26 08:23:00 1990
- --- new/cplus-dem.c Sat Aug 11 15:53:51 1990
***************
*** 23,29 ****
/* This file exports one function
! char *cplus_demangle (const char *name, int ansi)
If NAME is a mangled function name produced by GNU C++, then
a pointer to a malloced string giving a C++ representation
- --- 23,29 ----
/* This file exports one function
! char *cplus_demangle (const char *name, int mode)
If NAME is a mangled function name produced by GNU C++, then
a pointer to a malloced string giving a C++ representation
***************
*** 31,39 ****
It is the caller's responsibility to free the string which
is returned.
! If ANSI is non-zero, then ANSI qualifiers such as `const',
`void', and the ellipses operator `...' are output. Otherwise
they are not.
For example,
- --- 31,40 ----
It is the caller's responsibility to free the string which
is returned.
! If MODE > 0, then ANSI qualifiers such as `const',
`void', and the ellipses operator `...' are output. Otherwise
they are not.
+ if MODE >= 0, parameter are emiitted; otherwise not.
For example,
***************
*** 68,74 ****
#endif
#ifdef __STDC__
! extern char *cplus_demangle (const char *type, int ansi);
#else
extern char *cplus_demangle ();
#endif
- --- 69,75 ----
#endif
#ifdef __STDC__
! extern char *cplus_demangle (const char *type, int mode);
#else
extern char *cplus_demangle ();
#endif
***************
*** 148,158 ****
#endif
static void string_prependn (string *p, const char *s, int n);
static int get_count (const char **type, int *count);
! static int do_args (const char **type, string *decl);
! static int do_type (const char **type, string *result);
! static int do_arg (const char **type, string *result);
! static int do_args (const char **type, string *decl);
! static void munge_function_name (string *name);
static void remember_type (const char *type, int len);
#else
static void string_need ();
- --- 149,158 ----
#endif
static void string_prependn (string *p, const char *s, int n);
static int get_count (const char **type, int *count);
! static int do_args (const char **type, string *decl, int arg_mode);
! static int do_type (const char **type, string *result, int arg_mode);
! static int do_arg (const char **type, string *result, int arg_mode);
! static void munge_function_name (string *name, int arg_mode);
static void remember_type (const char *type, int len);
#else
static void string_need ();
***************
*** 175,186 ****
static void remember_type ();
#endif
- - static int print_ansi_qualifiers;
- -
char *
! cplus_demangle (type, ansi)
const char *type;
! int ansi;
{
string decl;
int n;
- --- 175,184 ----
static void remember_type ();
#endif
char *
! cplus_demangle (type, arg_mode)
const char *type;
! int arg_mode;
{
string decl;
int n;
***************
*** 193,199 ****
const char *premangle;
#endif
! print_ansi_qualifiers = ansi;
if (type == NULL || *type == '\0')
return NULL;
- --- 191,198 ----
const char *premangle;
#endif
! #define print_ansi_qualifiers (arg_mode > 0)
! #define print_arg_types (arg_mode >= 0)
if (type == NULL || *type == '\0')
return NULL;
***************
*** 253,259 ****
else
{
string_appendn (&decl, type, p - type);
! munge_function_name (&decl);
}
p += 2;
- --- 252,258 ----
else
{
string_appendn (&decl, type, p - type);
! munge_function_name (&decl, arg_mode);
}
p += 2;
***************
*** 310,322 ****
#ifndef LONGERNAMES
remember_type (premangle, p - premangle);
#endif
! success = do_args (&p, &decl);
! if (const_flag)
string_append (&decl, " const");
break;
case 'F':
p += 1;
! success = do_args (&p, &decl);
break;
}
- --- 309,321 ----
#ifndef LONGERNAMES
remember_type (premangle, p - premangle);
#endif
! success = do_args (&p, &decl, arg_mode);
! if (const_flag && print_arg_types)
string_append (&decl, " const");
break;
case 'F':
p += 1;
! success = do_args (&p, &decl, arg_mode);
break;
}
***************
*** 376,384 ****
/* result will be initialised here; it will be freed on failure */
static int
! do_type (type, result)
const char **type;
string *result;
{
int n;
int done;
- --- 375,384 ----
/* result will be initialised here; it will be freed on failure */
static int
! do_type (type, result, arg_mode)
const char **type;
string *result;
+ int arg_mode;
{
int n;
int done;
***************
*** 425,431 ****
string_prepend (&decl, "(");
string_append (&decl, ")");
}
! if (!do_args (type, &decl) || **type != '_')
success = 0;
else
*type += 1;
- --- 425,431 ----
string_prepend (&decl, "(");
string_append (&decl, ")");
}
! if (!do_args (type, &decl, arg_mode) || **type != '_')
success = 0;
else
*type += 1;
***************
*** 480,486 ****
break;
}
}
! if ((member && !do_args (type, &decl)) || **type != '_')
{
success = 0;
break;
- --- 480,486 ----
break;
}
}
! if ((member && !do_args (type, &decl, arg_mode)) || **type != '_')
{
success = 0;
break;
***************
*** 502,508 ****
string_append (&decl, " ");
else
non_empty = 1;
! string_append (&decl, "volatilep");
}
break;
}
- --- 502,508 ----
string_append (&decl, " ");
else
non_empty = 1;
! string_append (&decl, "volatile");
}
break;
}
***************
*** 691,703 ****
/* `result' will be initialised in do_type; it will be freed on failure */
static int
! do_arg (type, result)
const char **type;
string *result;
{
const char *start = *type;
! if (!do_type (type, result))
return 0;
remember_type (start, *type - start);
return 1;
- --- 691,704 ----
/* `result' will be initialised in do_type; it will be freed on failure */
static int
! do_arg (type, result, arg_mode)
const char **type;
string *result;
+ int arg_mode;
{
const char *start = *type;
! if (!do_type (type, result, arg_mode))
return 0;
remember_type (start, *type - start);
return 1;
***************
*** 733,746 ****
it won't be freed on failure */
static int
! do_args (type, decl)
const char **type;
string *decl;
{
string arg;
int need_comma = 0;
! string_append (decl, "(");
while (**type != '_' && **type != '\0' && **type != 'e' && **type != 'v')
{
- --- 734,749 ----
it won't be freed on failure */
static int
! do_args (type, decl, arg_mode)
const char **type;
string *decl;
+ int arg_mode;
{
string arg;
int need_comma = 0;
! if (print_arg_types)
! string_append (decl, "(");
while (**type != '_' && **type != '\0' && **type != 'e' && **type != 'v')
{
***************
*** 754,764 ****
while (--r >= 0)
{
const char *tem = typevec[t];
! if (need_comma)
string_append (decl, ", ");
! if (!do_arg (&tem, &arg))
return 0;
! string_appends (decl, &arg);
string_delete (&arg);
need_comma = 1;
}
- --- 757,768 ----
while (--r >= 0)
{
const char *tem = typevec[t];
! if (need_comma && print_arg_types)
string_append (decl, ", ");
! if (!do_arg (&tem, &arg, arg_mode))
return 0;
! if (print_arg_types)
! string_appends (decl, &arg);
string_delete (&arg);
need_comma = 1;
}
***************
*** 765,775 ****
}
else
{
! if (need_comma)
string_append (decl, ", ");
! if (!do_arg (type, &arg))
return 0;
! string_appends (decl, &arg);
string_delete (&arg);
need_comma = 1;
}
- --- 769,780 ----
}
else
{
! if (need_comma && print_arg_types)
string_append (decl, ", ");
! if (!do_arg (type, &arg, arg_mode))
return 0;
! if (print_arg_types)
! string_appends (decl, &arg);
string_delete (&arg);
need_comma = 1;
}
***************
*** 780,796 ****
else if (**type == 'e')
{
*type += 1;
! if (need_comma)
! string_append (decl, ",");
! string_append (decl, "...");
}
! string_append (decl, ")");
return 1;
}
static void
! munge_function_name (name)
string *name;
{
if (!string_empty (name) && name->p - name->b >= 3
- --- 785,805 ----
else if (**type == 'e')
{
*type += 1;
! if (print_arg_types)
! {
! if (need_comma)
! string_append (decl, ",");
! string_append (decl, "...");
! }
}
! if (print_arg_types)
! string_append (decl, ")");
return 1;
}
static void
! munge_function_name (name, arg_mode)
string *name;
{
if (!string_empty (name) && name->p - name->b >= 3
***************
*** 838,844 ****
/* type conversion operator */
string type;
const char *tem = name->b + 5;
! if (do_type (&tem, &type))
{
string_clear (name);
string_append (name, "operator ");
- --- 847,853 ----
/* type conversion operator */
string type;
const char *tem = name->b + 5;
! if (do_type (&tem, &type, arg_mode))
{
string_clear (name);
string_append (name, "operator ");
diff -c old/printcmd.c new/printcmd.c
*** old/printcmd.c Fri Jan 19 21:32:40 1990
- --- new/printcmd.c Sat Aug 11 21:24:03 1990
***************
*** 396,428 ****
value_from_long (builtin_type_int, (LONGEST) addr));
}
! /* Print address ADDR symbolically on STREAM.
! First print it as a number. Then perhaps print
! <SYMBOL + OFFSET> after the number. */
void
! print_address (addr, stream)
CORE_ADDR addr;
FILE *stream;
{
- - register int i = 0;
register char *format;
- - register struct symbol *fs;
- - char *name;
int name_location;
- - i = find_pc_partial_function (addr, &name, &name_location);
- -
/* If nothing comes out, don't print anything symbolic. */
!
! if (i == 0)
! format = "0x%x";
! else if (addr - name_location)
! format = "0x%x <%s+%d>";
else
! format = "0x%x <%s>";
! fprintf_filtered (stream, format, addr, name, addr - name_location);
}
/* Examine data at address ADDR in format FMT.
- --- 396,436 ----
value_from_long (builtin_type_int, (LONGEST) addr));
}
! /* Optionally print address ADDR symbolically as <SYMBOL+OFFSET> on STREAM. */
void
! print_address_symbolic (addr, stream)
CORE_ADDR addr;
FILE *stream;
{
register char *format;
int name_location;
+ register int i = find_pc_misc_function (addr);
/* If nothing comes out, don't print anything symbolic. */
! if (i < 0) return;
! name_location = misc_function_vector[i].address;
!
! if (addr - name_location)
! format = " <%s+%d>";
else
! format = " <%s>";
! fprintf_filtered (stream, format,
! misc_function_vector[i].name, addr - name_location);
! }
!
! /* Print address ADDR symbolically on STREAM.
! First print it as a number. Then perhaps print
! <SYMBOL + OFFSET> after the number. */
!
! void
! print_address (addr, stream)
! CORE_ADDR addr;
! FILE *stream;
! {
! fprintf_filtered (stream, "0x%x", addr);
! print_address_symbolic (addr, stream);
}
/* Examine data at address ADDR in format FMT.
diff -c old/stack.c new/stack.c
*** old/stack.c Tue Jun 5 09:19:13 1990
- --- new/stack.c Sun Aug 12 20:18:27 1990
***************
*** 99,105 ****
printf_filtered ("#%-2d ", level);
printf_filtered ("0x%x in ", fi->pc);
! printf_filtered ("%s (...) (...)\n", fname);
return;
}
- --- 99,106 ----
printf_filtered ("#%-2d ", level);
printf_filtered ("0x%x in ", fi->pc);
! fputs_demangled(fname, stdout, -1);
! fputs_filtered(" (...)\n", stdout);
return;
}
***************
*** 152,158 ****
printf ("#%-2d ", 0);
if (fi->pc != sal.pc || !sal.symtab)
printf_filtered ("0x%x in ", fi->pc);
! printf_filtered ("%s (", funname ? funname : "??");
if (args)
{
FRAME_NUM_ARGS (numargs, fi);
- --- 153,160 ----
printf ("#%-2d ", 0);
if (fi->pc != sal.pc || !sal.symtab)
printf_filtered ("0x%x in ", fi->pc);
! fputs_demangled(funname ? funname : "??", stdout, -1);
! printf_filtered(" (");
if (args)
{
FRAME_NUM_ARGS (numargs, fi);
***************
*** 571,577 ****
struct symtab_and_line sal;
sal = find_pc_line (SYMBOL_VALUE (sym), 0);
values_printed = 1;
! fputs_filtered (SYMBOL_NAME (sym), stream);
fprintf_filtered (stream, " 0x%x in file %s, line %d\n",
SYMBOL_VALUE (sym), sal.symtab->filename, sal.line);
fflush (stream);
- --- 573,579 ----
struct symtab_and_line sal;
sal = find_pc_line (SYMBOL_VALUE (sym), 0);
values_printed = 1;
! fputs_demangled (SYMBOL_NAME (sym), stream, 1);
fprintf_filtered (stream, " 0x%x in file %s, line %d\n",
SYMBOL_VALUE (sym), sal.symtab->filename, sal.line);
fflush (stream);
diff -c old/symtab.c new/symtab.c
*** old/symtab.c Wed Jul 4 07:27:27 1990
- --- new/symtab.c Mon Aug 13 12:30:07 1990
***************
*** 26,31 ****
- --- 26,33 ----
#include <assert.h>
char *index ();
+ extern char *cplus_demangle ();
+ extern struct value * value_of_this ();
/* Allocate an obstack to hold objects that should be freed
when we load a new symbol table.
***************
*** 934,940 ****
check to see if NAME is a field of `this'. */
if (is_a_field_of_this)
{
! int v = (int) value_of_this (0);
*is_a_field_of_this = 0;
if (v && check_field (v, name))
- --- 936,942 ----
check to see if NAME is a field of `this'. */
if (is_a_field_of_this)
{
! struct value *v = value_of_this (0);
*is_a_field_of_this = 0;
if (v && check_field (v, name))
***************
*** 967,972 ****
- --- 969,994 ----
{
int index = lookup_misc_func (name);
+ if (index == -1)
+ { /* Look for a mangled C++ name for NAME. */
+ int name_len = strlen (name);
+ for (index = misc_function_count; --index >= 0; )
+ /* Assume orginal name is prefix of mangled name. */
+ if (!strncmp (misc_function_vector[index].name, name, name_len))
+ {
+ char *demangled =
+ cplus_demangle(misc_function_vector[index].name, -1);
+ if (demangled != NULL)
+ {
+ int cond = strcmp (demangled, name);
+ free (demangled);
+ if (!cond)
+ break;
+ }
+ }
+ /* Loop terminates on no match with index == -1. */
+ }
+
if (index != -1)
{
ps = find_pc_psymtab (misc_function_vector[index].address);
***************
*** 1861,1869 ****
if (sym)
error ("%s is not a function.", copy);
! if ((i = lookup_misc_func (copy)) < 0)
! error ("Function %s not defined.", copy);
! else
{
value.symtab = 0;
value.line = 0;
- --- 1883,1892 ----
if (sym)
error ("%s is not a function.", copy);
! if (symtab_list == 0 && partial_symtab_list == 0)
! error ("No symbol table is loaded. Use the \"symbol-file\" command.");
!
! if ((i = lookup_misc_func (copy)) >= 0)
{
value.symtab = 0;
value.line = 0;
***************
*** 1876,1883 ****
return values;
}
- - if (symtab_list == 0 && partial_symtab_list == 0)
- - error ("No symbol table is loaded. Use the \"symbol-file\" command.");
error ("Function %s not defined.", copy);
}
- --- 1899,1904 ----
***************
*** 1929,1934 ****
- --- 1950,1956 ----
if (funfirstline)
SKIP_PROLOGUE (pc);
values.sals[i] = find_pc_line (pc, 0);
+ values.sals[i].pc = (values.sals[i].end && values.sals[i].pc != pc) ? values.sals[i].end : pc;
printf("[%d] file:%s; line number:%d\n",
(i+2), values.sals[i].symtab->filename, values.sals[i].line);
}
diff -c old/utils.c new/utils.c
*** old/utils.c Tue Jun 26 08:20:14 1990
- --- new/utils.c Sat Aug 11 15:16:23 1990
***************
*** 582,656 ****
Note that a longjmp to top level may occur in this routine
(since prompt_for_continue may do so) so this routine should not be
! called when cleanups are not in place.
- - fputs_filtered demangles g++ names.*/
- -
- - void _fputs_filtered (); /* forward decl. */
- -
- -
void
fputs_filtered (linebuffer, stream)
char *linebuffer;
FILE *stream;
{
- - #ifdef __STDC__
- - extern char *cplus_demangle (const char *, int);
- - #else
- - extern char *cplus_demangle ();
- - #endif
- - #define SYMBOL_MAX 1024
- -
- - #define SYMBOL_CHAR(c) (isascii(c) && (isalnum(c) || (c) == '_' || (c) == '$'))
- -
- - char buf[SYMBOL_MAX+1];
- - char *p;
- -
- - if (linebuffer == NULL)
- - return;
- -
- - p = linebuffer;
- -
- - while ( *p != (char) 0 ) {
- - int i = 0;
- -
- - /* collect non-interesting characters into buf */
- - while ( *p != (char) 0 && !SYMBOL_CHAR(*p) ) {
- - buf[i++] = *p;
- - p++;
- - }
- - if (i > 0) {
- - /* output the non-interesting characters without demangling */
- - buf[i] = (char) 0;
- - _fputs_filtered(buf, stream);
- - i = 0; /* reset buf */
- - }
- -
- - /* and now the interesting characters */
- - while (i < SYMBOL_MAX && *p != (char) 0 && SYMBOL_CHAR(*p) ) {
- - buf[i++] = *p;
- - p++;
- - }
- - buf[i] = (char) 0;
- - if (i > 0) {
- - char * result;
- -
- - if ( (result = cplus_demangle(buf, 1)) != NULL ) {
- - _fputs_filtered(result, stream);
- - free(result);
- - }
- - else {
- - _fputs_filtered(buf, stream);
- - }
- - }
- - }
- - }
- -
- - void
- - _fputs_filtered (linebuffer, stream)
- - char *linebuffer;
- - FILE *stream;
- - {
char *lineptr;
if (linebuffer == 0)
- --- 582,594 ----
Note that a longjmp to top level may occur in this routine
(since prompt_for_continue may do so) so this routine should not be
! called when cleanups are not in place. */
void
fputs_filtered (linebuffer, stream)
char *linebuffer;
FILE *stream;
{
char *lineptr;
if (linebuffer == 0)
***************
*** 711,716 ****
- --- 649,714 ----
chars_printed = 0;
}
}
+ }
+
+ /* fputs_demangled is a variant of fputs_filtered that
+ demangles g++ names.*/
+
+ void
+ fputs_demangled (linebuffer, stream, arg_mode)
+ char *linebuffer;
+ FILE *stream;
+ {
+ #ifdef __STDC__
+ extern char *cplus_demangle (const char *, int);
+ #else
+ extern char *cplus_demangle ();
+ #endif
+ #define SYMBOL_MAX 1024
+
+ #define SYMBOL_CHAR(c) (isascii(c) && (isalnum(c) || (c) == '_' || (c) == '$'))
+
+ char buf[SYMBOL_MAX+1];
+ char *p;
+
+ if (linebuffer == NULL)
+ return;
+
+ p = linebuffer;
+
+ while ( *p != (char) 0 ) {
+ int i = 0;
+
+ /* collect non-interesting characters into buf */
+ while ( *p != (char) 0 && !SYMBOL_CHAR(*p) ) {
+ buf[i++] = *p;
+ p++;
+ }
+ if (i > 0) {
+ /* output the non-interesting characters without demangling */
+ buf[i] = (char) 0;
+ fputs_filtered(buf, stream);
+ i = 0; /* reset buf */
+ }
+
+ /* and now the interesting characters */
+ while (i < SYMBOL_MAX && *p != (char) 0 && SYMBOL_CHAR(*p) ) {
+ buf[i++] = *p;
+ p++;
+ }
+ buf[i] = (char) 0;
+ if (i > 0) {
+ char * result;
+
+ if ( (result = cplus_demangle(buf, arg_mode)) != NULL ) {
+ fputs_filtered(result, stream);
+ free(result);
+ }
+ else {
+ fputs_filtered(buf, stream);
+ }
+ }
+ }
}
/* Print ARG1, ARG2, and ARG3 on stdout using format FORMAT. If this
diff -c old/valops.c new/valops.c
*** old/valops.c Wed Jun 27 01:46:50 1990
- --- new/valops.c Sun Aug 12 23:08:17 1990
***************
*** 768,773 ****
- --- 768,807 ----
return val;
}
+ /* Helper function used by value_struct_elt to recurse through baseclasses.
+ Look for a field NAME in ARG1. Adjust the address of ARG1 by OFFSET bytes,
+ and treat the result as having type TYPE.
+ If found, return value, else return NULL. */
+
+ static value search_struct_field (name, arg1, offset, type)
+ char *name;
+ register value arg1;
+ int offset;
+ register struct type *type;
+ {
+ int i;
+ check_stub_type (type);
+ for (i = TYPE_NFIELDS (type) - 1; i >= 0; i--)
+ {
+ char *t_field_name = TYPE_FIELD_NAME (type, i);
+ if (t_field_name && !strcmp (t_field_name, name))
+ return TYPE_FIELD_STATIC (type, i)
+ ? value_static_field (type, name, i)
+ : value_primitive_field (arg1, offset, i, type);
+ }
+
+ for (i = TYPE_N_BASECLASSES (type); --i >= 0; )
+ {
+ /* Needs work for virtual base classes */
+ value v = search_struct_field (name,
+ arg1,
+ offset + TYPE_FIELD_BITPOS (type, i) / 8,
+ TYPE_FIELD_TYPE (type, i));
+ if (v) return v;
+ }
+ return NULL;
+ }
+
/* Given ARG1, a value of type (pointer to a)* structure/union,
extract the component named NAME from the ultimate target structure/union
and return it as a value with its appropriate type.
***************
*** 827,857 ****
/* Try as a variable first, because if we succeed, there
is less work to be done. */
! while (t)
! {
! check_stub_type (t);
- - for (i = TYPE_NFIELDS (t) - 1; i >= 0; i--)
- - {
- - char *t_field_name = TYPE_FIELD_NAME (t, i);
- - if (t_field_name && !strcmp (t_field_name, name))
- - {
- - found = 1;
- - break;
- - }
- - }
- -
- - if (i >= 0)
- - return TYPE_FIELD_STATIC (t, i)
- - ? value_static_field (t, name, i) : value_field (arg1, i);
- -
- - if (TYPE_N_BASECLASSES (t) == 0)
- - break;
- -
- - t = TYPE_BASECLASS (t, 1);
- - VALUE_TYPE (arg1) = t; /* side effect! */
- - }
- -
/* C++: If it was not found as a data field, then try to
return it as a pointer to a method. */
t = baseclass;
- --- 861,869 ----
/* Try as a variable first, because if we succeed, there
is less work to be done. */
! value v = search_struct_field (name, arg1, 0, t);
! if (v) return v;
/* C++: If it was not found as a data field, then try to
return it as a pointer to a method. */
t = baseclass;
***************
*** 998,1003 ****
- --- 1010,1055 ----
return 0;
}
+ /* Helper function for check_field: Given TYPE, a structure/union,
+ return 1 if the component named NAME from the ultimate
+ target structure/union is defined, otherwise, return 0. */
+
+ static int
+ check_field_in (type, name)
+ register struct type *type;
+ char *name;
+ {
+ register int i;
+
+ for (i = TYPE_NFIELDS (type); --i >= 0; )
+ {
+ char *t_field_name = TYPE_FIELD_NAME (type, i);
+ if (t_field_name && !strcmp (t_field_name, name))
+ return 1;
+ }
+
+ /* C++: If it was not found as a data field, then try to
+ return it as a pointer to a method. */
+
+ /* Destructors are a special case. */
+ if (destructor_name_p (name, type))
+ return 1;
+
+ for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; --i)
+ {
+ if (!strcmp (TYPE_FN_FIELDLIST_NAME (type, i), name))
+ return 1;
+ }
+
+ for (i = TYPE_N_BASECLASSES (type); i > 0; i--)
+ {
+ if (check_field_in (TYPE_BASECLASS (type, i), name))
+ return 1;
+ }
+
+ return 0;
+ }
+
/* C++: Given ARG1, a value of type (pointer to a)* structure/union,
return 1 if the component named NAME from the ultimate
target structure/union is defined, otherwise, return 0. */
***************
*** 1008,1018 ****
char *name;
{
register struct type *t;
- - register int i;
- - int found = 0;
- -
- - struct type *baseclass;
- -
COERCE_ARRAY (arg1);
t = VALUE_TYPE (arg1);
- --- 1060,1065 ----
***************
*** 1029,1075 ****
&& TYPE_CODE (t) != TYPE_CODE_UNION)
error ("Internal error: `this' is not an aggregate");
! baseclass = t;
!
! while (t)
! {
! for (i = TYPE_NFIELDS (t) - 1; i >= 0; i--)
! {
! char *t_field_name = TYPE_FIELD_NAME (t, i);
! if (t_field_name && !strcmp (t_field_name, name))
! {
! return 1;
! }
! }
! if (TYPE_N_BASECLASSES (t) == 0)
! break;
!
! t = TYPE_BASECLASS (t, 1);
! }
!
! /* C++: If it was not found as a data field, then try to
! return it as a pointer to a method. */
! t = baseclass;
! VALUE_TYPE (arg1) = t; /* side effect! */
!
! /* Destructors are a special case. */
! if (destructor_name_p (name, t))
! return 1;
!
! while (t)
! {
! for (i = TYPE_NFN_FIELDS (t) - 1; i >= 0; --i)
! {
! if (!strcmp (TYPE_FN_FIELDLIST_NAME (t, i), name))
! return 1;
! }
!
! if (TYPE_N_BASECLASSES (t) == 0)
! break;
!
! t = TYPE_BASECLASS (t, 1);
! }
! return 0;
}
/* C++: Given an aggregate type DOMAIN, and a member name NAME,
- --- 1076,1082 ----
&& TYPE_CODE (t) != TYPE_CODE_UNION)
error ("Internal error: `this' is not an aggregate");
! return check_field_in (t, name);
}
/* C++: Given an aggregate type DOMAIN, and a member name NAME,
***************
*** 1251,1257 ****
else return 0;
sym = BLOCK_SYM (b, 0);
! if (strncmp ("$this", SYMBOL_NAME (sym), 5))
if (complain)
error ("current stack frame not in method");
else return 0;
- --- 1258,1264 ----
else return 0;
sym = BLOCK_SYM (b, 0);
! if (strcmp ("this", SYMBOL_NAME (sym)))
if (complain)
error ("current stack frame not in method");
else return 0;
diff -c old/valprint.c new/valprint.c
*** old/valprint.c Wed Jun 27 01:46:50 1990
- --- new/valprint.c Sun Aug 12 10:47:46 1990
***************
*** 635,654 ****
val_print (TYPE_FIELD_TYPE (type, i-1), baddr,
0, stream, 0, 0, recurse + 1, pretty);
}
- - if (i > 1) {
- - fprintf_filtered (stream, "\n");
- - print_spaces_filtered (2 + 2 * recurse, stream);
- - fputs_filtered ("members of ", stream);
- - fputs_filtered (type_name_no_tag (type), stream);
- - fputs_filtered (": ", stream);
- - }
if (!len && i == 1)
fprintf_filtered (stream, "<No data fields>");
else
{
for (i -= 1; i < len; i++)
{
! if (i > n_baseclasses) fprintf_filtered (stream, ", ");
if (pretty)
{
fprintf_filtered (stream, "\n");
- --- 635,660 ----
val_print (TYPE_FIELD_TYPE (type, i-1), baddr,
0, stream, 0, 0, recurse + 1, pretty);
}
if (!len && i == 1)
fprintf_filtered (stream, "<No data fields>");
else
{
+ int fields_seen = 0;
for (i -= 1; i < len; i++)
{
! /* check if static field */
! if (TYPE_FIELD_STATIC (type, i))
! continue;
! if (fields_seen) fprintf_filtered (stream, ", ");
! else if (n_baseclasses > 0)
! {
! fprintf_filtered (stream, "\n");
! print_spaces_filtered (2 + 2 * recurse, stream);
! fputs_filtered ("members of ", stream);
! fputs_filtered (type_name_no_tag (type), stream);
! fputs_filtered (": ", stream);
! }
! fields_seen = 1;
if (pretty)
{
fprintf_filtered (stream, "\n");
***************
*** 656,673 ****
}
fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
fputs_filtered (" = ", stream);
! /* check if static field */
! if (TYPE_FIELD_STATIC (type, i))
{
- - value v;
- -
- - v = value_static_field (type, TYPE_FIELD_NAME (type, i), i);
- - val_print (TYPE_FIELD_TYPE (type, i),
- - VALUE_CONTENTS (v), 0, stream, format,
- - deref_ref, recurse + 1, pretty);
- - }
- - else if (TYPE_FIELD_PACKED (type, i))
- - {
char *valp = (char *) & val;
union {int i; char c;} test;
test.i = 1;
- --- 662,669 ----
}
fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
fputs_filtered (" = ", stream);
! if (TYPE_FIELD_PACKED (type, i))
{
char *valp = (char *) & val;
union {int i; char c;} test;
test.i = 1;
***************
*** 893,900 ****
int i;
fputs_filtered (" ", stream);
! fputs_filtered (prefix, stream);
! fputs_filtered (varstring, stream);
fputs_filtered (" (", stream);
if (args && args[!staticp] && args[!staticp]->code != TYPE_CODE_VOID)
{
- --- 889,896 ----
int i;
fputs_filtered (" ", stream);
! fputs_demangled (prefix, stream, 1);
! fputs_demangled (varstring, stream, 1);
fputs_filtered (" (", stream);
if (args && args[!staticp] && args[!staticp]->code != TYPE_CODE_VOID)
{
***************
*** 930,957 ****
int i, n_baseclasses = TYPE_N_BASECLASSES (type);
struct type *basetype = 0;
! while (type && n_baseclasses == 1)
{
!
! check_stub_type(type); /* Not actually sure about this one -- Bryan. */
!
! basetype = TYPE_BASECLASS (type, 1);
! if (name = type_name_no_tag (basetype))
! {
! fprintf_filtered (stream, ": %s%s ",
! TYPE_VIA_PUBLIC (basetype) ? "public" : "private",
! TYPE_VIA_VIRTUAL (basetype) ? " virtual" : "");
! fputs_filtered (name, stream);
! fputs_filtered (" ", stream);
! }
! n_baseclasses = TYPE_N_BASECLASSES (basetype);
! type = basetype;
! }
!
! if (type)
! {
! if (n_baseclasses != 0)
! fprintf_filtered (stream, ": ");
for (i = 1; i <= n_baseclasses; i++)
{
basetype = TYPE_BASECLASS (type, i);
- --- 926,937 ----
int i, n_baseclasses = TYPE_N_BASECLASSES (type);
struct type *basetype = 0;
! while (type && n_baseclasses > 0)
{
! /* Not actually sure about this one -- Bryan. */
! check_stub_type (type);
!
! fprintf_filtered (stream, ": ");
for (i = 1; i <= n_baseclasses; i++)
{
basetype = TYPE_BASECLASS (type, i);
***************
*** 965,971 ****
- --- 945,955 ----
if (i < n_baseclasses)
fprintf_filtered (stream, ", ");
}
+
fprintf_filtered (stream, " ");
+ if (n_baseclasses != 1) break;
+ n_baseclasses = TYPE_N_BASECLASSES (basetype);
+ type = basetype;
}
}
***************
*** 1288,1294 ****
fprintf_filtered (stream, ";\n");
}
- - if (len2) fprintf_filtered (stream, "\n");
}
print_spaces_filtered (level, stream);
- --- 1272,1277 ----
diff -c old/value.h new/value.h
*** old/value.h Tue Jun 26 01:51:24 1990
- --- new/value.h Sat Aug 11 12:52:56 1990
***************
*** 165,171 ****
value value_neg ();
value value_lognot ();
value value_struct_elt (), value_struct_elt_for_address ();
! value value_field ();
value value_cast ();
value value_zero ();
value value_repeat ();
- --- 165,171 ----
value value_neg ();
value value_lognot ();
value value_struct_elt (), value_struct_elt_for_address ();
! value value_field (), value_primitive_field();
value value_cast ();
value value_zero ();
value value_repeat ();
diff -c old/values.c new/values.c
*** old/values.c Tue Jul 3 11:39:01 1990
- --- new/values.c Sat Aug 11 12:51:37 1990
***************
*** 642,648 ****
return (double) 0; /* To silence compiler warning. */
}
! /* Given a value ARG1 of a struct or union type,
extract and return the value of one of its fields.
FIELDNO says which field.
- --- 642,649 ----
return (double) 0; /* To silence compiler warning. */
}
! /* Given a value ARG1 (offset by OFFSET bytes)
! of a struct or union type ARG_TYPE,
extract and return the value of one of its fields.
FIELDNO says which field.
***************
*** 649,676 ****
For C++, must also be able to return values from static fields */
value
! value_field (arg1, fieldno)
register value arg1;
register int fieldno;
{
register value v;
register struct type *type;
- - register int offset;
! check_stub_type (VALUE_TYPE (arg1));
! type = TYPE_FIELD_TYPE (VALUE_TYPE (arg1), fieldno);
/* Handle packed fields */
! offset = TYPE_FIELD_BITPOS (VALUE_TYPE (arg1), fieldno) / 8;
if (TYPE_FIELD_BITSIZE (VALUE_TYPE (arg1), fieldno))
{
v = value_from_long (type,
! unpack_field_as_long (VALUE_TYPE (arg1),
VALUE_CONTENTS (arg1),
fieldno));
! VALUE_BITPOS (v) = TYPE_FIELD_BITPOS (VALUE_TYPE (arg1), fieldno) % 8;
! VALUE_BITSIZE (v) = TYPE_FIELD_BITSIZE (VALUE_TYPE (arg1), fieldno);
}
else
{
- --- 650,677 ----
For C++, must also be able to return values from static fields */
value
! value_primitive_field (arg1, offset, fieldno, arg_type)
register value arg1;
register int fieldno;
+ register struct type *arg_type;
{
register value v;
register struct type *type;
! check_stub_type (arg_type);
! type = TYPE_FIELD_TYPE (arg_type, fieldno);
/* Handle packed fields */
! offset += TYPE_FIELD_BITPOS (arg_type, fieldno) / 8;
if (TYPE_FIELD_BITSIZE (VALUE_TYPE (arg1), fieldno))
{
v = value_from_long (type,
! unpack_field_as_long (arg_type,
VALUE_CONTENTS (arg1),
fieldno));
! VALUE_BITPOS (v) = TYPE_FIELD_BITPOS (arg_type, fieldno) % 8;
! VALUE_BITSIZE (v) = TYPE_FIELD_BITSIZE (arg_type, fieldno);
}
else
{
***************
*** 685,690 ****
- --- 686,705 ----
VALUE_ADDRESS (v) = VALUE_ADDRESS (arg1);
VALUE_OFFSET (v) = offset + VALUE_OFFSET (arg1);
return v;
+ }
+
+ /* Given a value ARG1 of a struct or union type,
+ extract and return the value of one of its fields.
+ FIELDNO says which field.
+
+ For C++, must also be able to return values from static fields */
+
+ value
+ value_field (arg1, fieldno)
+ register value arg1;
+ register int fieldno;
+ {
+ return value_primitive_field (arg1, 0, VALUE_TYPE (arg1), fieldno);
}
value
Technical Details
Message-ID:
<9008131858.AA21679@sevenlayer.cs.wisc.edu>Path:
arc1-ca.pugleaf.net!gmdzi!unido!mcsun!uunet!tut.cis.ohio-state.edu!CS.WISC.EDU!bothnerShow Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: f5053,b78a05d6f56ffcae,start X-Google-Attributes: gidf5053,public X-Google-ArrivalTime: 1990-08-14 10:06:32 PST Path: arc1-ca.pugleaf.net!gmdzi!unido!mcsun!uunet!tut.cis.ohio-state.edu!CS.WISC.EDU!bothner From: bothner@CS.WISC.EDU Newsgroups: gnu.gdb.bug Subject: Gdb patches for g++ users Message-ID: <9008131858.AA21679@sevenlayer.cs.wisc.edu> Date: 13 Aug 90 18:58:42 GMT Sender: daemon@tut.cis.ohio-state.edu Distribution: gnu Organization: GNUs Not Usenet Lines: 1465 Posted: Mon Aug 13 19:58:42 1990