#include "defs.h"
#include "gdb_string.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "value.h"
#include "gdbcore.h"
#include "command.h"
#include "gdbcmd.h"
#include "target.h"
#include "language.h"
#include "scm-lang.h"
#include "demangle.h"
#include "doublest.h"
#include "gdb_assert.h"
#include "regcache.h"
#include "block.h"
void _initialize_values (void);
struct value
{
enum lval_type lval;
int modifiable;
union
{
CORE_ADDR address;
struct internalvar *internalvar;
} location;
int offset;
int bitsize;
int bitpos;
struct frame_id frame_id;
struct type *type;
struct type *enclosing_type;
int embedded_offset;
int pointed_to_offset;
struct value *next;
short regnum;
char lazy;
enum opt_state optimized_out;
int var_status;
union
{
gdb_byte contents[1];
DOUBLEST force_doublest_align;
LONGEST force_longest_align;
CORE_ADDR force_core_addr_align;
void *force_pointer_align;
} aligner;
};
struct cached_value
{
char *name;
struct type *type;
struct value val;
int bound;
unsigned int generation;
};
extern unsigned int symbol_generation;
struct cached_value *
create_cached_function (name, type)
char *name;
struct type *type;
{
struct cached_value *ptr;
ptr = (struct cached_value *) xmalloc (sizeof (struct cached_value));
ptr->name = xstrdup (name);
ptr->type = type;
ptr->bound = 0;
memset (&ptr->val, 0, sizeof (struct value));
ptr->generation = (unsigned int) -1;
return ptr;
}
void
set_var_status (struct value *val, int status)
{
val->var_status = status;
}
int
value_var_status (struct value *val)
{
return val->var_status;
}
struct value *
lookup_cached_function (struct cached_value *cval)
{
struct value *val = NULL;
struct value *next = NULL;
if (cval->generation != symbol_generation)
{
val = find_function_in_inferior (cval->name, cval->type);
cval->val = *val;
cval->val.next = NULL;
cval->bound = 0;
cval->generation = symbol_generation;
}
if (!cval->bound)
{
if (!target_bind_function (cval->name))
error ("Could not bind function \"%s\".", cval->name);
else
cval->bound = 1;
}
val = allocate_value (cval->val.type);
next = val->next;
*val = cval->val;
val->next = next;
return val;
}
static void show_values (char *, int);
static void show_convenience (char *, int);
#define VALUE_HISTORY_CHUNK 60
struct value_history_chunk
{
struct value_history_chunk *next;
struct value *values[VALUE_HISTORY_CHUNK];
};
static struct value_history_chunk *value_history_chain;
static int value_history_count;
static struct value *all_values;
struct value *
allocate_value (struct type *type)
{
struct value *val;
struct type *atype = check_typedef (type);
val = (struct value *) xzalloc (sizeof (struct value) + TYPE_LENGTH (atype));
val->next = all_values;
all_values = val;
val->type = type;
val->enclosing_type = type;
VALUE_LVAL (val) = not_lval;
VALUE_ADDRESS (val) = 0;
VALUE_FRAME_ID (val) = null_frame_id;
val->offset = 0;
val->bitpos = 0;
val->bitsize = 0;
VALUE_REGNUM (val) = -1;
val->lazy = 0;
val->optimized_out = 0;
val->embedded_offset = 0;
val->pointed_to_offset = 0;
val->modifiable = 1;
val->var_status = 1;
return val;
}
struct value *
allocate_repeat_value (struct type *type, int count)
{
int low_bound = current_language->string_lower_bound;
struct type *range_type
= create_range_type ((struct type *) NULL, builtin_type_int,
low_bound, count + low_bound - 1);
return allocate_value (create_array_type ((struct type *) NULL,
type, range_type));
}
struct value *
value_next (struct value *value)
{
return value->next;
}
struct type *
value_type (struct value *value)
{
return value->type;
}
void
deprecated_set_value_type (struct value *value, struct type *type)
{
value->type = type;
}
int
value_offset (struct value *value)
{
return value->offset;
}
void
set_value_offset (struct value *value, int offset)
{
value->offset = offset;
}
int
value_bitpos (struct value *value)
{
return value->bitpos;
}
void
set_value_bitpos (struct value *value, int bit)
{
value->bitpos = bit;
}
int
value_bitsize (struct value *value)
{
return value->bitsize;
}
void
set_value_bitsize (struct value *value, int bit)
{
value->bitsize = bit;
}
gdb_byte *
value_contents_raw (struct value *value)
{
return value->aligner.contents + value->embedded_offset;
}
gdb_byte *
value_contents_all_raw (struct value *value)
{
return value->aligner.contents;
}
struct type *
value_enclosing_type (struct value *value)
{
return value->enclosing_type;
}
const gdb_byte *
value_contents_all (struct value *value)
{
if (value->lazy)
value_fetch_lazy (value);
return value->aligner.contents;
}
int
value_lazy (struct value *value)
{
return value->lazy;
}
void
set_value_lazy (struct value *value, int val)
{
value->lazy = val;
}
const gdb_byte *
value_contents (struct value *value)
{
return value_contents_writeable (value);
}
gdb_byte *
value_contents_writeable (struct value *value)
{
if (value->lazy)
value_fetch_lazy (value);
return value_contents_raw (value);
}
int
value_contents_equal (struct value *val1, struct value *val2)
{
struct type *type1;
struct type *type2;
int len;
type1 = check_typedef (value_type (val1));
type2 = check_typedef (value_type (val2));
len = TYPE_LENGTH (type1);
if (len != TYPE_LENGTH (type2))
return 0;
return (memcmp (value_contents (val1), value_contents (val2), len) == 0);
}
enum opt_state
value_optimized_out (struct value *value)
{
return value->optimized_out;
}
void
set_value_optimized_out (struct value *value, enum opt_state val)
{
value->optimized_out = val;
}
int
value_embedded_offset (struct value *value)
{
return value->embedded_offset;
}
void
set_value_embedded_offset (struct value *value, int val)
{
value->embedded_offset = val;
}
int
value_pointed_to_offset (struct value *value)
{
return value->pointed_to_offset;
}
void
set_value_pointed_to_offset (struct value *value, int val)
{
value->pointed_to_offset = val;
}
enum lval_type *
deprecated_value_lval_hack (struct value *value)
{
return &value->lval;
}
CORE_ADDR *
deprecated_value_address_hack (struct value *value)
{
return &value->location.address;
}
struct internalvar **
deprecated_value_internalvar_hack (struct value *value)
{
return &value->location.internalvar;
}
struct frame_id *
deprecated_value_frame_id_hack (struct value *value)
{
return &value->frame_id;
}
short *
deprecated_value_regnum_hack (struct value *value)
{
return &value->regnum;
}
int
deprecated_value_modifiable (struct value *value)
{
return value->modifiable;
}
void
deprecated_set_value_modifiable (struct value *value, int modifiable)
{
value->modifiable = modifiable;
}
struct value *
value_mark (void)
{
return all_values;
}
void
value_free_to_mark (struct value *mark)
{
struct value *val;
struct value *next;
for (val = all_values; val && val != mark; val = next)
{
next = val->next;
value_free (val);
}
all_values = val;
}
void
free_all_values (void)
{
struct value *val;
struct value *next;
for (val = all_values; val; val = next)
{
next = val->next;
value_free (val);
}
all_values = 0;
}
void
release_value (struct value *val)
{
struct value *v;
if (all_values == val)
{
all_values = val->next;
return;
}
for (v = all_values; v; v = v->next)
{
if (v->next == val)
{
v->next = val->next;
break;
}
}
}
struct value *
value_release_to_mark (struct value *mark)
{
struct value *val;
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;
}
all_values = 0;
return val;
}
struct value *
value_copy (struct value *arg)
{
struct type *encl_type = value_enclosing_type (arg);
struct value *val = allocate_value (encl_type);
val->type = arg->type;
VALUE_LVAL (val) = VALUE_LVAL (arg);
VALUE_ADDRESS (val) = VALUE_ADDRESS (arg);
val->offset = arg->offset;
val->bitpos = arg->bitpos;
val->bitsize = arg->bitsize;
VALUE_FRAME_ID (val) = VALUE_FRAME_ID (arg);
VALUE_REGNUM (val) = VALUE_REGNUM (arg);
val->lazy = arg->lazy;
val->optimized_out = arg->optimized_out;
val->embedded_offset = value_embedded_offset (arg);
val->pointed_to_offset = arg->pointed_to_offset;
val->modifiable = arg->modifiable;
if (!value_lazy (val))
{
memcpy (value_contents_all_raw (val), value_contents_all_raw (arg),
TYPE_LENGTH (value_enclosing_type (arg)));
}
return val;
}
int
record_latest_value (struct value *val)
{
int i;
if (value_lazy (val))
value_fetch_lazy (val);
val->modifiable = 0;
release_value (val);
i = value_history_count % VALUE_HISTORY_CHUNK;
if (i == 0)
{
struct value_history_chunk *new
= (struct value_history_chunk *)
xmalloc (sizeof (struct value_history_chunk));
memset (new->values, 0, sizeof new->values);
new->next = value_history_chain;
value_history_chain = new;
}
value_history_chain->values[i] = val;
return ++value_history_count;
}
struct value *
access_value_history (int num)
{
struct value_history_chunk *chunk;
int i;
int absnum = num;
if (absnum <= 0)
absnum += value_history_count;
if (absnum <= 0)
{
if (num == 0)
error (_("The history is empty."));
else if (num == 1)
error (_("There is only one value in the history."));
else
error (_("History does not go back to $$%d."), -num);
}
if (absnum > value_history_count)
error (_("History has not yet reached $%d."), absnum);
absnum--;
chunk = value_history_chain;
for (i = (value_history_count - 1) / VALUE_HISTORY_CHUNK - absnum / VALUE_HISTORY_CHUNK;
i > 0; i--)
chunk = chunk->next;
return value_copy (chunk->values[absnum % VALUE_HISTORY_CHUNK]);
}
void
clear_value_history (void)
{
struct value_history_chunk *next;
int i;
struct value *val;
while (value_history_chain)
{
for (i = 0; i < VALUE_HISTORY_CHUNK; i++)
if ((val = value_history_chain->values[i]) != NULL)
xfree (val);
next = value_history_chain->next;
xfree (value_history_chain);
value_history_chain = next;
}
value_history_count = 0;
}
static void
show_values (char *num_exp, int from_tty)
{
int i;
struct value *val;
static int num = 1;
if (num_exp)
{
if (num_exp[0] != '+' || num_exp[1] != '\0')
num = parse_and_eval_long (num_exp) - 5;
}
else
{
num = value_history_count - 9;
}
if (num <= 0)
num = 1;
for (i = num; i < num + 10 && i <= value_history_count; i++)
{
val = access_value_history (i);
printf_filtered (("$%d = "), i);
value_print (val, gdb_stdout, 0, Val_pretty_default);
printf_filtered (("\n"));
}
num += 10;
if (from_tty && num_exp)
{
num_exp[0] = '+';
num_exp[1] = '\0';
}
}
static struct internalvar *internalvars;
struct internalvar *
lookup_internalvar (char *name)
{
struct internalvar *var;
for (var = internalvars; var; var = var->next)
if (strcmp (var->name, name) == 0)
return var;
var = (struct internalvar *) xmalloc (sizeof (struct internalvar));
var->name = concat (name, (char *)NULL);
var->value = allocate_value (builtin_type_void);
release_value (var->value);
var->next = internalvars;
internalvars = var;
return var;
}
struct value *
value_of_internalvar (struct internalvar *var)
{
struct value *val;
val = value_copy (var->value);
if (value_lazy (val))
value_fetch_lazy (val);
VALUE_LVAL (val) = lval_internalvar;
VALUE_INTERNALVAR (val) = var;
return val;
}
void
set_internalvar_component (struct internalvar *var, int offset, int bitpos,
int bitsize, struct value *newval)
{
gdb_byte *addr = value_contents_writeable (var->value) + offset;
if (bitsize)
modify_field (addr, value_as_long (newval),
bitpos, bitsize);
else
memcpy (addr, value_contents (newval), TYPE_LENGTH (value_type (newval)));
}
void
set_internalvar (struct internalvar *var, struct value *val)
{
struct value *newval;
newval = value_copy (val);
newval->modifiable = 1;
if (value_lazy (newval))
value_fetch_lazy (newval);
xfree (var->value);
var->value = newval;
release_value (newval);
}
char *
internalvar_name (struct internalvar *var)
{
return var->name;
}
void
clear_internalvars (void)
{
struct internalvar *var;
while (internalvars)
{
var = internalvars;
internalvars = var->next;
xfree (var->name);
xfree (var->value);
xfree (var);
}
}
static void
show_convenience (char *ignore, int from_tty)
{
struct internalvar *var;
int varseen = 0;
for (var = internalvars; var; var = var->next)
{
if (!varseen)
{
varseen = 1;
}
printf_filtered (("$%s = "), var->name);
value_print (var->value, gdb_stdout, 0, Val_pretty_default);
printf_filtered (("\n"));
}
if (!varseen)
printf_unfiltered (_("\
No debugger convenience variables now defined.\n\
Convenience variables have names starting with \"$\";\n\
use \"set\" as in \"set $foo = 5\" to define them.\n"));
}
LONGEST
value_as_long (struct value *val)
{
val = coerce_array (val);
return unpack_long (value_type (val), value_contents (val));
}
DOUBLEST
value_as_double (struct value *val)
{
DOUBLEST foo;
int inv;
foo = unpack_double (value_type (val), value_contents (val), &inv);
if (inv)
error (_("Invalid floating value found in program."));
return foo;
}
CORE_ADDR
value_as_address (struct value *val)
{
#if 0
return ADDR_BITS_REMOVE (value_as_long (val));
#else
if (TYPE_CODE (value_type (val)) == TYPE_CODE_FUNC
|| TYPE_CODE (value_type (val)) == TYPE_CODE_METHOD)
return VALUE_ADDRESS (val);
val = coerce_array (val);
if (TYPE_CODE (value_type (val)) != TYPE_CODE_PTR
&& TYPE_CODE (value_type (val)) != TYPE_CODE_REF
&& gdbarch_integer_to_address_p (current_gdbarch))
return gdbarch_integer_to_address (current_gdbarch, value_type (val),
value_contents (val));
return unpack_long (value_type (val), value_contents (val));
#endif
}
LONGEST
unpack_long (struct type *type, const gdb_byte *valaddr)
{
enum type_code code = TYPE_CODE (type);
int len = TYPE_LENGTH (type);
int nosign = TYPE_UNSIGNED (type);
if (current_language->la_language == language_scm
&& is_scmvalue_type (type))
return scm_unpack (type, valaddr, TYPE_CODE_INT);
switch (code)
{
case TYPE_CODE_TYPEDEF:
return unpack_long (check_typedef (type), valaddr);
case TYPE_CODE_ENUM:
case TYPE_CODE_BOOL:
case TYPE_CODE_INT:
case TYPE_CODE_CHAR:
case TYPE_CODE_RANGE:
if (nosign)
return extract_unsigned_integer_with_byte_order (valaddr, len, TYPE_BYTE_ORDER (type));
else
return extract_signed_integer_with_byte_order (valaddr, len, TYPE_BYTE_ORDER (type));
case TYPE_CODE_FLT:
return extract_typed_floating (valaddr, type);
case TYPE_CODE_PTR:
case TYPE_CODE_REF:
return extract_typed_address (valaddr, type);
case TYPE_CODE_MEMBER:
error (_("not implemented: member types in unpack_long"));
default:
error (_("Value can't be converted to integer."));
}
return 0;
}
DOUBLEST
unpack_double (struct type *type, const gdb_byte *valaddr, int *invp)
{
enum type_code code;
int len;
int nosign;
*invp = 0;
CHECK_TYPEDEF (type);
code = TYPE_CODE (type);
len = TYPE_LENGTH (type);
nosign = TYPE_UNSIGNED (type);
if (code == TYPE_CODE_FLT)
{
if (!floatformat_is_valid (floatformat_from_type (type), valaddr))
{
*invp = 1;
return 0.0;
}
return extract_typed_floating (valaddr, type);
}
else if (nosign)
{
return (ULONGEST) unpack_long (type, valaddr);
}
else
{
return unpack_long (type, valaddr);
}
}
CORE_ADDR
unpack_pointer (struct type *type, const gdb_byte *valaddr)
{
return unpack_long (type, valaddr);
}
struct value *
value_static_field (struct type *type, int fieldno)
{
struct value *retval;
if (TYPE_FIELD_STATIC_HAS_ADDR (type, fieldno))
{
retval = value_at (TYPE_FIELD_TYPE (type, fieldno),
TYPE_FIELD_STATIC_PHYSADDR (type, fieldno));
}
else
{
char *phys_name = TYPE_FIELD_STATIC_PHYSNAME (type, fieldno);
struct symbol *sym = lookup_symbol (phys_name, 0, VAR_DOMAIN, 0, NULL);
if (sym == NULL)
{
struct minimal_symbol *msym = lookup_minimal_symbol (phys_name, NULL, NULL);
if (!msym)
return NULL;
else
{
retval = value_at (TYPE_FIELD_TYPE (type, fieldno),
SYMBOL_VALUE_ADDRESS (msym));
}
}
else
{
if (symbol_read_needs_frame (sym))
warning (_("static field's value depends on the current "
"frame - bad debug info?"));
retval = read_var_value (sym, NULL);
}
if (retval && VALUE_LVAL (retval) == lval_memory)
SET_FIELD_PHYSADDR (TYPE_FIELD (type, fieldno),
VALUE_ADDRESS (retval));
}
return retval;
}
struct value *
value_change_enclosing_type (struct value *val, struct type *new_encl_type)
{
if (TYPE_LENGTH (new_encl_type) <= TYPE_LENGTH (value_enclosing_type (val)))
{
val->enclosing_type = new_encl_type;
return val;
}
else
{
struct value *new_val;
struct value *prev;
new_val = (struct value *) xrealloc (val, sizeof (struct value) + TYPE_LENGTH (new_encl_type));
new_val->enclosing_type = new_encl_type;
if (val != all_values)
{
for (prev = all_values; prev != NULL; prev = prev->next)
{
if (prev->next == val)
{
prev->next = new_val;
break;
}
}
}
return new_val;
}
}
struct value *
value_primitive_field (struct value *arg1, int offset,
int fieldno, struct type *arg_type)
{
struct value *v;
struct type *type;
CHECK_TYPEDEF (arg_type);
type = TYPE_FIELD_TYPE (arg_type, fieldno);
if (TYPE_FIELD_BITSIZE (arg_type, fieldno))
{
v = value_from_longest (type,
unpack_field_as_long (arg_type,
value_contents (arg1)
+ offset,
fieldno));
v->bitpos = TYPE_FIELD_BITPOS (arg_type, fieldno) % 8;
v->bitsize = TYPE_FIELD_BITSIZE (arg_type, fieldno);
v->offset = value_offset (arg1) + offset
+ TYPE_FIELD_BITPOS (arg_type, fieldno) / 8;
}
else if (fieldno < TYPE_N_BASECLASSES (arg_type))
{
v = allocate_value (value_enclosing_type (arg1));
v->type = type;
if (value_lazy (arg1))
set_value_lazy (v, 1);
else
memcpy (value_contents_all_raw (v), value_contents_all_raw (arg1),
TYPE_LENGTH (value_enclosing_type (arg1)));
v->offset = value_offset (arg1);
v->embedded_offset = (offset + value_embedded_offset (arg1)
+ TYPE_FIELD_BITPOS (arg_type, fieldno) / 8);
}
else
{
offset += TYPE_FIELD_BITPOS (arg_type, fieldno) / 8;
v = allocate_value (type);
if (value_lazy (arg1))
set_value_lazy (v, 1);
else
memcpy (value_contents_raw (v),
value_contents_raw (arg1) + offset,
TYPE_LENGTH (type));
v->offset = (value_offset (arg1) + offset
+ value_embedded_offset (arg1));
}
VALUE_LVAL (v) = VALUE_LVAL (arg1);
if (VALUE_LVAL (arg1) == lval_internalvar)
VALUE_LVAL (v) = lval_internalvar_component;
VALUE_ADDRESS (v) = VALUE_ADDRESS (arg1);
VALUE_REGNUM (v) = VALUE_REGNUM (arg1);
VALUE_FRAME_ID (v) = VALUE_FRAME_ID (arg1);
return v;
}
struct value *
value_field (struct value *arg1, int fieldno)
{
return value_primitive_field (arg1, 0, fieldno, value_type (arg1));
}
struct value *
value_fn_field (struct value **arg1p, struct fn_field *f, int j, struct type *type,
int offset)
{
struct value *v;
struct type *ftype = TYPE_FN_FIELD_TYPE (f, j);
char *physname = TYPE_FN_FIELD_PHYSNAME (f, j);
struct symbol *sym;
struct minimal_symbol *msym;
sym = lookup_symbol (physname, 0, VAR_DOMAIN, 0, NULL);
if (sym != NULL)
{
msym = NULL;
}
else
{
gdb_assert (sym == NULL);
msym = lookup_minimal_symbol (physname, NULL, NULL);
if (msym == NULL)
return NULL;
}
v = allocate_value (ftype);
if (sym)
{
struct block *block = SYMBOL_BLOCK_VALUE (sym);
if (block == NULL)
error ("value_fn_field: function symbol with no block");
VALUE_ADDRESS (v) = BLOCK_LOWEST_PC (block);
}
else
{
VALUE_ADDRESS (v) = SYMBOL_VALUE_ADDRESS (msym);
}
if (arg1p)
{
if (type != value_type (*arg1p))
*arg1p = value_ind (value_cast (lookup_pointer_type (type),
value_addr (*arg1p)));
}
return v;
}
LONGEST
unpack_field_as_long (struct type *type, const gdb_byte *valaddr, int fieldno)
{
ULONGEST val;
ULONGEST valmask;
int bitpos = TYPE_FIELD_BITPOS (type, fieldno);
int bitsize = TYPE_FIELD_BITSIZE (type, fieldno);
int lsbcount;
struct type *field_type;
val = extract_unsigned_integer (valaddr + bitpos / 8, sizeof (val));
field_type = TYPE_FIELD_TYPE (type, fieldno);
CHECK_TYPEDEF (field_type);
if (BITS_BIG_ENDIAN)
lsbcount = (sizeof val * 8 - bitpos % 8 - bitsize);
else
lsbcount = (bitpos % 8);
val >>= lsbcount;
if ((bitsize > 0) && (bitsize < 8 * (int) sizeof (val)))
{
valmask = (((ULONGEST) 1) << bitsize) - 1;
val &= valmask;
if (!TYPE_UNSIGNED (field_type))
{
if (val & (valmask ^ (valmask >> 1)))
{
val |= ~valmask;
}
}
}
return (val);
}
void
modify_field (gdb_byte *addr, LONGEST fieldval, int bitpos, int bitsize)
{
ULONGEST oword;
ULONGEST mask = (ULONGEST) -1 >> (8 * sizeof (ULONGEST) - bitsize);
if ((~fieldval & ~(mask >> 1)) == 0)
fieldval &= mask;
if (0 != (fieldval & ~mask))
{
warning (_("Value does not fit in %d bits."), bitsize);
fieldval &= mask;
}
oword = extract_unsigned_integer (addr, sizeof oword);
if (BITS_BIG_ENDIAN)
bitpos = sizeof (oword) * 8 - bitpos - bitsize;
oword &= ~(mask << bitpos);
oword |= fieldval << bitpos;
store_unsigned_integer (addr, sizeof oword, oword);
}
struct value *
value_from_longest (struct type *type, LONGEST num)
{
struct value *val = allocate_value (type);
enum type_code code;
int len;
retry:
code = TYPE_CODE (type);
len = TYPE_LENGTH (type);
switch (code)
{
case TYPE_CODE_TYPEDEF:
type = check_typedef (type);
goto retry;
case TYPE_CODE_INT:
case TYPE_CODE_CHAR:
case TYPE_CODE_ENUM:
case TYPE_CODE_BOOL:
case TYPE_CODE_RANGE:
store_signed_integer (value_contents_raw (val), len, num);
break;
case TYPE_CODE_REF:
case TYPE_CODE_PTR:
store_typed_address (value_contents_raw (val), type, (CORE_ADDR) num);
break;
default:
error (_("Unexpected type (%d) encountered for integer constant."), code);
}
return val;
}
struct value *
value_from_pointer (struct type *type, CORE_ADDR addr)
{
struct value *val = allocate_value (type);
store_typed_address (value_contents_raw (val), type, addr);
return val;
}
struct value *
value_from_string (char *ptr)
{
struct value *val;
int len = strlen (ptr);
int lowbound = current_language->string_lower_bound;
struct type *string_char_type;
struct type *rangetype;
struct type *stringtype;
rangetype = create_range_type ((struct type *) NULL,
builtin_type_int,
lowbound, len + lowbound - 1);
string_char_type = language_string_char_type (current_language,
current_gdbarch);
stringtype = create_array_type ((struct type *) NULL,
string_char_type,
rangetype);
val = allocate_value (stringtype);
memcpy (value_contents_raw (val), ptr, len);
return val;
}
struct value *
value_from_double (struct type *type, DOUBLEST num)
{
struct value *val = allocate_value (type);
struct type *base_type = check_typedef (type);
enum type_code code = TYPE_CODE (base_type);
int len = TYPE_LENGTH (base_type);
if (code == TYPE_CODE_FLT)
{
store_typed_floating (value_contents_raw (val), base_type, num);
}
else
error (_("Unexpected type encountered for floating constant."));
return val;
}
struct value *
coerce_ref (struct value *arg)
{
struct type *value_type_arg_tmp = check_typedef (value_type (arg));
if (TYPE_CODE (value_type_arg_tmp) == TYPE_CODE_REF)
arg = value_at_lazy (TYPE_TARGET_TYPE (value_type_arg_tmp),
unpack_pointer (value_type (arg),
value_contents (arg)));
return arg;
}
struct value *
coerce_array (struct value *arg)
{
arg = coerce_ref (arg);
if (current_language->c_style_arrays
&& TYPE_CODE (value_type (arg)) == TYPE_CODE_ARRAY)
arg = value_coerce_array (arg);
if (TYPE_CODE (value_type (arg)) == TYPE_CODE_FUNC)
arg = value_coerce_function (arg);
return arg;
}
struct value *
coerce_number (struct value *arg)
{
arg = coerce_array (arg);
arg = coerce_enum (arg);
return arg;
}
struct value *
coerce_enum (struct value *arg)
{
if (TYPE_CODE (check_typedef (value_type (arg))) == TYPE_CODE_ENUM)
arg = value_cast (builtin_type_unsigned_int, arg);
return arg;
}
int
generic_use_struct_convention (int gcc_p, struct type *value_type)
{
return !(TYPE_LENGTH (value_type) == 1
|| TYPE_LENGTH (value_type) == 2
|| TYPE_LENGTH (value_type) == 4
|| TYPE_LENGTH (value_type) == 8);
}
int
using_struct_return (struct type *value_type, int gcc_p)
{
enum type_code code = TYPE_CODE (value_type);
if (code == TYPE_CODE_ERROR)
error (_("Function return type unknown."));
if (code == TYPE_CODE_VOID)
return 0;
return (gdbarch_return_value (current_gdbarch, value_type,
NULL, NULL, NULL)
!= RETURN_VALUE_REGISTER_CONVENTION);
}
void
_initialize_values (void)
{
add_cmd ("convenience", no_class, show_convenience, _("\
Debugger convenience (\"$foo\") variables.\n\
These variables are created when you assign them values;\n\
thus, \"print $foo=1\" gives \"$foo\" the value 1. Values may be any type.\n\
\n\
A few convenience variables are given values automatically:\n\
\"$_\"holds the last address examined with \"x\" or \"info lines\",\n\
\"$__\" holds the contents of the last address examined with \"x\"."),
&showlist);
add_cmd ("values", no_class, show_values,
_("Elements of value history around item number IDX (or last ten)."),
&showlist);
}