aboutsummaryrefslogtreecommitdiff
path: root/gdb/values.c
diff options
context:
space:
mode:
authorgdb-2.5.1 <gdb@fsf.org>1988-05-02 01:00:00 +0100
committerPedro Alves <palves@redhat.com>2012-06-03 15:36:30 +0100
commit632ea0ccc5c4c3f9fc06881bfedfc4b075873941 (patch)
tree96f152433c41c5f51fe57307b287eb85865a43e2 /gdb/values.c
parent7b4ac7e1ed2c4616bce56d1760807798be87ac9e (diff)
downloadgdb-632ea0ccc5c4c3f9fc06881bfedfc4b075873941.zip
gdb-632ea0ccc5c4c3f9fc06881bfedfc4b075873941.tar.gz
gdb-632ea0ccc5c4c3f9fc06881bfedfc4b075873941.tar.bz2
gdb-2.5.1
Diffstat (limited to 'gdb/values.c')
-rw-r--r--gdb/values.c108
1 files changed, 103 insertions, 5 deletions
diff --git a/gdb/values.c b/gdb/values.c
index 9af5d96..93d9482 100644
--- a/gdb/values.c
+++ b/gdb/values.c
@@ -424,7 +424,12 @@ value_as_double (val)
/* Unpack raw data (copied from debugee) at VALADDR
as a long, or as a double, assuming the raw data is described
by type TYPE. Knows how to convert different sizes of values
- and can convert between fixed and floating point. */
+ and can convert between fixed and floating point.
+
+ C++: It is assumed that the front-end has taken care of
+ all matters concerning pointers to members. A pointer
+ to member which reaches here is considered to be equivalent
+ to an INT (or some size). After all, it is only an offset. */
long
unpack_long (type, valaddr)
@@ -459,7 +464,8 @@ unpack_long (type, valaddr)
if (len == sizeof (long))
return * (unsigned long *) valaddr;
}
- else if (code == TYPE_CODE_INT)
+ else if (code == TYPE_CODE_INT
+ || code == TYPE_CODE_MPTR)
{
if (len == sizeof (char))
return * (char *) valaddr;
@@ -473,12 +479,12 @@ unpack_long (type, valaddr)
if (len == sizeof (long))
return * (long *) valaddr;
}
- else if (code == TYPE_CODE_PTR)
+ else if (code == TYPE_CODE_PTR
+ || code == TYPE_CODE_REF)
{
if (len == sizeof (char *))
return (CORE_ADDR) * (char **) valaddr;
}
-
error ("Value not integer or pointer.");
}
@@ -536,7 +542,9 @@ unpack_double (type, valaddr)
/* Given a value ARG1 of a struct or union type,
extract and return the value of one of its fields.
- FIELDNO says which field. */
+ FIELDNO says which field.
+
+ For C++, must also be able to return values from static fields */
value
value_field (arg1, fieldno)
@@ -574,6 +582,96 @@ value_field (arg1, fieldno)
return v;
}
+value
+value_fn_field (arg1, fieldno, subfieldno)
+ register value arg1;
+ register int fieldno;
+{
+ register value v;
+ struct fn_field *f = TYPE_FN_FIELDLIST1 (VALUE_TYPE (arg1), fieldno);
+ register struct type *type = TYPE_FN_FIELD_TYPE (f, subfieldno);
+ struct symbol *sym;
+
+ sym = lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, subfieldno),
+ 0, VAR_NAMESPACE);
+ if (! sym) error ("Internal error: could not find physical method named %s",
+ TYPE_FN_FIELD_PHYSNAME (f, subfieldno));
+
+ v = allocate_value (type);
+ VALUE_ADDRESS (v) = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
+ VALUE_TYPE (v) = type;
+ return v;
+}
+
+/* The value of a static class member does not depend
+ on its instance, only on its type. If FIELDNO >= 0,
+ then fieldno is a valid field number and is used directly.
+ Otherwise, FIELDNAME is the name of the field we are
+ searching for. If it is not a static field name, an
+ error is signaled. TYPE is the type in which we look for the
+ static field member. */
+value
+value_static_field (type, fieldname, fieldno)
+ register struct type *type;
+ char *fieldname;
+ register int fieldno;
+{
+ register value v;
+ struct symbol *sym;
+
+ if (fieldno < 0)
+ {
+ register struct type *t = type;
+ /* Look for static field. */
+ while (t)
+ {
+ int i;
+ for (i = TYPE_NFIELDS (t) - 1; i >= 0; i--)
+ if (! strcmp (TYPE_FIELD_NAME (t, i), fieldname))
+ {
+ if (TYPE_FIELD_STATIC (t, i))
+ {
+ fieldno = i;
+ goto found;
+ }
+ else
+ error ("field `%s' is not static");
+ }
+ t = TYPE_BASECLASS (t);
+ }
+
+ t = type;
+
+ if (destructor_name_p (fieldname, t))
+ error ("use `info method' command to print out value of destructor");
+
+ while (t)
+ {
+ int i, j;
+
+ for (i = TYPE_NFN_FIELDS (t) - 1; i >= 0; i--)
+ {
+ if (! strcmp (TYPE_FN_FIELDLIST_NAME (t, i), fieldname))
+ {
+ error ("use `info method' command to print value of method \"%s\"", fieldname);
+ }
+ }
+ t = TYPE_BASECLASS (t);
+ }
+ error("there is no field named %s", fieldname);
+ }
+
+ found:
+
+ sym = lookup_symbol (TYPE_FIELD_STATIC_PHYSNAME (type, fieldno),
+ 0, VAR_NAMESPACE);
+ if (! sym) error ("Internal error: could not find physical static variable named %s", TYPE_FIELD_BITSIZE (type, fieldno));
+
+ type = TYPE_FIELD_TYPE (type, fieldno);
+ v = value_at (type, (CORE_ADDR)SYMBOL_BLOCK_VALUE (sym));
+ return v;
+}
+
long
unpack_field_as_long (type, valaddr, fieldno)
struct type *type;