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:
Per Bothner 1992-03-19 00:05:35 +00:00
parent c976b3499c
commit 2cd9998540
4 changed files with 192 additions and 54 deletions

View File

@ -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.

View File

@ -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
@ -2104,10 +2175,10 @@ list_symbols (regexp, class, bpt)
else
{
QUIT;
/* 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 &&

View File

@ -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;

View File

@ -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