/* Perform non-arithmetic operations on values, for GDB.
- Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
- 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
- 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+ Copyright (C) 1986-2012 Free Software Foundation, Inc.
This file is part of GDB.
#include "symtab.h"
#include "exceptions.h"
-extern int overload_debug;
+extern unsigned int overload_debug;
/* Local functions. */
static int typecmp (int staticp, int varargs, int nargs,
struct value **,
int, int *, struct type *);
-static int find_oload_champ_namespace (struct type **, int,
+static int find_oload_champ_namespace (struct value **, int,
const char *, const char *,
struct symbol ***,
struct badness_vector **,
const int no_adl);
static
-int find_oload_champ_namespace_loop (struct type **, int,
+int find_oload_champ_namespace_loop (struct value **, int,
const char *, const char *,
int, struct symbol ***,
struct badness_vector **, int *,
const int no_adl);
-static int find_oload_champ (struct type **, int, int, int,
+static int find_oload_champ (struct value **, int, int, int,
struct fn_field *, struct symbol **,
struct badness_vector **);
/* Cast one pointer or reference type to another. Both TYPE and
the type of ARG2 should be pointer types, or else both should be
- reference types. Returns the new pointer or reference. */
+ reference types. If SUBCLASS_CHECK is non-zero, this will force a
+ check to see whether TYPE is a superclass of ARG2's type. If
+ SUBCLASS_CHECK is zero, then the subclass check is done only when
+ ARG2 is itself non-zero. Returns the new pointer or reference. */
struct value *
-value_cast_pointers (struct type *type, struct value *arg2)
+value_cast_pointers (struct type *type, struct value *arg2,
+ int subclass_check)
{
struct type *type1 = check_typedef (type);
struct type *type2 = check_typedef (value_type (arg2));
if (TYPE_CODE (t1) == TYPE_CODE_STRUCT
&& TYPE_CODE (t2) == TYPE_CODE_STRUCT
- && !value_logical_not (arg2))
+ && (subclass_check || !value_logical_not (arg2)))
{
struct value *v2;
}
return val;
}
+ else if (code1 == TYPE_CODE_VOID)
+ {
+ return value_zero (type, not_lval);
+ }
else if (TYPE_LENGTH (type) == TYPE_LENGTH (type2))
{
if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_PTR)
- return value_cast_pointers (type, arg2);
+ return value_cast_pointers (type, arg2, 0);
arg2 = value_copy (arg2);
deprecated_set_value_type (arg2, type);
}
else if (VALUE_LVAL (arg2) == lval_memory)
return value_at_lazy (type, value_address (arg2));
- else if (code1 == TYPE_CODE_VOID)
- {
- return value_zero (type, not_lval);
- }
else
{
error (_("Invalid cast."));
{
struct value *val = allocate_value (type);
- VALUE_LVAL (val) = lv;
+ VALUE_LVAL (val) = (lv == lval_computed ? not_lval : lv);
return val;
}
-/* Create a value of numeric type TYPE that is one, and return it. */
+/* Create a not_lval value of numeric type TYPE that is one, and return it. */
struct value *
-value_one (struct type *type, enum lval_type lv)
+value_one (struct type *type)
{
struct type *type1 = check_typedef (type);
struct value *val;
val = allocate_value (type);
for (i = 0; i < high_bound - low_bound + 1; i++)
{
- tmp = value_one (eltype, lv);
+ tmp = value_one (eltype);
memcpy (value_contents_writeable (val) + i * TYPE_LENGTH (eltype),
value_contents_all (tmp), TYPE_LENGTH (eltype));
}
error (_("Not a numeric type."));
}
- VALUE_LVAL (val) = lv;
+ /* value_one result is never used for assignments to. */
+ gdb_assert (VALUE_LVAL (val) == not_lval);
+
return val;
}
struct value *parent = value_parent (val);
LONGEST offset = value_offset (val);
LONGEST num;
- int length = TYPE_LENGTH (type);
if (!value_bits_valid (val,
TARGET_CHAR_BIT * offset + value_bitpos (val),
value_bitsize (val), parent, &num))
mark_value_bytes_unavailable (val,
value_embedded_offset (val),
- length);
+ TYPE_LENGTH (type));
else
- store_signed_integer (value_contents_raw (val), length,
+ store_signed_integer (value_contents_raw (val), TYPE_LENGTH (type),
byte_order, num);
}
else if (VALUE_LVAL (val) == lval_memory)
{
CORE_ADDR addr = value_address (val);
- int length = TYPE_LENGTH (check_typedef (value_enclosing_type (val)));
+ struct type *type = check_typedef (value_enclosing_type (val));
- if (length)
+ if (TYPE_LENGTH (type))
read_value_memory (val, 0, value_stack (val),
- addr, value_contents_all_raw (val), length);
+ addr, value_contents_all_raw (val),
+ TYPE_LENGTH (type));
}
else if (VALUE_LVAL (val) == lval_register)
{
watchpoints from trying to watch the saved frame pointer. */
value_free_to_mark (mark);
}
- else if (VALUE_LVAL (val) == lval_computed)
+ else if (VALUE_LVAL (val) == lval_computed
+ && value_computed_funcs (val)->read != NULL)
value_computed_funcs (val)->read (val);
else if (value_optimized_out (val))
/* Keep it optimized out. */;
dest_buffer = value_contents (fromval);
}
- write_memory (changed_addr, dest_buffer, changed_len);
- observer_notify_memory_changed (changed_addr, changed_len,
- dest_buffer);
+ write_memory_with_notification (changed_addr, dest_buffer, changed_len);
}
break;
if (deprecated_register_changed_hook)
deprecated_register_changed_hook (-1);
- observer_notify_target_changed (¤t_target);
break;
}
case lval_computed:
{
- struct lval_funcs *funcs = value_computed_funcs (toval);
+ const struct lval_funcs *funcs = value_computed_funcs (toval);
- funcs->write (toval, fromval);
+ if (funcs->write != NULL)
+ {
+ funcs->write (toval, fromval);
+ break;
+ }
}
- break;
+ /* Fall through. */
default:
error (_("Left operand of assignment is not an lvalue."));
/* Assigning to the stack pointer, frame pointer, and other
(architecture and calling convention specific) registers may
- cause the frame cache to be out of date. Assigning to memory
+ cause the frame cache and regcache to be out of date. Assigning to memory
also can. We just do this on all assignments to registers or
memory, for simplicity's sake; I doubt the slowdown matters. */
switch (VALUE_LVAL (toval))
case lval_register:
case lval_computed:
- reinit_frame_cache ();
+ observer_notify_target_changed (¤t_target);
/* Having destroyed the frame cache, restore the selected
frame. */
}
struct value *
-value_of_variable (struct symbol *var, struct block *b)
+value_of_variable (struct symbol *var, const struct block *b)
{
- struct value *val;
struct frame_info *frame;
if (!symbol_read_needs_frame (var))
}
}
- val = read_var_value (var, frame);
- if (!val)
- error (_("Address of symbol \"%s\" is unknown."), SYMBOL_PRINT_NAME (var));
-
- return val;
+ return read_var_value (var, frame);
}
struct value *
-address_of_variable (struct symbol *var, struct block *b)
+address_of_variable (struct symbol *var, const struct block *b)
{
struct type *type = SYMBOL_TYPE (var);
struct value *val;
if (VALUE_LVAL (arg1) == lval_computed)
{
- struct lval_funcs *funcs = value_computed_funcs (arg1);
+ const struct lval_funcs *funcs = value_computed_funcs (arg1);
if (funcs->indirect)
{
(value_as_address (arg1)
- value_pointed_to_offset (arg1)));
- /* Re-adjust type. */
- deprecated_set_value_type (arg2, TYPE_TARGET_TYPE (base_type));
- /* Add embedding info. */
- set_value_enclosing_type (arg2, enc_type);
- set_value_embedded_offset (arg2, value_pointed_to_offset (arg1));
-
- /* We may be pointing to an object of some derived type. */
- arg2 = value_full_object (arg2, NULL, 0, 0, 0);
- return arg2;
+ return readjust_indirect_value_type (arg2, enc_type, base_type, arg1);
}
error (_("Attempt to take contents of a non-pointer value."));
}
struct value *
-value_cstring (char *ptr, int len, struct type *char_type)
+value_cstring (char *ptr, ssize_t len, struct type *char_type)
{
struct value *val;
int lowbound = current_language->string_lower_bound;
- int highbound = len / TYPE_LENGTH (char_type);
+ ssize_t highbound = len / TYPE_LENGTH (char_type);
struct type *stringtype
= lookup_array_range_type (char_type, lowbound, highbound + lowbound - 1);
string may contain embedded null bytes. */
struct value *
-value_string (char *ptr, int len, struct type *char_type)
+value_string (char *ptr, ssize_t len, struct type *char_type)
{
struct value *val;
int lowbound = current_language->string_lower_bound;
- int highbound = len / TYPE_LENGTH (char_type);
+ ssize_t highbound = len / TYPE_LENGTH (char_type);
struct type *stringtype
= lookup_string_range_type (char_type, lowbound, highbound + lowbound - 1);
return val;
}
-struct value *
-value_bitstring (char *ptr, int len, struct type *index_type)
-{
- struct value *val;
- struct type *domain_type
- = create_range_type (NULL, index_type, 0, len - 1);
- struct type *type = create_set_type (NULL, domain_type);
-
- TYPE_CODE (type) = TYPE_CODE_BITSTRING;
- val = allocate_value (type);
- memcpy (value_contents_raw (val), ptr, TYPE_LENGTH (type));
- return val;
-}
\f
/* See if we can pass arguments in T2 to a function which takes
arguments of types T1. T1 is a list of NARGS arguments, and T2 is
return i + 1;
}
-/* Helper function used by value_struct_elt to recurse through
- baseclasses. Look for a field NAME in ARG1. Adjust the address of
- ARG1 by OFFSET bytes, and search in it assuming it has (class) type
- TYPE. If found, return value, else return NULL.
+/* Helper class for do_search_struct_field that updates *RESULT_PTR
+ and *LAST_BOFFSET, and possibly throws an exception if the field
+ search has yielded ambiguous results. */
- If LOOKING_FOR_BASECLASS, then instead of looking for struct
- fields, look for a baseclass named NAME. */
+static void
+update_search_result (struct value **result_ptr, struct value *v,
+ int *last_boffset, int boffset,
+ const char *name, struct type *type)
+{
+ if (v != NULL)
+ {
+ if (*result_ptr != NULL
+ /* The result is not ambiguous if all the classes that are
+ found occupy the same space. */
+ && *last_boffset != boffset)
+ error (_("base class '%s' is ambiguous in type '%s'"),
+ name, TYPE_SAFE_NAME (type));
+ *result_ptr = v;
+ *last_boffset = boffset;
+ }
+}
-static struct value *
-search_struct_field (const char *name, struct value *arg1, int offset,
- struct type *type, int looking_for_baseclass)
+/* A helper for search_struct_field. This does all the work; most
+ arguments are as passed to search_struct_field. The result is
+ stored in *RESULT_PTR, which must be initialized to NULL.
+ OUTERMOST_TYPE is the type of the initial type passed to
+ search_struct_field; this is used for error reporting when the
+ lookup is ambiguous. */
+
+static void
+do_search_struct_field (const char *name, struct value *arg1, int offset,
+ struct type *type, int looking_for_baseclass,
+ struct value **result_ptr,
+ int *last_boffset,
+ struct type *outermost_type)
{
int i;
int nbases;
if (!looking_for_baseclass)
for (i = TYPE_NFIELDS (type) - 1; i >= nbases; i--)
{
- char *t_field_name = TYPE_FIELD_NAME (type, i);
+ const char *t_field_name = TYPE_FIELD_NAME (type, i);
if (t_field_name && (strcmp_iw (t_field_name, name) == 0))
{
name);
}
else
- {
- v = value_primitive_field (arg1, offset, i, type);
- if (v == 0)
- error (_("there is no field named %s"), name);
- }
- return v;
+ v = value_primitive_field (arg1, offset, i, type);
+ *result_ptr = v;
+ return;
}
if (t_field_name
represented as a struct, with a member for each
<variant field>. */
- struct value *v;
+ struct value *v = NULL;
int new_offset = offset;
/* This is pretty gross. In G++, the offset in an
&& TYPE_FIELD_BITPOS (field_type, 0) == 0))
new_offset += TYPE_FIELD_BITPOS (type, i) / 8;
- v = search_struct_field (name, arg1, new_offset,
- field_type,
- looking_for_baseclass);
+ do_search_struct_field (name, arg1, new_offset,
+ field_type,
+ looking_for_baseclass, &v,
+ last_boffset,
+ outermost_type);
if (v)
- return v;
+ {
+ *result_ptr = v;
+ return;
+ }
}
}
}
for (i = 0; i < nbases; i++)
{
- struct value *v;
+ struct value *v = NULL;
struct type *basetype = check_typedef (TYPE_BASECLASS (type, i));
/* If we are looking for baseclasses, this is what we get when
we hit them. But it could happen that the base part's member
&& (strcmp_iw (name,
TYPE_BASECLASS_NAME (type,
i)) == 0));
+ int boffset = value_embedded_offset (arg1) + offset;
if (BASETYPE_VIA_VIRTUAL (type, i))
{
- int boffset;
struct value *v2;
boffset = baseclass_offset (type, i,
}
if (found_baseclass)
- return v2;
- v = search_struct_field (name, v2, 0,
- TYPE_BASECLASS (type, i),
- looking_for_baseclass);
+ v = v2;
+ else
+ {
+ do_search_struct_field (name, v2, 0,
+ TYPE_BASECLASS (type, i),
+ looking_for_baseclass,
+ result_ptr, last_boffset,
+ outermost_type);
+ }
}
else if (found_baseclass)
v = value_primitive_field (arg1, offset, i, type);
else
- v = search_struct_field (name, arg1,
- offset + TYPE_BASECLASS_BITPOS (type,
- i) / 8,
- basetype, looking_for_baseclass);
- if (v)
- return v;
+ {
+ do_search_struct_field (name, arg1,
+ offset + TYPE_BASECLASS_BITPOS (type,
+ i) / 8,
+ basetype, looking_for_baseclass,
+ result_ptr, last_boffset,
+ outermost_type);
+ }
+
+ update_search_result (result_ptr, v, last_boffset,
+ boffset, name, outermost_type);
}
- return NULL;
+}
+
+/* Helper function used by value_struct_elt to recurse through
+ baseclasses. Look for a field NAME in ARG1. Adjust the address of
+ ARG1 by OFFSET bytes, and search in it assuming it has (class) type
+ TYPE. If found, return value, else return NULL.
+
+ If LOOKING_FOR_BASECLASS, then instead of looking for struct
+ fields, look for a baseclass named NAME. */
+
+static struct value *
+search_struct_field (const char *name, struct value *arg1, int offset,
+ struct type *type, int looking_for_baseclass)
+{
+ struct value *result = NULL;
+ int boffset = 0;
+
+ do_search_struct_field (name, arg1, offset, type, looking_for_baseclass,
+ &result, &boffset, type);
+ return result;
}
/* Helper function used by value_struct_elt to recurse through
CHECK_TYPEDEF (type);
for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; i--)
{
- char *t_field_name = TYPE_FN_FIELDLIST_NAME (type, i);
+ const char *t_field_name = TYPE_FN_FIELDLIST_NAME (type, i);
/* FIXME! May need to check for ARM demangling here. */
if (strncmp (t_field_name, "__", 2) == 0 ||
if (offset < 0 || offset >= TYPE_LENGTH (type))
{
- gdb_byte *tmp = alloca (TYPE_LENGTH (baseclass));
- CORE_ADDR address = value_address (*arg1p);
+ gdb_byte *tmp;
+ struct cleanup *back_to;
+ CORE_ADDR address;
+
+ tmp = xmalloc (TYPE_LENGTH (baseclass));
+ back_to = make_cleanup (xfree, tmp);
+ address = value_address (*arg1p);
if (target_read_memory (address + offset,
tmp, TYPE_LENGTH (baseclass)) != 0)
address + offset);
base_valaddr = value_contents_for_printing (base_val);
this_offset = 0;
+ do_cleanups (back_to);
}
else
{
for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; i--)
{
/* pai: FIXME What about operators and type conversions? */
- char *fn_field_name = TYPE_FN_FIELDLIST_NAME (type, i);
+ const char *fn_field_name = TYPE_FN_FIELDLIST_NAME (type, i);
if (fn_field_name && (strcmp_iw (fn_field_name, method) == 0))
{
method.
BOFFSET is the offset of the base subobject which defines the method. */
-struct fn_field *
+static struct fn_field *
value_find_oload_method_list (struct value **argp, const char *method,
int offset, int *num_fns,
struct type **basetype, int *boffset)
basetype, boffset);
}
-/* Given an array of argument types (ARGTYPES) (which includes an
+/* Given an array of arguments (ARGS) (which includes an
entry for "this" in the case of C++ methods), the number of
arguments NARGS, the NAME of a function whether it's a method or
not (METHOD), and the degree of laxness (LAX) in conforming to
resolution is permitted. */
int
-find_overload_match (struct type **arg_types, int nargs,
+find_overload_match (struct value **args, int nargs,
const char *name, enum oload_search_type method,
int lax, struct value **objp, struct symbol *fsym,
struct value **valp, struct symbol **symp,
int *staticp, const int no_adl)
{
struct value *obj = (objp ? *objp : NULL);
+ struct type *obj_type = obj ? value_type (obj) : NULL;
/* Index of best overloaded function. */
int func_oload_champ = -1;
int method_oload_champ = -1;
if (*valp)
{
*staticp = 1;
+ do_cleanups (all_cleanups);
return 0;
}
}
if (fns_ptr)
{
gdb_assert (TYPE_DOMAIN_TYPE (fns_ptr[0].type) != NULL);
- method_oload_champ = find_oload_champ (arg_types, nargs, method,
+ method_oload_champ = find_oload_champ (args, nargs, method,
num_fns, fns_ptr,
oload_syms, &method_badness);
and non member function, the first argument must now be
dereferenced. */
if (method == BOTH)
- arg_types[0] = TYPE_TARGET_TYPE (arg_types[0]);
+ args[0] = value_ind (args[0]);
if (fsym)
{
return 0;
}
- func_oload_champ = find_oload_champ_namespace (arg_types, nargs,
+ func_oload_champ = find_oload_champ_namespace (args, nargs,
func_name,
qualified_name,
&oload_syms,
if (objp)
{
struct type *temp_type = check_typedef (value_type (temp));
- struct type *obj_type = check_typedef (value_type (*objp));
+ struct type *objtype = check_typedef (obj_type);
if (TYPE_CODE (temp_type) != TYPE_CODE_PTR
- && (TYPE_CODE (obj_type) == TYPE_CODE_PTR
- || TYPE_CODE (obj_type) == TYPE_CODE_REF))
+ && (TYPE_CODE (objtype) == TYPE_CODE_PTR
+ || TYPE_CODE (objtype) == TYPE_CODE_REF))
{
temp = value_addr (temp);
}
performned. */
static int
-find_oload_champ_namespace (struct type **arg_types, int nargs,
+find_oload_champ_namespace (struct value **args, int nargs,
const char *func_name,
const char *qualified_name,
struct symbol ***oload_syms,
{
int oload_champ;
- find_oload_champ_namespace_loop (arg_types, nargs,
+ find_oload_champ_namespace_loop (args, nargs,
func_name,
qualified_name, 0,
oload_syms, oload_champ_bv,
*OLOAD_CHAMP_BV. */
static int
-find_oload_champ_namespace_loop (struct type **arg_types, int nargs,
+find_oload_champ_namespace_loop (struct value **args, int nargs,
const char *func_name,
const char *qualified_name,
int namespace_len,
{
searched_deeper = 1;
- if (find_oload_champ_namespace_loop (arg_types, nargs,
+ if (find_oload_champ_namespace_loop (args, nargs,
func_name, qualified_name,
next_namespace_len,
oload_syms, oload_champ_bv,
/* If we have reached the deepest level perform argument
determined lookup. */
if (!searched_deeper && !no_adl)
- make_symbol_overload_list_adl (arg_types, nargs, func_name);
+ {
+ int ix;
+ struct type **arg_types;
+
+ /* Prepare list of argument types for overload resolution. */
+ arg_types = (struct type **)
+ alloca (nargs * (sizeof (struct type *)));
+ for (ix = 0; ix < nargs; ix++)
+ arg_types[ix] = value_type (args[ix]);
+ make_symbol_overload_list_adl (arg_types, nargs, func_name);
+ }
while (new_oload_syms[num_fns])
++num_fns;
- new_oload_champ = find_oload_champ (arg_types, nargs, 0, num_fns,
+ new_oload_champ = find_oload_champ (args, nargs, 0, num_fns,
NULL, new_oload_syms,
&new_oload_champ_bv);
}
}
-/* Look for a function to take NARGS args of types ARG_TYPES. Find
+/* Look for a function to take NARGS args of ARGS. Find
the best match from among the overloaded methods or functions
(depending on METHOD) given by FNS_PTR or OLOAD_SYMS, respectively.
The number of methods/functions in the list is given by NUM_FNS.
It is the caller's responsibility to free *OLOAD_CHAMP_BV. */
static int
-find_oload_champ (struct type **arg_types, int nargs, int method,
+find_oload_champ (struct value **args, int nargs, int method,
int num_fns, struct fn_field *fns_ptr,
struct symbol **oload_syms,
struct badness_vector **oload_champ_bv)
/* Compare parameter types to supplied argument types. Skip
THIS for static methods. */
bv = rank_function (parm_types, nparms,
- arg_types + static_offset,
+ args + static_offset,
nargs - static_offset);
if (!*oload_champ_bv)
int static_offset)
{
int ix;
+ enum oload_classification worst = STANDARD;
for (ix = 1; ix <= nargs - static_offset; ix++)
{
NS_POINTER_CONVERSION_BADNESS or worse return NON_STANDARD. */
else if (compare_ranks (oload_champ_bv->rank[ix],
NS_POINTER_CONVERSION_BADNESS) <= 0)
- return NON_STANDARD; /* Non-standard type conversions
+ worst = NON_STANDARD; /* Non-standard type conversions
needed. */
}
- return STANDARD; /* Only standard conversions needed. */
+ /* If no INCOMPATIBLE classification was found, return the worst one
+ that was found (if any). */
+ return worst;
}
/* C++: return 1 is NAME is a legitimate name for the destructor of
return 0;
}
-/* Given TYPE, a structure/union,
- return 1 if the component named NAME from the ultimate target
- structure/union is defined, otherwise, return 0. */
-
-int
-check_field (struct type *type, const char *name)
-{
- int i;
-
- /* The type may be a stub. */
- CHECK_TYPEDEF (type);
-
- for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--)
- {
- char *t_field_name = TYPE_FIELD_NAME (type, i);
-
- if (t_field_name && (strcmp_iw (t_field_name, name) == 0))
- return 1;
- }
-
- /* C++: If it was not found as a data field, then try to return it
- as a pointer to a method. */
-
- for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; --i)
- {
- if (strcmp_iw (TYPE_FN_FIELDLIST_NAME (type, i), name) == 0)
- return 1;
- }
-
- for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
- if (check_field (TYPE_BASECLASS (type, i), name))
- return 1;
-
- return 0;
-}
-
/* C++: Given an aggregate type CURTYPE, and a member name NAME,
return the appropriate member (or the address of the member, if
WANT_ADDRESS). This function is used to resolve user expressions
for (i = 0; i < TYPE_NFIELDS (t2); ++i)
{
if (compare_ranks (rank_one_type (TYPE_FIELD_TYPE (t1, start + i),
- TYPE_FIELD_TYPE (t2, i)),
+ TYPE_FIELD_TYPE (t2, i), NULL),
EXACT_MATCH_BADNESS) != 0)
return 0;
}
for (i = TYPE_NFIELDS (t) - 1; i >= TYPE_N_BASECLASSES (t); i--)
{
- char *t_field_name = TYPE_FIELD_NAME (t, i);
+ const char *t_field_name = TYPE_FIELD_NAME (t, i);
if (t_field_name && strcmp (t_field_name, name) == 0)
{
for (i = TYPE_NFN_FIELDS (t) - 1; i >= 0; --i)
{
- char *t_field_name = TYPE_FN_FIELDLIST_NAME (t, i);
+ const char *t_field_name = TYPE_FN_FIELDLIST_NAME (t, i);
char dem_opname[64];
if (strncmp (t_field_name, "__", 2) == 0
return result;
}
-/* Given a pointer value V, find the real (RTTI) type of the object it
- points to.
+/* Given a pointer or a reference value V, find its real (RTTI) type.
Other parameters FULL, TOP, USING_ENC as with value_rtti_type()
and refer to the values computed for the object pointed to. */
struct type *
-value_rtti_target_type (struct value *v, int *full,
- int *top, int *using_enc)
+value_rtti_indirect_type (struct value *v, int *full,
+ int *top, int *using_enc)
{
struct value *target;
+ struct type *type, *real_type, *target_type;
+
+ type = value_type (v);
+ type = check_typedef (type);
+ if (TYPE_CODE (type) == TYPE_CODE_REF)
+ target = coerce_ref (v);
+ else if (TYPE_CODE (type) == TYPE_CODE_PTR)
+ target = value_ind (v);
+ else
+ return NULL;
- target = value_ind (v);
+ real_type = value_rtti_type (target, full, top, using_enc);
- return value_rtti_type (target, full, top, using_enc);
+ if (real_type)
+ {
+ /* Copy qualifiers to the referenced object. */
+ target_type = value_type (target);
+ real_type = make_cv_type (TYPE_CONST (target_type),
+ TYPE_VOLATILE (target_type), real_type, NULL);
+ if (TYPE_CODE (type) == TYPE_CODE_REF)
+ real_type = lookup_reference_type (real_type);
+ else if (TYPE_CODE (type) == TYPE_CODE_PTR)
+ real_type = lookup_pointer_type (real_type);
+ else
+ internal_error (__FILE__, __LINE__, _("Unexpected value type."));
+
+ /* Copy qualifiers to the pointer/reference. */
+ real_type = make_cv_type (TYPE_CONST (type), TYPE_VOLATILE (type),
+ real_type, NULL);
+ }
+
+ return real_type;
}
/* Given a value pointed to by ARGP, check its real run-time type, and
if (!real_type || real_type == value_enclosing_type (argp))
return argp;
+ /* In a destructor we might see a real type that is a superclass of
+ the object's type. In this case it is better to leave the object
+ as-is. */
+ if (full
+ && TYPE_LENGTH (real_type) < TYPE_LENGTH (value_enclosing_type (argp)))
+ return argp;
+
/* If we have the full object, but for some reason the enclosing
type is wrong, set it. */
/* pai: FIXME -- sounds iffy */
}
-/* Return the value of the local variable, if one exists.
- Flag COMPLAIN signals an error if the request is made in an
- inappropriate context. */
+/* Return the value of the local variable, if one exists. Throw error
+ otherwise, such as if the request is made in an inappropriate context. */
struct value *
-value_of_this (const struct language_defn *lang, int complain)
+value_of_this (const struct language_defn *lang)
{
struct symbol *sym;
struct block *b;
- struct value * ret;
struct frame_info *frame;
if (!lang->la_name_of_this)
- {
- if (complain)
- error (_("no `this' in current language"));
- return 0;
- }
+ error (_("no `this' in current language"));
- if (complain)
- frame = get_selected_frame (_("no frame selected"));
- else
- {
- frame = deprecated_safe_get_selected_frame ();
- if (frame == 0)
- return 0;
- }
+ frame = get_selected_frame (_("no frame selected"));
b = get_frame_block (frame, NULL);
sym = lookup_language_this (lang, b);
if (sym == NULL)
+ error (_("current stack frame does not contain a variable named `%s'"),
+ lang->la_name_of_this);
+
+ return read_var_value (sym, frame);
+}
+
+/* Return the value of the local variable, if one exists. Return NULL
+ otherwise. Never throw error. */
+
+struct value *
+value_of_this_silent (const struct language_defn *lang)
+{
+ struct value *ret = NULL;
+ volatile struct gdb_exception except;
+
+ TRY_CATCH (except, RETURN_MASK_ERROR)
{
- if (complain)
- error (_("current stack frame does not contain a variable named `%s'"),
- lang->la_name_of_this);
- else
- return NULL;
+ ret = value_of_this (lang);
}
- ret = read_var_value (sym, frame);
- if (ret == 0 && complain)
- error (_("`%s' argument unreadable"), lang->la_name_of_this);
return ret;
}
array_type = check_typedef (value_type (array));
if (TYPE_CODE (array_type) != TYPE_CODE_ARRAY
- && TYPE_CODE (array_type) != TYPE_CODE_STRING
- && TYPE_CODE (array_type) != TYPE_CODE_BITSTRING)
+ && TYPE_CODE (array_type) != TYPE_CODE_STRING)
error (_("cannot take slice of non-array"));
range_type = TYPE_INDEX_TYPE (array_type);
TYPE_TARGET_TYPE (range_type),
lowbound,
lowbound + length - 1);
- if (TYPE_CODE (array_type) == TYPE_CODE_BITSTRING)
- {
- int i;
-
- slice_type = create_set_type ((struct type *) NULL,
- slice_range_type);
- TYPE_CODE (slice_type) = TYPE_CODE_BITSTRING;
- slice = value_zero (slice_type, not_lval);
- for (i = 0; i < length; i++)
- {
- int element = value_bit_index (array_type,
- value_contents (array),
- lowbound + i);
-
- if (element < 0)
- error (_("internal error accessing bitstring"));
- else if (element > 0)
- {
- int j = i % TARGET_CHAR_BIT;
-
- if (gdbarch_bits_big_endian (get_type_arch (array_type)))
- j = TARGET_CHAR_BIT - 1 - j;
- value_contents_raw (slice)[i / TARGET_CHAR_BIT] |= (1 << j);
- }
- }
- /* We should set the address, bitssize, and bitspos, so the
- slice can be used on the LHS, but that may require extensions
- to value_assign. For now, just leave as a non_lval.
- FIXME. */
- }
- else
{
struct type *element_type = TYPE_TARGET_TYPE (array_type);
LONGEST offset =