#include "value.h"
#include "command.h"
#include "gdbcmd.h"
+#include "demangle.h"
int vtblprint; /* Controls printing of vtbl's */
int objectprint; /* Controls looking up an object's derived type
struct obstack dont_print_obstack;
static void
-cplus_print_value PARAMS ((struct type *, char *, FILE *, int, int,
+cplus_print_value PARAMS ((struct type *, char *, GDB_FILE *, int, int,
enum val_prettyprint, struct type **));
/* BEGIN-FIXME: Hooks into typeprint.c, find a better home for prototypes. */
extern void
-c_type_print_base PARAMS ((struct type *, FILE *, int, int));
+c_type_print_base PARAMS ((struct type *, GDB_FILE *, int, int));
extern void
-c_type_print_varspec_prefix PARAMS ((struct type *, FILE *, int, int));
+c_type_print_varspec_prefix PARAMS ((struct type *, GDB_FILE *, int, int));
extern void
cp_type_print_method_args PARAMS ((struct type **, char *, char *, int,
- FILE *));
+ GDB_FILE *));
extern struct obstack dont_print_obstack;
/* END-FIXME */
-
-/* BEGIN-FIXME: Hooks into c-valprint.c */
-
-extern int
-c_val_print PARAMS ((struct type *, char *, CORE_ADDR, FILE *, int, int, int,
- enum val_prettyprint));
-/* END-FIXME */
-
+void
+cp_print_class_method (valaddr, type, stream)
+ char *valaddr;
+ struct type *type;
+ GDB_FILE *stream;
+{
+ struct type *domain;
+ struct fn_field *f = NULL;
+ int j = 0;
+ int len2;
+ int offset;
+ char *kind = "";
+ CORE_ADDR addr;
+ struct symbol *sym;
+ unsigned len;
+ unsigned int i;
+
+ check_stub_type (TYPE_TARGET_TYPE (type));
+ domain = TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type));
+ if (domain == (struct type *)NULL)
+ {
+ fprintf_filtered (stream, "<unknown>");
+ return;
+ }
+ addr = unpack_pointer (lookup_pointer_type (builtin_type_void), valaddr);
+ if (METHOD_PTR_IS_VIRTUAL (addr))
+ {
+ 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
+ {
+ 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 (TYPE_FN_FIELD_STUB (f, j))
+ check_stub_method (domain, i, j);
+ 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_unfiltered (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);
+ }
+ }
+ else
+ {
+ fprintf_filtered (stream, "(");
+ type_print (type, "", stream, -1);
+ fprintf_filtered (stream, ") %d", (int) addr >> 3);
+ }
+}
/* Return truth value for assertion that TYPE is of the type
"pointer to virtual function". */
struct type *type;
{
char *typename = type_name_no_tag (type);
- static const char vtbl_ptr_name[] =
+ /* This was what it was for gcc 2.4.5 and earlier. */
+ static const char vtbl_ptr_name_old[] =
{ CPLUS_MARKER,'v','t','b','l','_','p','t','r','_','t','y','p','e', 0 };
+ /* It was changed to this after 2.4.5. */
+ static const char vtbl_ptr_name[] =
+ { '_','_','v','t','b','l','_','p','t','r','_','t','y','p','e', 0 };
- return (typename != NULL && !strcmp(typename, vtbl_ptr_name));
+ return (typename != NULL
+ && (STREQ (typename, vtbl_ptr_name)
+ || STREQ (typename, vtbl_ptr_name_old)));
}
/* Return truth value for the assertion that TYPE is of the type
dont_print)
struct type *type;
char *valaddr;
- FILE *stream;
+ GDB_FILE *stream;
int format;
int recurse;
enum val_prettyprint pretty;
fputs_filtered ("\"( ptr \"", stream);
else
fputs_filtered ("\"( nodef \"", stream);
- fprint_symbol (stream, TYPE_FIELD_NAME (type, i));
+ fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
+ language_cplus,
+ DMGL_PARAMS | DMGL_ANSI);
fputs_filtered ("\" \"", stream);
- fprint_symbol (stream, TYPE_FIELD_NAME (type, i));
+ fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
+ language_cplus,
+ DMGL_PARAMS | DMGL_ANSI);
fputs_filtered ("\") \"", stream);
}
else
{
- fprint_symbol (stream, TYPE_FIELD_NAME (type, i));
+ fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i),
+ language_cplus,
+ DMGL_PARAMS | DMGL_ANSI);
fputs_filtered (" = ", stream);
}
if (TYPE_FIELD_PACKED (type, i))
/* Bitfields require special handling, especially due to byte
order problems. */
- v = value_from_longest (TYPE_FIELD_TYPE (type, i),
+ if (TYPE_FIELD_IGNORE (type, i))
+ {
+ fputs_filtered ("<optimized out or zero length>", stream);
+ }
+ else
+ {
+ v = value_from_longest (TYPE_FIELD_TYPE (type, i),
unpack_field_as_long (type, valaddr, i));
- c_val_print (TYPE_FIELD_TYPE (type, i), VALUE_CONTENTS (v), 0,
- stream, format, 0, recurse + 1, pretty);
+ val_print (TYPE_FIELD_TYPE(type, i), VALUE_CONTENTS (v), 0,
+ stream, format, 0, recurse + 1, pretty);
+ }
}
else
{
- c_val_print (TYPE_FIELD_TYPE (type, i),
- valaddr + TYPE_FIELD_BITPOS (type, i) / 8,
- 0, stream, format, 0, recurse + 1, pretty);
+ if (TYPE_FIELD_IGNORE (type, i))
+ {
+ fputs_filtered ("<optimized out or zero length>", stream);
+ }
+ else
+ {
+ val_print (TYPE_FIELD_TYPE (type, i),
+ valaddr + TYPE_FIELD_BITPOS (type, i) / 8,
+ 0, stream, format, 0, recurse + 1, pretty);
+ }
}
}
if (pretty)
cplus_print_value (type, valaddr, stream, format, recurse, pretty, dont_print)
struct type *type;
char *valaddr;
- FILE *stream;
+ GDB_FILE *stream;
int format;
int recurse;
enum val_prettyprint pretty;
for (i = 0; i < n_baseclasses; i++)
{
+ /* FIXME-32x64--assumes that a target pointer can fit in a char *.
+ Fix it by nuking baseclass_addr. */
char *baddr;
int err;
+ char *basename;
+
+ check_stub_type (TYPE_BASECLASS (type, i));
+ basename = TYPE_NAME (TYPE_BASECLASS (type, i));
if (BASETYPE_VIA_VIRTUAL (type, i))
{
/* Fix to use baseclass_offset instead. FIXME */
baddr = baseclass_addr (type, i, valaddr, 0, &err);
if (err == 0 && baddr == 0)
- error ("could not find virtual baseclass `%s'\n",
- type_name_no_tag (TYPE_BASECLASS (type, i)));
+ error ("could not find virtual baseclass %s\n",
+ basename ? basename : "");
if (pretty)
{
print_spaces_filtered (2 * recurse, stream);
}
fputs_filtered ("<", stream);
- fputs_filtered (type_name_no_tag (TYPE_BASECLASS (type, i)), stream);
+ /* Not sure what the best notation is in the case where there is no
+ baseclass name. */
+ fputs_filtered (basename ? basename : "", stream);
fputs_filtered ("> = ", stream);
if (err != 0)
- fprintf_filtered (stream, "<invalid address 0x%x>", baddr);
+ {
+ fprintf_filtered (stream, "<invalid address ");
+ print_address_numeric ((CORE_ADDR) baddr, stream);
+ fprintf_filtered (stream, ">");
+ }
else
cp_print_value_fields (TYPE_BASECLASS (type, i), baddr, stream, format,
recurse, pretty,
cp_print_class_member (valaddr, domain, stream, prefix)
char *valaddr;
struct type *domain;
- FILE *stream;
+ GDB_FILE *stream;
char *prefix;
{