Index: gdb/value.c |
diff --git a/gdb/value.c b/gdb/value.c |
index 2a210d75a53e8aca081b131d8164f5789c8bb14e..218d4d5cbadf035deac53abf00cd8fe40233fb3c 100644 |
--- a/gdb/value.c |
+++ b/gdb/value.c |
@@ -41,6 +41,7 @@ |
#include "python/python.h" |
#include <ctype.h> |
#include "tracepoint.h" |
+#include "cp-abi.h" |
/* Prototypes for exported functions. */ |
@@ -167,6 +168,9 @@ ranges_contain (VEC(range_s) *ranges, int offset, int length) |
static struct cmd_list_element *functionlist; |
+/* Note that the fields in this structure are arranged to save a bit |
+ of memory. */ |
+ |
struct value |
{ |
/* Type of value; either not an lval, or one of the various |
@@ -174,7 +178,37 @@ struct value |
enum lval_type lval; |
/* Is it modifiable? Only relevant if lval != not_lval. */ |
- int modifiable; |
+ unsigned int modifiable : 1; |
+ |
+ /* If zero, contents of this value are in the contents field. If |
+ nonzero, contents are in inferior. If the lval field is lval_memory, |
+ the contents are in inferior memory at location.address plus offset. |
+ The lval field may also be lval_register. |
+ |
+ WARNING: This field is used by the code which handles watchpoints |
+ (see breakpoint.c) to decide whether a particular value can be |
+ watched by hardware watchpoints. If the lazy flag is set for |
+ some member of a value chain, it is assumed that this member of |
+ the chain doesn't need to be watched as part of watching the |
+ value itself. This is how GDB avoids watching the entire struct |
+ or array when the user wants to watch a single struct member or |
+ array element. If you ever change the way lazy flag is set and |
+ reset, be sure to consider this use as well! */ |
+ unsigned int lazy : 1; |
+ |
+ /* If nonzero, this is the value of a variable which does not |
+ actually exist in the program. */ |
+ unsigned int optimized_out : 1; |
+ |
+ /* If value is a variable, is it initialized or not. */ |
+ unsigned int initialized : 1; |
+ |
+ /* If value is from the stack. If this is set, read_stack will be |
+ used instead of read_memory to enable extra caching. */ |
+ unsigned int stack : 1; |
+ |
+ /* If the value has been released. */ |
+ unsigned int released : 1; |
/* Location of value (if lval). */ |
union |
@@ -215,6 +249,13 @@ struct value |
gdbarch_bits_big_endian=1 targets, it is the position of the MSB. */ |
int bitpos; |
+ /* The number of references to this value. When a value is created, |
+ the value chain holds a reference, so REFERENCE_COUNT is 1. If |
+ release_value is called, this value is removed from the chain but |
+ the caller of release_value now has a reference to this value. |
+ The caller must arrange for a call to value_free later. */ |
+ int reference_count; |
+ |
/* Only used for bitfields; the containing value. This allows a |
single read from the target when displaying multiple |
bitfields. */ |
@@ -280,33 +321,6 @@ struct value |
/* Register number if the value is from a register. */ |
short regnum; |
- /* If zero, contents of this value are in the contents field. If |
- nonzero, contents are in inferior. If the lval field is lval_memory, |
- the contents are in inferior memory at location.address plus offset. |
- The lval field may also be lval_register. |
- |
- WARNING: This field is used by the code which handles watchpoints |
- (see breakpoint.c) to decide whether a particular value can be |
- watched by hardware watchpoints. If the lazy flag is set for |
- some member of a value chain, it is assumed that this member of |
- the chain doesn't need to be watched as part of watching the |
- value itself. This is how GDB avoids watching the entire struct |
- or array when the user wants to watch a single struct member or |
- array element. If you ever change the way lazy flag is set and |
- reset, be sure to consider this use as well! */ |
- char lazy; |
- |
- /* If nonzero, this is the value of a variable which does not |
- actually exist in the program. */ |
- char optimized_out; |
- |
- /* If value is a variable, is it initialized or not. */ |
- int initialized; |
- |
- /* If value is from the stack. If this is set, read_stack will be |
- used instead of read_memory to enable extra caching. */ |
- int stack; |
- |
/* Actual contents of the value. Target byte-order. NULL or not |
valid if lazy is nonzero. */ |
gdb_byte *contents; |
@@ -315,13 +329,6 @@ struct value |
rather than available, since the common and default case is for a |
value to be available. This is filled in at value read time. */ |
VEC(range_s) *unavailable; |
- |
- /* The number of references to this value. When a value is created, |
- the value chain holds a reference, so REFERENCE_COUNT is 1. If |
- release_value is called, this value is removed from the chain but |
- the caller of release_value now has a reference to this value. |
- The caller must arrange for a call to value_free later. */ |
- int reference_count; |
}; |
int |
@@ -799,6 +806,14 @@ value_parent (struct value *value) |
return value->parent; |
} |
+/* See value.h. */ |
+ |
+void |
+set_value_parent (struct value *value, struct value *parent) |
+{ |
+ value->parent = parent; |
+} |
+ |
gdb_byte * |
value_contents_raw (struct value *value) |
{ |
@@ -819,6 +834,50 @@ value_enclosing_type (struct value *value) |
return value->enclosing_type; |
} |
+/* Look at value.h for description. */ |
+ |
+struct type * |
+value_actual_type (struct value *value, int resolve_simple_types, |
+ int *real_type_found) |
+{ |
+ struct value_print_options opts; |
+ struct type *result; |
+ |
+ get_user_print_options (&opts); |
+ |
+ if (real_type_found) |
+ *real_type_found = 0; |
+ result = value_type (value); |
+ if (opts.objectprint) |
+ { |
+ /* If result's target type is TYPE_CODE_STRUCT, proceed to |
+ fetch its rtti type. */ |
+ if ((TYPE_CODE (result) == TYPE_CODE_PTR |
+ || TYPE_CODE (result) == TYPE_CODE_REF) |
+ && TYPE_CODE (check_typedef (TYPE_TARGET_TYPE (result))) |
+ == TYPE_CODE_STRUCT) |
+ { |
+ struct type *real_type; |
+ |
+ real_type = value_rtti_indirect_type (value, NULL, NULL, NULL); |
+ if (real_type) |
+ { |
+ if (real_type_found) |
+ *real_type_found = 1; |
+ result = real_type; |
+ } |
+ } |
+ else if (resolve_simple_types) |
+ { |
+ if (real_type_found) |
+ *real_type_found = 1; |
+ result = value_enclosing_type (value); |
+ } |
+ } |
+ |
+ return result; |
+} |
+ |
static void |
require_not_optimized_out (const struct value *value) |
{ |
@@ -1094,7 +1153,10 @@ value_address (const struct value *value) |
if (value->lval == lval_internalvar |
|| value->lval == lval_internalvar_component) |
return 0; |
- return value->location.address + value->offset; |
+ if (value->parent != NULL) |
+ return value_address (value->parent) + value->offset; |
+ else |
+ return value->location.address + value->offset; |
} |
CORE_ADDR |
@@ -1205,6 +1267,7 @@ value_free_to_mark (struct value *mark) |
for (val = all_values; val && val != mark; val = next) |
{ |
next = val->next; |
+ val->released = 1; |
value_free (val); |
} |
all_values = val; |
@@ -1223,6 +1286,7 @@ free_all_values (void) |
for (val = all_values; val; val = next) |
{ |
next = val->next; |
+ val->released = 1; |
value_free (val); |
} |
@@ -1255,6 +1319,7 @@ release_value (struct value *val) |
{ |
all_values = val->next; |
val->next = NULL; |
+ val->released = 1; |
return; |
} |
@@ -1264,11 +1329,26 @@ release_value (struct value *val) |
{ |
v->next = val->next; |
val->next = NULL; |
+ val->released = 1; |
break; |
} |
} |
} |
+/* If the value is not already released, release it. |
+ If the value is already released, increment its reference count. |
+ That is, this function ensures that the value is released from the |
+ value chain and that the caller owns a reference to it. */ |
+ |
+void |
+release_value_or_incref (struct value *val) |
+{ |
+ if (val->released) |
+ value_incref (val); |
+ else |
+ release_value (val); |
+} |
+ |
/* Release all values up to mark */ |
struct value * |
value_release_to_mark (struct value *mark) |
@@ -1277,12 +1357,15 @@ value_release_to_mark (struct value *mark) |
struct value *next; |
for (val = next = all_values; next; next = next->next) |
- if (next->next == mark) |
- { |
- all_values = next->next; |
- next->next = NULL; |
- return val; |
- } |
+ { |
+ if (next->next == mark) |
+ { |
+ all_values = next->next; |
+ next->next = NULL; |
+ return val; |
+ } |
+ next->released = 1; |
+ } |
all_values = 0; |
return val; |
} |
@@ -1549,7 +1632,14 @@ struct internalvar |
struct value *value; |
/* The call-back routine used with INTERNALVAR_MAKE_VALUE. */ |
- internalvar_make_value make_value; |
+ struct |
+ { |
+ /* The functions to call. */ |
+ const struct internalvar_funcs *functions; |
+ |
+ /* The function's user-data. */ |
+ void *data; |
+ } make_value; |
/* The internal function used with INTERNALVAR_FUNCTION. */ |
struct |
@@ -1628,6 +1718,29 @@ lookup_only_internalvar (const char *name) |
return NULL; |
} |
+/* Complete NAME by comparing it to the names of internal variables. |
+ Returns a vector of newly allocated strings, or NULL if no matches |
+ were found. */ |
+ |
+VEC (char_ptr) * |
+complete_internalvar (const char *name) |
+{ |
+ VEC (char_ptr) *result = NULL; |
+ struct internalvar *var; |
+ int len; |
+ |
+ len = strlen (name); |
+ |
+ for (var = internalvars; var; var = var->next) |
+ if (strncmp (var->name, name, len) == 0) |
+ { |
+ char *r = xstrdup (var->name); |
+ |
+ VEC_safe_push (char_ptr, result, r); |
+ } |
+ |
+ return result; |
+} |
/* Create an internal variable with name NAME and with a void value. |
NAME should not normally include a dollar sign. */ |
@@ -1648,18 +1761,39 @@ create_internalvar (const char *name) |
/* Create an internal variable with name NAME and register FUN as the |
function that value_of_internalvar uses to create a value whenever |
this variable is referenced. NAME should not normally include a |
- dollar sign. */ |
+ dollar sign. DATA is passed uninterpreted to FUN when it is |
+ called. CLEANUP, if not NULL, is called when the internal variable |
+ is destroyed. It is passed DATA as its only argument. */ |
struct internalvar * |
-create_internalvar_type_lazy (char *name, internalvar_make_value fun) |
+create_internalvar_type_lazy (const char *name, |
+ const struct internalvar_funcs *funcs, |
+ void *data) |
{ |
struct internalvar *var = create_internalvar (name); |
var->kind = INTERNALVAR_MAKE_VALUE; |
- var->u.make_value = fun; |
+ var->u.make_value.functions = funcs; |
+ var->u.make_value.data = data; |
return var; |
} |
+/* See documentation in value.h. */ |
+ |
+int |
+compile_internalvar_to_ax (struct internalvar *var, |
+ struct agent_expr *expr, |
+ struct axs_value *value) |
+{ |
+ if (var->kind != INTERNALVAR_MAKE_VALUE |
+ || var->u.make_value.functions->compile_to_ax == NULL) |
+ return 0; |
+ |
+ var->u.make_value.functions->compile_to_ax (var, expr, value, |
+ var->u.make_value.data); |
+ return 1; |
+} |
+ |
/* Look up an internal variable with name NAME. NAME should not |
normally include a dollar sign. |
@@ -1732,7 +1866,8 @@ value_of_internalvar (struct gdbarch *gdbarch, struct internalvar *var) |
break; |
case INTERNALVAR_MAKE_VALUE: |
- val = (*var->u.make_value) (gdbarch, var); |
+ val = (*var->u.make_value.functions->make_value) (gdbarch, var, |
+ var->u.make_value.data); |
break; |
default: |
@@ -1928,6 +2063,11 @@ clear_internalvar (struct internalvar *var) |
xfree (var->u.string); |
break; |
+ case INTERNALVAR_MAKE_VALUE: |
+ if (var->u.make_value.functions->destroy != NULL) |
+ var->u.make_value.functions->destroy (var->u.make_value.data); |
+ break; |
+ |
default: |
break; |
} |
@@ -2522,11 +2662,24 @@ value_primitive_field (struct value *arg1, int offset, |
/* This field is actually a base subobject, so preserve the |
entire object's contents for later references to virtual |
bases, etc. */ |
+ int boffset; |
/* Lazy register values with offsets are not supported. */ |
if (VALUE_LVAL (arg1) == lval_register && value_lazy (arg1)) |
value_fetch_lazy (arg1); |
+ /* We special case virtual inheritance here because this |
+ requires access to the contents, which we would rather avoid |
+ for references to ordinary fields of unavailable values. */ |
+ if (BASETYPE_VIA_VIRTUAL (arg_type, fieldno)) |
+ boffset = baseclass_offset (arg_type, fieldno, |
+ value_contents (arg1), |
+ value_embedded_offset (arg1), |
+ value_address (arg1), |
+ arg1); |
+ else |
+ boffset = TYPE_FIELD_BITPOS (arg_type, fieldno) / 8; |
+ |
if (value_lazy (arg1)) |
v = allocate_value_lazy (value_enclosing_type (arg1)); |
else |
@@ -2537,8 +2690,7 @@ value_primitive_field (struct value *arg1, int offset, |
} |
v->type = type; |
v->offset = value_offset (arg1); |
- v->embedded_offset = (offset + value_embedded_offset (arg1) |
- + TYPE_FIELD_BITPOS (arg_type, fieldno) / 8); |
+ v->embedded_offset = offset + value_embedded_offset (arg1) + boffset; |
} |
else |
{ |
@@ -2902,7 +3054,7 @@ pack_long (gdb_byte *buf, struct type *type, LONGEST num) |
/* Pack NUM into BUF using a target format of TYPE. */ |
-void |
+static void |
pack_unsigned_long (gdb_byte *buf, struct type *type, ULONGEST num) |
{ |
int len; |
@@ -3107,11 +3259,30 @@ coerce_ref_if_computed (const struct value *arg) |
return funcs->coerce_ref (arg); |
} |
+/* Look at value.h for description. */ |
+ |
+struct value * |
+readjust_indirect_value_type (struct value *value, struct type *enc_type, |
+ struct type *original_type, |
+ struct value *original_value) |
+{ |
+ /* Re-adjust type. */ |
+ deprecated_set_value_type (value, TYPE_TARGET_TYPE (original_type)); |
+ |
+ /* Add embedding info. */ |
+ set_value_enclosing_type (value, enc_type); |
+ set_value_embedded_offset (value, value_pointed_to_offset (original_value)); |
+ |
+ /* We may be pointing to an object of some derived type. */ |
+ return value_full_object (value, NULL, 0, 0, 0); |
+} |
+ |
struct value * |
coerce_ref (struct value *arg) |
{ |
struct type *value_type_arg_tmp = check_typedef (value_type (arg)); |
struct value *retval; |
+ struct type *enc_type; |
retval = coerce_ref_if_computed (arg); |
if (retval) |
@@ -3120,9 +3291,14 @@ coerce_ref (struct value *arg) |
if (TYPE_CODE (value_type_arg_tmp) != TYPE_CODE_REF) |
return arg; |
- return value_at_lazy (TYPE_TARGET_TYPE (value_type_arg_tmp), |
- unpack_pointer (value_type (arg), |
- value_contents (arg))); |
+ enc_type = check_typedef (value_enclosing_type (arg)); |
+ enc_type = TYPE_TARGET_TYPE (enc_type); |
+ |
+ retval = value_at_lazy (enc_type, |
+ unpack_pointer (value_type (arg), |
+ value_contents (arg))); |
+ return readjust_indirect_value_type (retval, enc_type, |
+ value_type_arg_tmp, arg); |
} |
struct value * |
@@ -3153,7 +3329,7 @@ coerce_array (struct value *arg) |
int |
using_struct_return (struct gdbarch *gdbarch, |
- struct type *func_type, struct type *value_type) |
+ struct value *function, struct type *value_type) |
{ |
enum type_code code = TYPE_CODE (value_type); |
@@ -3166,7 +3342,7 @@ using_struct_return (struct gdbarch *gdbarch, |
return 0; |
/* Probe the architecture for the return-value convention. */ |
- return (gdbarch_return_value (gdbarch, func_type, value_type, |
+ return (gdbarch_return_value (gdbarch, function, value_type, |
NULL, NULL, NULL) |
!= RETURN_VALUE_REGISTER_CONVENTION); |
} |