Some improvements to g++ debugging.
* symtab.c (list_symbols): demangle before pattern matching. * symtab.c: Other fixes to improve handing of operators. * valprint.c (type_print_base): Fix test for constructor. * values.c (value_static_field): Allow evaluation of CLASS::METHOD, returning a function pointer.
This commit is contained in:
parent
c976b3499c
commit
2cd9998540
|
@ -1,3 +1,12 @@
|
|||
Wed Mar 18 15:51:15 1992 Per Bothner (bothner@cygnus.com)
|
||||
|
||||
Some improvements to g++ debugging.
|
||||
* symtab.c (list_symbols): demangle before pattern matching.
|
||||
* symtab.c: Other fixes to improve handing of operators.
|
||||
* valprint.c (type_print_base): Fix test for constructor.
|
||||
* values.c (value_static_field): Allow evaluation of
|
||||
CLASS::METHOD, returning a function pointer.
|
||||
|
||||
Wed Mar 18 08:39:52 1992 Fred Fish (fnf@cygnus.com)
|
||||
|
||||
* Makefile.in (VERSION): Roll 4.4.6.
|
||||
|
|
105
gdb/symtab.c
105
gdb/symtab.c
|
@ -37,10 +37,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/* Prototypes for local functions */
|
||||
|
||||
static int
|
||||
extern int
|
||||
find_methods PARAMS ((struct type *, char *, char **, struct symbol **));
|
||||
|
||||
static void
|
||||
|
@ -1260,14 +1261,24 @@ operator_chars (p, end)
|
|||
|
||||
/* Don't get faked out by `operator' being part of a longer
|
||||
identifier. */
|
||||
if ((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z')
|
||||
|| *p == '_' || *p == '$' || *p == '\0')
|
||||
if (isalpha(*p) || *p == '_' || *p == '$' || *p == '\0')
|
||||
return *end;
|
||||
|
||||
/* Allow some whitespace between `operator' and the operator symbol. */
|
||||
while (*p == ' ' || *p == '\t')
|
||||
p++;
|
||||
|
||||
/* Recognize 'operator TYPENAME'. */
|
||||
|
||||
if (isalpha(*p) || *p == '_' || *p == '$')
|
||||
{
|
||||
register char *q = p+1;
|
||||
while (isalnum(*q) || *q == '_' || *q == '$')
|
||||
q++;
|
||||
*end = q;
|
||||
return p;
|
||||
}
|
||||
|
||||
switch (*p)
|
||||
{
|
||||
case '!':
|
||||
|
@ -1328,7 +1339,7 @@ operator_chars (p, end)
|
|||
* physnames = (char **) alloca (TYPE_NFN_FIELDS_TOTAL (t) * sizeof(char*));
|
||||
*/
|
||||
|
||||
static int
|
||||
int
|
||||
find_methods (t, name, physnames, sym_arr)
|
||||
struct type *t;
|
||||
char *name;
|
||||
|
@ -1392,6 +1403,12 @@ find_methods (t, name, physnames, sym_arr)
|
|||
(int *) NULL,
|
||||
(struct symtab **) NULL);
|
||||
if (sym_arr[i1]) i1++;
|
||||
else
|
||||
{
|
||||
fputs_filtered("(Cannot find method ", stdout);
|
||||
fputs_demangled(phys_name, stdout, 0);
|
||||
fputs_filtered(" - possibly inlined.)\n", stdout);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1525,18 +1542,22 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
|
|||
while (*p && *p != ' ' && *p != '\t' && *p != ',' && *p !=':') p++;
|
||||
q = operator_chars (*argptr, &q1);
|
||||
|
||||
copy = (char *) alloca (p - *argptr + 1 + (q1 - q));
|
||||
if (q1 - q)
|
||||
{
|
||||
copy[0] = 'o';
|
||||
copy[1] = 'p';
|
||||
copy[2] = CPLUS_MARKER;
|
||||
bcopy (q, copy + 3, q1 - q);
|
||||
copy[3 + (q1 - q)] = '\0';
|
||||
char *opname;
|
||||
char *tmp = alloca (q1 - q + 1);
|
||||
memcpy (tmp, q, q1 - q);
|
||||
tmp[q1 - q] = '\0';
|
||||
opname = cplus_mangle_opname (tmp, 1);
|
||||
if (opname == NULL)
|
||||
error ("No mangling for \"%s\"", tmp);
|
||||
copy = (char*) alloca (3 + strlen(opname));
|
||||
sprintf (copy, "__%s", opname);
|
||||
p = q1;
|
||||
}
|
||||
else
|
||||
{
|
||||
copy = (char *) alloca (p - *argptr + 1 + (q1 - q));
|
||||
bcopy (*argptr, copy, p - *argptr);
|
||||
copy[p - *argptr] = '\0';
|
||||
}
|
||||
|
@ -1709,6 +1730,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line)
|
|||
|
||||
/* Arg token is not digits => try it as a variable name
|
||||
Find the next token (everything up to end or next whitespace). */
|
||||
|
||||
p = *argptr;
|
||||
while (*p && *p != ' ' && *p != '\t' && *p != ',') p++;
|
||||
copy = (char *) alloca (p - *argptr + 1);
|
||||
|
@ -2027,6 +2049,21 @@ sources_info ()
|
|||
printf_filtered ("\n");
|
||||
}
|
||||
|
||||
static int
|
||||
name_match(name)
|
||||
char *name;
|
||||
{
|
||||
char *demangled = cplus_demangle(name, -1);
|
||||
if (demangled != NULL)
|
||||
{
|
||||
int cond = re_exec (demangled);
|
||||
free (demangled);
|
||||
return cond;
|
||||
}
|
||||
return re_exec(name);
|
||||
}
|
||||
#define NAME_MATCH(NAME) name_match(NAME)
|
||||
|
||||
/* List all symbols (if REGEXP is 0) or all symbols matching REGEXP.
|
||||
If CLASS is zero, list all symbols except functions and type names.
|
||||
If CLASS is 1, list only functions.
|
||||
|
@ -2052,7 +2089,8 @@ list_symbols (regexp, class, bpt)
|
|||
struct partial_symbol *psym;
|
||||
struct objfile *objfile;
|
||||
struct minimal_symbol *msymbol;
|
||||
char *val;
|
||||
char *val, *q2;
|
||||
/* char *mangled;*/
|
||||
static char *classnames[]
|
||||
= {"variable", "function", "type", "method"};
|
||||
int found_in_file = 0;
|
||||
|
@ -2064,9 +2102,42 @@ list_symbols (regexp, class, bpt)
|
|||
enum minimal_symbol_type ourtype = types[class];
|
||||
enum minimal_symbol_type ourtype2 = types2[class];
|
||||
|
||||
|
||||
if (regexp)
|
||||
if (0 != (val = re_comp (regexp)))
|
||||
error ("Invalid regexp (%s): %s", val, regexp);
|
||||
{
|
||||
/* Make sure spacing is right for C++ operators.
|
||||
This is just a courtesy to make the matching less sensitive
|
||||
to how many spaces the user leaves between 'operator'
|
||||
and <TYPENAME> or <OPERATOR>. */
|
||||
char *opend;
|
||||
char *opname = operator_chars (regexp, &opend);
|
||||
if (*opname)
|
||||
{
|
||||
int fix = -1; /* -1 means ok; otherwise number of spaces needed. */
|
||||
if (isalpha(*opname) || *opname == '_' || *opname == '$')
|
||||
{
|
||||
/* There should 1 space between 'operator' and 'TYPENAME'. */
|
||||
if (opname[-1] != ' ' || opname[-2] == ' ')
|
||||
fix = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* There should 0 spaces between 'operator' and 'OPERATOR'. */
|
||||
if (opname[-1] == ' ')
|
||||
fix = 0;
|
||||
}
|
||||
/* If wrong number of spaces, fix it. */
|
||||
if (fix >= 0)
|
||||
{
|
||||
char *tmp = (char*) alloca(opend-opname+10);
|
||||
sprintf(tmp, "operator%.*s%s", fix, " ", opname);
|
||||
regexp = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 != (val = re_comp (regexp)))
|
||||
error ("Invalid regexp (%s): %s", val, regexp);
|
||||
}
|
||||
|
||||
/* Search through the partial symtabs *first* for all symbols
|
||||
matching the regexp. That way we don't have to reproduce all of
|
||||
|
@ -2107,7 +2178,7 @@ list_symbols (regexp, class, bpt)
|
|||
|
||||
/* If it would match (logic taken from loop below)
|
||||
load the file and go on to the next one */
|
||||
if ((regexp == 0 || re_exec (SYMBOL_NAME (psym)))
|
||||
if ((regexp == 0 || NAME_MATCH (SYMBOL_NAME (psym)))
|
||||
&& ((class == 0 && SYMBOL_CLASS (psym) != LOC_TYPEDEF
|
||||
&& SYMBOL_CLASS (psym) != LOC_BLOCK)
|
||||
|| (class == 1 && SYMBOL_CLASS (psym) == LOC_BLOCK)
|
||||
|
@ -2138,7 +2209,7 @@ list_symbols (regexp, class, bpt)
|
|||
{
|
||||
if (msymbol -> type == ourtype || msymbol -> type == ourtype2)
|
||||
{
|
||||
if (regexp == 0 || re_exec (msymbol -> name))
|
||||
if (regexp == 0 || NAME_MATCH (msymbol -> name))
|
||||
{
|
||||
if (0 == find_pc_symtab (msymbol -> address))
|
||||
{
|
||||
|
@ -2181,7 +2252,7 @@ list_symbols (regexp, class, bpt)
|
|||
{
|
||||
QUIT;
|
||||
sym = BLOCK_SYM (b, j);
|
||||
if ((regexp == 0 || re_exec (SYMBOL_NAME (sym)))
|
||||
if ((regexp == 0 || NAME_MATCH (SYMBOL_NAME (sym)))
|
||||
&& ((class == 0 && SYMBOL_CLASS (sym) != LOC_TYPEDEF
|
||||
&& SYMBOL_CLASS (sym) != LOC_BLOCK)
|
||||
|| (class == 1 && SYMBOL_CLASS (sym) == LOC_BLOCK)
|
||||
|
@ -2251,7 +2322,7 @@ list_symbols (regexp, class, bpt)
|
|||
{
|
||||
if (msymbol -> type == ourtype || msymbol -> type == ourtype2)
|
||||
{
|
||||
if (regexp == 0 || re_exec (msymbol -> name))
|
||||
if (regexp == 0 || NAME_MATCH (msymbol -> name))
|
||||
{
|
||||
/* Functions: Look up by address. */
|
||||
if (class != 1 &&
|
||||
|
|
101
gdb/valprint.c
101
gdb/valprint.c
|
@ -17,10 +17,10 @@ You should have received a copy of the GNU General Public License
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "defs.h"
|
||||
#include <string.h>
|
||||
#include "symtab.h"
|
||||
#include "gdbtypes.h"
|
||||
#include "value.h"
|
||||
#include "gdbcore.h"
|
||||
#include "gdbcmd.h"
|
||||
|
@ -29,11 +29,59 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|||
#include "language.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
/* Prototypes for local functions */
|
||||
|
||||
static void
|
||||
print_string PARAMS ((FILE *, char *, unsigned int, int));
|
||||
|
||||
static void
|
||||
show_print PARAMS ((char *, int));
|
||||
|
||||
static void
|
||||
set_print PARAMS ((char *, int));
|
||||
|
||||
static void
|
||||
set_radix PARAMS ((char *, int, struct cmd_list_element *));
|
||||
|
||||
static void
|
||||
set_output_radix PARAMS ((char *, int, struct cmd_list_element *));
|
||||
|
||||
static void
|
||||
type_print_base PARAMS ((struct type *, FILE *, int, int));
|
||||
|
||||
static void
|
||||
type_print_varspec_suffix PARAMS ((struct type *, FILE *, int, int));
|
||||
|
||||
static void
|
||||
type_print_varspec_prefix PARAMS ((struct type *, FILE *, int, int));
|
||||
|
||||
static void
|
||||
type_print_derivation_info PARAMS ((FILE *, struct type *));
|
||||
|
||||
static void
|
||||
type_print_method_args PARAMS ((struct type **, char *, char *, int, FILE *));
|
||||
|
||||
static void
|
||||
cplus_val_print PARAMS ((struct type *, char *, FILE *, int, int,
|
||||
enum val_prettyprint, struct type **));
|
||||
|
||||
static void
|
||||
val_print_fields PARAMS ((struct type *, char *, FILE *, int, int,
|
||||
enum val_prettyprint, struct type **));
|
||||
|
||||
static int
|
||||
is_vtbl_member PARAMS ((struct type *));
|
||||
|
||||
static int
|
||||
is_vtbl_ptr_type PARAMS ((struct type *));
|
||||
|
||||
static void
|
||||
print_hex_chars PARAMS ((FILE *, unsigned char *, unsigned));
|
||||
|
||||
extern int sys_nerr;
|
||||
extern char *sys_errlist[];
|
||||
|
||||
extern void print_scalar_formatted(); /* printcmd.c */
|
||||
extern void print_address_demangle(); /* printcmd.c */
|
||||
extern int demangle; /* whether to print C++ syms raw or source-form */
|
||||
|
||||
/* Maximum number of chars to print for a string pointer value
|
||||
|
@ -41,11 +89,6 @@ extern int demangle; /* whether to print C++ syms raw or source-form */
|
|||
|
||||
static unsigned int print_max;
|
||||
|
||||
static void type_print_varspec_suffix ();
|
||||
static void type_print_varspec_prefix ();
|
||||
static void type_print_base ();
|
||||
static void type_print_method_args ();
|
||||
|
||||
/* Default input and output radixes, and output format letter. */
|
||||
|
||||
unsigned input_radix = 10;
|
||||
|
@ -74,14 +117,13 @@ int objectprint; /* Controls looking up an object's derived type
|
|||
|
||||
struct obstack dont_print_obstack;
|
||||
|
||||
static void cplus_val_print ();
|
||||
|
||||
/* Print the character string STRING, printing at most LENGTH characters.
|
||||
Printing stops early if the number hits print_max; repeat counts
|
||||
are printed as appropriate. Print ellipses at the end if we
|
||||
had to stop before printing LENGTH characters, or if FORCE_ELLIPSES. */
|
||||
|
||||
void
|
||||
static void
|
||||
print_string (stream, string, length, force_ellipses)
|
||||
FILE *stream;
|
||||
char *string;
|
||||
|
@ -286,7 +328,7 @@ int
|
|||
value_print (val, stream, format, pretty)
|
||||
value val;
|
||||
FILE *stream;
|
||||
char format;
|
||||
int format;
|
||||
enum val_prettyprint pretty;
|
||||
{
|
||||
register unsigned int i, n, typelen;
|
||||
|
@ -439,12 +481,13 @@ is_vtbl_member(type)
|
|||
|
||||
DONT_PRINT is an array of baseclass types that we
|
||||
should not print, or zero if called from top level. */
|
||||
|
||||
static void
|
||||
val_print_fields (type, valaddr, stream, format, recurse, pretty, dont_print)
|
||||
struct type *type;
|
||||
char *valaddr;
|
||||
FILE *stream;
|
||||
char format;
|
||||
int format;
|
||||
int recurse;
|
||||
enum val_prettyprint pretty;
|
||||
struct type **dont_print;
|
||||
|
@ -547,7 +590,7 @@ cplus_val_print (type, valaddr, stream, format, recurse, pretty, dont_print)
|
|||
struct type *type;
|
||||
char *valaddr;
|
||||
FILE *stream;
|
||||
char format;
|
||||
int format;
|
||||
int recurse;
|
||||
enum val_prettyprint pretty;
|
||||
struct type **dont_print;
|
||||
|
@ -634,13 +677,12 @@ cplus_val_print (type, valaddr, stream, format, recurse, pretty, dont_print)
|
|||
The PRETTY parameter controls prettyprinting. */
|
||||
|
||||
int
|
||||
val_print (type, valaddr, address, stream, format,
|
||||
deref_ref, recurse, pretty)
|
||||
val_print (type, valaddr, address, stream, format, deref_ref, recurse, pretty)
|
||||
struct type *type;
|
||||
char *valaddr;
|
||||
CORE_ADDR address;
|
||||
FILE *stream;
|
||||
char format;
|
||||
int format;
|
||||
int deref_ref;
|
||||
int recurse;
|
||||
enum val_prettyprint pretty;
|
||||
|
@ -927,10 +969,17 @@ val_print (type, valaddr, address, stream, format,
|
|||
slower if print_max is set high, e.g. if you set
|
||||
print_max to 1000, not only will it take a long
|
||||
time to fetch short strings, but if you are near
|
||||
the end of the address space, it might not work.
|
||||
FIXME. */
|
||||
the end of the address space, it might not work. */
|
||||
QUIT;
|
||||
errcode = target_read_memory (addr, string, print_max);
|
||||
if (errcode != 0)
|
||||
{
|
||||
/* Try reading just one character. If that succeeds,
|
||||
assume we hit the end of the address space, but
|
||||
the initial part of the string is probably safe. */
|
||||
char x[1];
|
||||
errcode = target_read_memory (addr, x, 1);
|
||||
}
|
||||
if (errcode != 0)
|
||||
force_ellipses = 0;
|
||||
else
|
||||
|
@ -974,13 +1023,12 @@ val_print (type, valaddr, address, stream, format,
|
|||
{
|
||||
CORE_ADDR vt_address = unpack_pointer (type, valaddr);
|
||||
|
||||
int vt_index = find_pc_misc_function (vt_address);
|
||||
if (vt_index >= 0
|
||||
&& vt_address == misc_function_vector[vt_index].address)
|
||||
struct minimal_symbol *msymbol =
|
||||
lookup_minimal_symbol_by_pc (vt_address);
|
||||
if ((msymbol != NULL) && (vt_address == msymbol -> address))
|
||||
{
|
||||
fputs_filtered (" <", stream);
|
||||
fputs_demangled (misc_function_vector[vt_index].name,
|
||||
stream, 1);
|
||||
fputs_demangled (msymbol -> name, stream, 1);
|
||||
fputs_filtered (">", stream);
|
||||
}
|
||||
if (vtblprint)
|
||||
|
@ -1698,7 +1746,7 @@ type_print_base (type, stream, show, level)
|
|||
struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);
|
||||
int j, len2 = TYPE_FN_FIELDLIST_LENGTH (type, i);
|
||||
char *method_name = TYPE_FN_FIELDLIST_NAME (type, i);
|
||||
int is_constructor = strcmp(method_name, TYPE_NAME (type)) == 0;
|
||||
int is_constructor = name && strcmp(method_name, name) == 0;
|
||||
for (j = 0; j < len2; j++)
|
||||
{
|
||||
QUIT;
|
||||
|
@ -1723,7 +1771,6 @@ type_print_base (type, stream, show, level)
|
|||
if (TYPE_FN_FIELD_STUB (f, j))
|
||||
{
|
||||
/* Build something we can demangle. */
|
||||
char *strchr (), *gdb_mangle_name (), *cplus_demangle ();
|
||||
char *mangled_name = gdb_mangle_name (type, i, j);
|
||||
char *demangled_name = cplus_demangle (mangled_name, 1);
|
||||
if (demangled_name == 0)
|
||||
|
@ -2011,7 +2058,7 @@ _initialize_valprint ()
|
|||
"Set default input and output number radix.",
|
||||
&setlist);
|
||||
add_show_from_set (c, &showlist);
|
||||
c->function = set_radix;
|
||||
c->function.sfunc = set_radix;
|
||||
|
||||
/* Give people the defaults which they are used to. */
|
||||
prettyprint = 0;
|
||||
|
|
29
gdb/values.c
29
gdb/values.c
|
@ -1124,6 +1124,8 @@ value_static_field (type, fieldname, fieldno)
|
|||
|
||||
if (fieldno < 0)
|
||||
{
|
||||
char **physnames;
|
||||
struct symbol **sym_arr;
|
||||
/* Look for static field. */
|
||||
int i;
|
||||
for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--)
|
||||
|
@ -1144,14 +1146,24 @@ value_static_field (type, fieldname, fieldno)
|
|||
return v;
|
||||
}
|
||||
|
||||
if (destructor_name_p (fieldname, type))
|
||||
error ("Cannot get value of destructor");
|
||||
|
||||
for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; i--)
|
||||
sym_arr = (struct symbol **)
|
||||
alloca(TYPE_NFN_FIELDS_TOTAL (type) * sizeof(struct symbol*));
|
||||
physnames = (char **)
|
||||
alloca (TYPE_NFN_FIELDS_TOTAL (type) * sizeof(char*));
|
||||
/* Note: This does duplicate work, since find_methods does a
|
||||
recursive search *and* so does value_static_field. FIXME */
|
||||
i = find_methods (type, fieldname, physnames, sym_arr);
|
||||
if (i > 1)
|
||||
error ("Cannot get value of overloaded method \"%s\"", fieldname);
|
||||
else if (i)
|
||||
{
|
||||
if (! strcmp (TYPE_FN_FIELDLIST_NAME (type, i), fieldname))
|
||||
error ("Cannot get value of method \"%s\"", fieldname);
|
||||
}
|
||||
struct symbol *sym = sym_arr[0];
|
||||
value val = read_var_value (sym, (FRAME) 0);
|
||||
if (val == 0)
|
||||
error ("Address of method \"%s\" is unknown (possibly inlined).",
|
||||
fieldname);
|
||||
return val;
|
||||
}
|
||||
error("there is no field named %s", fieldname);
|
||||
}
|
||||
|
||||
|
@ -1161,8 +1173,7 @@ value_static_field (type, fieldname, fieldno)
|
|||
if (! sym) error ("Internal error: could not find physical static variable named %s", phys_name);
|
||||
|
||||
type = TYPE_FIELD_TYPE (type, fieldno);
|
||||
v = value_at (type, (CORE_ADDR)SYMBOL_BLOCK_VALUE (sym));
|
||||
return v;
|
||||
return value_at (type, (CORE_ADDR)SYMBOL_BLOCK_VALUE (sym));
|
||||
}
|
||||
|
||||
/* Compute the address of the baseclass which is
|
||||
|
|
Loading…
Reference in New Issue