old-cross-binutils/gdb/c-valprint.c
Fred Fish 2e4964adfc * defs.h (STRCMP, STREQ, STREQN): New macros.
* defs.h (demangle_and_match):  Remove prototype.
	* dwarfread.c (STREQ, STREQN):  Remove macros, replaced with STREQ
	  and STREQN defined in defs.h.
	* dwarfread.c (set_cu_language):  For completely unknown languages,
	  try to deduce the language from the filename.  Retain behavior
	  that for known languages we don't know how to handle, we use
	  language_unknown.
	* dwarfread.c (enum_type, symthesize_typedef):  Initialize language
	  and demangled name fields in symbol.
	* dwarfread.c, mipsread.c, partial-stab.h:  For all usages of
	  ADD_PSYMBOL_TO_LIST, add language and objfile parameters.
	* dwarfread.c (new_symbol):  Attempt to demangle C++ symbol names
	  and cache the results in SYMBOL_DEMANGLED_NAME for the symbol.
	* elfread.c (STREQ):  Remove macro, use STREQ defined in defs.h.
	  Replace usages throughout.
	* elfread.c (demangle.h):  Include.
	* elfread.c (record_minimal_symbol):  Remove prototype and function.
	* gdbtypes.h, symtab.h (B_SET, B_CLR, B_TST, B_TYPE, B_BYTES,
	  B_CLRALL):  Moved from symtab.h to gdbtypes.h.
	* infcmd.c (jump_command):  Remove code to demangle name and add
	  it to a cleanup list.  Now just use SYMBOL_DEMANGLED_NAME.
	* minsyms.c (demangle.h):  Include.
	* minsyms.c (lookup_minimal_symbol):  Indent comment to match code.
	* minsyms.c (install_minimal_symbols):  Attempt to demangle symbol
	  names as C++ names, and cache them in SYMBOL_DEMANGLED_NAME.
	* mipsread.c (psymtab_language):  Add static variable.
	* stabsread.c (demangle.h):  Include.
	* stabsread.c (define_symbol):  Attempt to demangle C++ symbol
	  names and cache them in the SYMBOL_DEMANGLED_NAME field.
	* stack.c (return_command):  Remove explicit demangling of name
	  and use of cleanups.  Just use SYMBOL_DEMANGLED_NAME.
	* symfile.c (demangle.h):  Include.
	* symfile.c (add_psymbol_to_list, add_psymbol_addr_to_list):  Fix
	  to match macros in symfile.h and allow them to be compiled
	  if INLINE_ADD_PSYMBOL is not true.
	* symfile.h (INLINE_ADD_PSYMBOL):  Default to true if not set.
	* symfile.h (ADD_PSYMBOL_*):  Add language and objfile parameters.
	  Add code to demangle and cache C++ symbol names.  Use macro form
	  if INLINE_ADD_PSYMBOL is true, otherwise use C function form.
	* symmisc.c (add_psymbol_to_list, add_psymbol_addr_to_list):
	  Remove, also defined in symfile.c, which we already fixed.
	* symtab.c (expensive_mangler):  Remove prototype and function.
	* symtab.c (find_methods):  Remove physnames parameter and fix
	  prototype to match.
	* symtab.c (completion_list_add_symbol):  Name changed to
	  completion_list_add_name.
	* symtab.c (COMPLETION_LIST_ADD_SYMBOL):  New macro, adds both
	  the normal symbol name and the cached C++ demangled name.
	* symtab.c (lookup_demangled_partial_symbol,
	  lookup_demangled_block_symbol):  Remove prototypes and functions.
	* symtab.c (lookup_symbol):  Remove use of expensive_mangler,
	  use lookup_block_symbol instead of lookup_demangled_block_symbol.
	  Remove code to try demangling names and matching them.
	* symtab.c (lookup_partial_symbol, lookup_block_symbol):
	  Fix to try matching the cached demangled name if no match is
	  found using the regular symbol name.
	* symtab.c (find_methods):  Remove unused physnames array.
	* symtab.c (name_match, NAME_MATCH):  Remove function and macro,
	  replaced with SYMBOL_MATCHES_REGEXP from symtab.h.
	* symtab.c (completion_list_add_symbol):  Rewrite to use cached
	  C++ demangled symbol names.
	* symtab.h:  Much reformatting of structures and such to add
	  whitespace to make them more readable, and make them more
	  consistent with other gdb structure definitions.
	* symtab.h (general_symbol_info): New struct containing fields
	  common to all symbols.
	* symtab.h (SYMBOL_LANGUAGE, SYMBOL_DEMANGLED_NAME,
	  SYMBOL_SOURCE_NAME, SYMBOL_LINKAGE_NAME, SYMBOL_MATCHES_NAME,
	  SYMBOL_MATCHES_REGEXP, MSYMBOL_INFO, MSYMBOL_TYPE):  New macros.
	* symtab. (struct minimal_symbol, struct partial_symbol, struct
	  symbol): Use general_symbol_info struct.
	* utils.c (demangle_and_match):  Remove, no longer used.
	* valops.c (demangle.h):  Include.
	* xcoffexec.c (eq):  Remove macro, replace usages with STREQ.
	* blockframe.c, breakpoint.c, c-exp.y, c-valprint.c, dbxread.c,
	  infcmd.c, m2-exp.y, minsyms.c, objfiles.h, solib.c, stack.c,
	  symmisc.c, symtab.c, valops.c:  Replace references to minimal
	  symbol fields with appropriate macros.
	* breakpoint.c, buildsym.c, c-exp.y, c-typeprint.c, c-valprint.c,
	  coffread.c, command.c, convex-tdep.c, cp-valprint.c, dbxread.c,
	  demangle.c, elfread.c, energize.c, environ.c, exec.c,
	  gdbtypes.c, i960-tdep.c, infrun.c, infrun-hacked.c, language.c,
	  main.c, minsyms.c, mipsread.c, partial-stab.h, remote-es1800.c,
	  remote-nindy.c, remote-udi.c, rs6000-tdep.c, solib.c, source.c,
	  sparc-pinsn.c, stabsread.c, standalone.c, state.c, stuff.c,
	  symfile.c, symmisc.c, symtab.c, symtab.h, tm-sysv4.h,
	  tm-ultra3.h, values.c, xcoffexec.c, xcoffread.c:  Replace strcmp
	  and strncmp usages with STREQ, STREQN, or STRCMP as appropriate.
	* breakpoint.c, buildsym.c, c-typeprint.c, expprint.c, findvar.c,
	  mipsread.c, printcmd.c, source.c, stabsread.c, stack.c,
	  symmisc.c, tm-29k.h, valops.c, values.c:  Replace SYMBOL_NAME
	  references with SYMBOL_SOURCE_NAME or SYMBOL_LINKAGE_NAME as
	  appropriate.
	* buildsym.c (start_subfile, patch_subfile_names):  Default the
	  source language to what can be deduced from the filename.
	* buildsym.c (end_symtab):  Update the source language in the
	  allocated symtab to match what we have been using.
	* buildsym.h (struct subfile):  Add a language field.
	* c-typeprint.c (c_print_type):  Remove code to do explicit
	  demangling.
	* dbxread.c (psymtab_language):  Add static variable.
	* dbxread.c (start_psymtab):  Initialize psymtab_language using
	  deduce_language_from_filename.
1992-12-23 06:34:57 +00:00

542 lines
14 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* Support for printing C values for GDB, the GNU debugger.
Copyright 1986, 1988, 1989, 1991 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
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 "defs.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "expression.h"
#include "value.h"
#include "demangle.h"
#include "valprint.h"
#include "language.h"
/* BEGIN-FIXME */
extern int vtblprint; /* Controls printing of vtbl's */
extern int demangle; /* whether to print C++ syms raw or src-form */
extern void
cp_print_class_member PARAMS ((char *, struct type *, FILE *, char *));
extern int
cp_is_vtbl_ptr_type PARAMS ((struct type *));
extern void
cp_print_value_fields PARAMS ((struct type *, char *, FILE *, int, int,
enum val_prettyprint, struct type **));
extern int
cp_is_vtbl_member PARAMS ((struct type *));
/* END-FIXME */
/* BEGIN-FIXME: Hooks into c-typeprint.c */
extern void
c_type_print_varspec_prefix PARAMS ((struct type *, FILE *, int, int));
extern void
cp_type_print_method_args PARAMS ((struct type **, char *, char *, int,
FILE *));
/* END-FIXME */
extern struct obstack dont_print_obstack;
/* Print data of type TYPE located at VALADDR (within GDB), which came from
the inferior at address ADDRESS, onto stdio stream STREAM according to
FORMAT (a letter or 0 for natural format). The data at VALADDR is in
target byte order.
If the data are a string pointer, returns the number of string characters
printed.
If DEREF_REF is nonzero, then dereference references, otherwise just print
them like pointers.
The PRETTY parameter controls prettyprinting. */
int
c_val_print (type, valaddr, address, stream, format, deref_ref, recurse,
pretty)
struct type *type;
char *valaddr;
CORE_ADDR address;
FILE *stream;
int format;
int deref_ref;
int recurse;
enum val_prettyprint pretty;
{
register unsigned int i;
unsigned len;
struct type *elttype;
unsigned eltlen;
LONGEST val;
unsigned char c;
switch (TYPE_CODE (type))
{
case TYPE_CODE_ARRAY:
if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0)
{
elttype = TYPE_TARGET_TYPE (type);
eltlen = TYPE_LENGTH (elttype);
len = TYPE_LENGTH (type) / eltlen;
if (prettyprint_arrays)
{
print_spaces_filtered (2 + 2 * recurse, stream);
}
fprintf_filtered (stream, "{");
/* For an array of chars, print with string syntax. */
if (eltlen == 1 && TYPE_CODE (elttype) == TYPE_CODE_INT
&& (format == 0 || format == 's') )
{
LA_PRINT_STRING (stream, valaddr, len, 0);
}
else
{
/* If this is a virtual function table, print the 0th
entry specially, and the rest of the members normally. */
if (cp_is_vtbl_ptr_type (elttype))
{
i = 1;
fprintf_filtered (stream, "%d vtable entries", len - 1);
}
else
{
i = 0;
}
val_print_array_elements (type, valaddr, address, stream,
format, deref_ref, recurse, pretty, i);
}
fprintf_filtered (stream, "}");
break;
}
/* Array of unspecified length: treat like pointer to first elt. */
valaddr = (char *) &address;
case TYPE_CODE_PTR:
if (format && format != 's')
{
print_scalar_formatted (valaddr, type, format, 0, stream);
break;
}
if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_METHOD)
{
struct type *domain = TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type));
struct fn_field *f;
int j, len2;
char *kind = "";
CORE_ADDR addr;
addr = unpack_pointer (lookup_pointer_type (builtin_type_void),
valaddr);
if (METHOD_PTR_IS_VIRTUAL(addr))
{
int offset = METHOD_PTR_TO_VOFFSET(addr);
len = TYPE_NFN_FIELDS (domain);
for (i = 0; i < len; i++)
{
f = TYPE_FN_FIELDLIST1 (domain, i);
len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
for (j = 0; j < len2; j++)
{
QUIT;
if (TYPE_FN_FIELD_VOFFSET (f, j) == offset)
{
kind = "virtual ";
goto common;
}
}
}
}
else
{
struct symbol *sym = find_pc_function (addr);
if (sym == 0)
{
error ("invalid pointer to member function");
}
len = TYPE_NFN_FIELDS (domain);
for (i = 0; i < len; i++)
{
f = TYPE_FN_FIELDLIST1 (domain, i);
len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
for (j = 0; j < len2; j++)
{
QUIT;
if (STREQ (SYMBOL_NAME (sym),
TYPE_FN_FIELD_PHYSNAME (f, j)))
{
goto common;
}
}
}
}
common:
if (i < len)
{
fprintf_filtered (stream, "&");
c_type_print_varspec_prefix (TYPE_FN_FIELD_TYPE (f, j), stream, 0, 0);
fprintf (stream, kind);
if (TYPE_FN_FIELD_PHYSNAME (f, j)[0] == '_'
&& TYPE_FN_FIELD_PHYSNAME (f, j)[1] == CPLUS_MARKER)
cp_type_print_method_args (TYPE_FN_FIELD_ARGS (f, j) + 1, "~",
TYPE_FN_FIELDLIST_NAME (domain, i),
0, stream);
else
cp_type_print_method_args (TYPE_FN_FIELD_ARGS (f, j), "",
TYPE_FN_FIELDLIST_NAME (domain, i),
0, stream);
break;
}
fprintf_filtered (stream, "(");
type_print (type, "", stream, -1);
fprintf_filtered (stream, ") %d", (int) addr >> 3);
}
else if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_MEMBER)
{
cp_print_class_member (valaddr,
TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type)),
stream, "&");
}
else
{
CORE_ADDR addr = unpack_pointer (type, valaddr);
elttype = TYPE_TARGET_TYPE (type);
if (TYPE_CODE (elttype) == TYPE_CODE_FUNC)
{
/* Try to print what function it points to. */
print_address_demangle (addr, stream, demangle);
/* Return value is irrelevant except for string pointers. */
return (0);
}
if (addressprint && format != 's')
{
fprintf_filtered (stream, "0x%x", addr);
}
/* For a pointer to char or unsigned char, also print the string
pointed to, unless pointer is null. */
i = 0; /* Number of characters printed. */
if (TYPE_LENGTH (elttype) == 1 &&
TYPE_CODE (elttype) == TYPE_CODE_INT &&
(format == 0 || format == 's') &&
addr != 0 &&
/* If print_max is UINT_MAX, the alloca below will fail.
In that case don't try to print the string. */
print_max < UINT_MAX)
{
int first_addr_err = 0;
int errcode = 0;
/* Get first character. */
errcode = target_read_memory (addr, (char *)&c, 1);
if (errcode != 0)
{
/* First address out of bounds. */
first_addr_err = 1;
}
else
{
/* A real string. */
char *string = (char *) alloca (print_max);
/* If the loop ends by us hitting print_max characters,
we need to have elipses at the end. */
int force_ellipses = 1;
/* This loop always fetches print_max characters, even
though LA_PRINT_STRING might want to print more or fewer
(with repeated characters). This is so that
we don't spend forever fetching if we print
a long string consisting of the same character
repeated. Also so we can do it all in one memory
operation, which is faster. However, this will be
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. */
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
for (i = 0; i < print_max; i++)
if (string[i] == '\0')
{
force_ellipses = 0;
break;
}
QUIT;
if (addressprint)
{
fputs_filtered (" ", stream);
}
LA_PRINT_STRING (stream, string, i, force_ellipses);
}
if (errcode != 0)
{
if (errcode == EIO)
{
fprintf_filtered (stream,
(" <Address 0x%x out of bounds>" +
first_addr_err),
addr + i);
}
else
{
error ("Error reading memory address 0x%x: %s.",
addr + i, safe_strerror (errcode));
}
}
fflush (stream);
}
else if (cp_is_vtbl_member(type))
{
/* print vtbl's nicely */
CORE_ADDR vt_address = unpack_pointer (type, valaddr);
struct minimal_symbol *msymbol =
lookup_minimal_symbol_by_pc (vt_address);
if ((msymbol != NULL) &&
(vt_address == SYMBOL_VALUE_ADDRESS (msymbol)))
{
fputs_filtered (" <", stream);
fputs_filtered (SYMBOL_SOURCE_NAME (msymbol), stream);
fputs_filtered (">", stream);
}
if (vtblprint)
{
value vt_val;
vt_val = value_at (TYPE_TARGET_TYPE (type), vt_address);
val_print (VALUE_TYPE (vt_val), VALUE_CONTENTS (vt_val),
VALUE_ADDRESS (vt_val), stream, format,
deref_ref, recurse + 1, pretty);
if (pretty)
{
fprintf_filtered (stream, "\n");
print_spaces_filtered (2 + 2 * recurse, stream);
}
}
}
/* Return number of characters printed, plus one for the
terminating null if we have "reached the end". */
return (i + (print_max && i != print_max));
}
break;
case TYPE_CODE_MEMBER:
error ("not implemented: member type in c_val_print");
break;
case TYPE_CODE_REF:
if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_MEMBER)
{
cp_print_class_member (valaddr,
TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type)),
stream, "");
break;
}
if (addressprint)
{
fprintf_filtered (stream, "@0x%lx",
unpack_long (builtin_type_int, valaddr));
if (deref_ref)
fputs_filtered (": ", stream);
}
/* De-reference the reference. */
if (deref_ref)
{
if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_UNDEF)
{
value deref_val =
value_at
(TYPE_TARGET_TYPE (type),
unpack_pointer (lookup_pointer_type (builtin_type_void),
valaddr));
val_print (VALUE_TYPE (deref_val),
VALUE_CONTENTS (deref_val),
VALUE_ADDRESS (deref_val), stream, format,
deref_ref, recurse + 1, pretty);
}
else
fputs_filtered ("???", stream);
}
break;
case TYPE_CODE_UNION:
if (recurse && !unionprint)
{
fprintf_filtered (stream, "{...}");
break;
}
/* Fall through. */
case TYPE_CODE_STRUCT:
if (vtblprint && cp_is_vtbl_ptr_type(type))
{
/* Print the unmangled name if desired. */
print_address_demangle(*((int *) (valaddr + /* FIXME bytesex */
TYPE_FIELD_BITPOS (type, VTBL_FNADDR_OFFSET) / 8)),
stream, demangle);
break;
}
cp_print_value_fields (type, valaddr, stream, format, recurse, pretty,
0);
break;
case TYPE_CODE_ENUM:
if (format)
{
print_scalar_formatted (valaddr, type, format, 0, stream);
break;
}
len = TYPE_NFIELDS (type);
val = unpack_long (builtin_type_int, valaddr);
for (i = 0; i < len; i++)
{
QUIT;
if (val == TYPE_FIELD_BITPOS (type, i))
{
break;
}
}
if (i < len)
{
fputs_filtered (TYPE_FIELD_NAME (type, i), stream);
}
else
{
#ifdef LONG_LONG
fprintf_filtered (stream, "%lld", val);
#else
fprintf_filtered (stream, "%ld", val);
#endif
}
break;
case TYPE_CODE_FUNC:
if (format)
{
print_scalar_formatted (valaddr, type, format, 0, stream);
break;
}
/* FIXME, we should consider, at least for ANSI C language, eliminating
the distinction made between FUNCs and POINTERs to FUNCs. */
fprintf_filtered (stream, "{");
type_print (type, "", stream, -1);
fprintf_filtered (stream, "} ");
/* Try to print what function it points to, and its address. */
print_address_demangle (address, stream, demangle);
break;
case TYPE_CODE_INT:
format = format ? format : output_format;
if (format)
{
print_scalar_formatted (valaddr, type, format, 0, stream);
}
else
{
val_print_type_code_int (type, valaddr, stream);
/* C and C++ has no single byte int type, char is used instead.
Since we don't know whether the value is really intended to
be used as an integer or a character, print the character
equivalent as well. */
if (TYPE_LENGTH (type) == 1)
{
fputs_filtered (" ", stream);
LA_PRINT_CHAR ((unsigned char) unpack_long (type, valaddr),
stream);
}
}
break;
case TYPE_CODE_CHAR:
format = format ? format : output_format;
if (format)
{
print_scalar_formatted (valaddr, type, format, 0, stream);
}
else
{
fprintf_filtered (stream, TYPE_UNSIGNED (type) ? "%u" : "%d",
unpack_long (type, valaddr));
fputs_filtered (" ", stream);
LA_PRINT_CHAR ((unsigned char) unpack_long (type, valaddr), stream);
}
break;
case TYPE_CODE_FLT:
if (format)
{
print_scalar_formatted (valaddr, type, format, 0, stream);
}
else
{
print_floating (valaddr, type, stream);
}
break;
case TYPE_CODE_VOID:
fprintf_filtered (stream, "void");
break;
case TYPE_CODE_ERROR:
fprintf_filtered (stream, "<error type>");
break;
case TYPE_CODE_RANGE:
/* FIXME, we should not ever have to print one of these yet. */
fprintf_filtered (stream, "<range type>");
break;
case TYPE_CODE_UNDEF:
/* This happens (without TYPE_FLAG_STUB set) on systems which don't use
dbx xrefs (NO_DBX_XREFS in gcc) if a file has a "struct foo *bar"
and no complete type for struct foo in that file. */
fprintf_filtered (stream, "<incomplete type>");
break;
default:
error ("Invalid C/C++ type code %d in symbol table.", TYPE_CODE (type));
}
fflush (stream);
return (0);
}