summaryrefslogtreecommitdiff
path: root/gdb/valops.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/valops.c')
-rw-r--r--gdb/valops.c641
1 files changed, 392 insertions, 249 deletions
diff --git a/gdb/valops.c b/gdb/valops.c
index 7cc025d4eff..b3515d274b2 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -30,6 +30,7 @@
#include "demangle.h"
#include "language.h"
#include "gdbcmd.h"
+#include "cp-abi.h"
#include "regcache.h"
#include "cp-abi.h"
@@ -43,6 +44,12 @@ extern int hp_som_som_object_present;
extern int overload_debug;
/* Local functions. */
+enum looking_for_baseclass_type
+ {
+ no_baseclass,
+ only_baseclass,
+ struct_or_baseclass
+ };
static int typecmp (int staticp, struct type *t1[], value_ptr t2[]);
static CORE_ADDR find_function_addr (value_ptr, struct type **);
@@ -50,11 +57,14 @@ static value_ptr value_arg_coerce (value_ptr, struct type *, int);
static CORE_ADDR value_push (CORE_ADDR, value_ptr);
-
-static value_ptr search_struct_field (char *, value_ptr, int,
- struct type *, int);
-
-static value_ptr search_struct_method (char *, value_ptr *,
+static value_ptr
+search_struct_field (const char *, value_ptr, int, struct type *,
+ enum looking_for_baseclass_type, char *);
+static value_ptr
+search_struct_field_aux (const char *, value_ptr, int, struct type *,
+ enum looking_for_baseclass_type,
+ int *, char *, struct type **, char *);
+static value_ptr search_struct_method (const char *, value_ptr *,
value_ptr *,
int, int *, struct type *);
@@ -113,7 +123,7 @@ find_function_in_inferior (char *name)
struct type *type;
CORE_ADDR maddr;
type = lookup_pointer_type (builtin_type_char);
- type = lookup_function_type (type);
+ type = (struct type *)make_function_type (NULL, type, 0, NULL, 0);
type = lookup_pointer_type (type);
maddr = SYMBOL_VALUE_ADDRESS (msymbol);
return value_from_pointer (type, maddr);
@@ -183,10 +193,11 @@ value_cast (struct type *type, register value_ptr arg2)
where N is sizeof(OBJECT)/sizeof(TYPE). */
if (code1 == TYPE_CODE_ARRAY)
{
- struct type *element_type = TYPE_TARGET_TYPE (type);
+ struct type *element_type = ARRAY_ELEMENT_TYPE (type);
unsigned element_length = TYPE_LENGTH (check_typedef (element_type));
- if (element_length > 0
- && TYPE_ARRAY_UPPER_BOUND_TYPE (type) == BOUND_CANNOT_BE_DETERMINED)
+#if TYPEFIX
+ if (current_language->la_language == language_fortran && element_length > 0
+ && TYPE_ARRAY_UPPER_BOUND_TYPE (type) == BT_cannot_be_determined)
{
struct type *range_type = TYPE_INDEX_TYPE (type);
int val_length = TYPE_LENGTH (type2);
@@ -196,7 +207,7 @@ value_cast (struct type *type, register value_ptr arg2)
new_length = val_length / element_length;
if (val_length % element_length != 0)
warning ("array element type size does not divide object size in cast");
- /* FIXME-type-allocation: need a way to free this type when we are
+ /* TYPEFIX-type-allocation: need a way to free this type when we are
done with it. */
range_type = create_range_type ((struct type *) NULL,
TYPE_TARGET_TYPE (range_type),
@@ -206,6 +217,7 @@ value_cast (struct type *type, register value_ptr arg2)
element_type, range_type);
return arg2;
}
+#endif
}
if (current_language->c_style_arrays
@@ -242,7 +254,7 @@ value_cast (struct type *type, register value_ptr arg2)
type of the target as a superclass. If so, we'll need to
offset the object in addition to changing its type. */
value_ptr v = search_struct_field (type_name_no_tag (type),
- arg2, 0, type2, 1);
+ arg2, 0, type2, only_baseclass, 0);
if (v)
{
VALUE_TYPE (v) = type;
@@ -263,7 +275,7 @@ value_cast (struct type *type, register value_ptr arg2)
unsigned int *ptr;
value_ptr retvalp;
- switch (TYPE_CODE (TYPE_TARGET_TYPE (type2)))
+ switch (TYPE_CODE (POINTER_TARGET_TYPE (type2)))
{
/* With HP aCC, pointers to data members have a bias */
case TYPE_CODE_MEMBER:
@@ -314,8 +326,8 @@ value_cast (struct type *type, register value_ptr arg2)
{
if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_PTR)
{
- struct type *t1 = check_typedef (TYPE_TARGET_TYPE (type));
- struct type *t2 = check_typedef (TYPE_TARGET_TYPE (type2));
+ struct type *t1 = check_typedef (POINTER_TARGET_TYPE (type));
+ struct type *t2 = check_typedef (POINTER_TARGET_TYPE (type2));
if (TYPE_CODE (t1) == TYPE_CODE_STRUCT
&& TYPE_CODE (t2) == TYPE_CODE_STRUCT
&& !value_logical_not (arg2))
@@ -328,7 +340,7 @@ value_cast (struct type *type, register value_ptr arg2)
if (TYPE_NAME (t1) != NULL)
{
v = search_struct_field (type_name_no_tag (t1),
- value_ind (arg2), 0, t2, 1);
+ value_ind (arg2), 0, t2, only_baseclass, 0);
if (v)
{
v = value_addr (v);
@@ -344,7 +356,7 @@ value_cast (struct type *type, register value_ptr arg2)
if (TYPE_NAME (t2) != NULL)
{
v = search_struct_field (type_name_no_tag (t2),
- value_zero (t1, not_lval), 0, t1, 1);
+ value_zero (t1, not_lval), 0, t1, only_baseclass, 0);
if (v)
{
value_ptr v2 = value_ind (arg2);
@@ -369,6 +381,7 @@ value_cast (struct type *type, register value_ptr arg2)
VALUE_POINTED_TO_OFFSET (arg2) = 0; /* pai: chk_val */
return arg2;
}
+#if TYPEFIX
else if (chill_varying_type (type))
{
struct type *range1, *range2, *eltype1, *eltype2;
@@ -412,6 +425,7 @@ value_cast (struct type *type, register value_ptr arg2)
(count1 - count2) * TYPE_LENGTH (eltype2));
return val;
}
+#endif
else if (VALUE_LVAL (arg2) == lval_memory)
{
return value_at_lazy (type, VALUE_ADDRESS (arg2) + VALUE_OFFSET (arg2),
@@ -465,8 +479,8 @@ value_at (struct type *type, CORE_ADDR addr, asection *sect)
if (GDB_TARGET_IS_D10V
&& TYPE_CODE (type) == TYPE_CODE_PTR
- && TYPE_TARGET_TYPE (type)
- && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC))
+ && POINTER_TARGET_TYPE (type)
+ && (TYPE_CODE (POINTER_TARGET_TYPE (type)) == TYPE_CODE_FUNC))
{
/* pointer to function */
unsigned long num;
@@ -536,8 +550,8 @@ value_fetch_lazy (register value_ptr val)
struct type *type = VALUE_TYPE (val);
if (GDB_TARGET_IS_D10V
&& TYPE_CODE (type) == TYPE_CODE_PTR
- && TYPE_TARGET_TYPE (type)
- && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC))
+ && POINTER_TARGET_TYPE (type)
+ && (TYPE_CODE (POINTER_TARGET_TYPE (type)) == TYPE_CODE_FUNC))
{
/* pointer to function */
unsigned long num;
@@ -1001,13 +1015,13 @@ value_ind (value_ptr arg1)
/* We may be pointing to something embedded in a larger object */
/* Get the real type of the enclosing object */
enc_type = check_typedef (VALUE_ENCLOSING_TYPE (arg1));
- enc_type = TYPE_TARGET_TYPE (enc_type);
+ enc_type = POINTER_TARGET_TYPE (enc_type);
/* Retrieve the enclosing object pointed to */
arg2 = value_at_lazy (enc_type,
value_as_pointer (arg1) - VALUE_POINTED_TO_OFFSET (arg1),
VALUE_BFD_SECTION (arg1));
/* Re-adjust type */
- VALUE_TYPE (arg2) = TYPE_TARGET_TYPE (base_type);
+ VALUE_TYPE (arg2) = POINTER_TARGET_TYPE (base_type);
/* Add embedding info */
arg2 = value_change_enclosing_type (arg2, enc_type);
VALUE_EMBEDDED_OFFSET (arg2) = VALUE_POINTED_TO_OFFSET (arg1);
@@ -1211,7 +1225,7 @@ value_arg_coerce (value_ptr arg, struct type *param_type, int is_prototyped)
break;
case TYPE_CODE_ARRAY:
if (current_language->c_style_arrays)
- type = lookup_pointer_type (TYPE_TARGET_TYPE (type));
+ type = lookup_pointer_type (ARRAY_ELEMENT_TYPE (type));
break;
case TYPE_CODE_UNDEF:
case TYPE_CODE_PTR:
@@ -1248,7 +1262,12 @@ find_function_addr (value_ptr function, struct type **retval_type)
part of it. */
/* Determine address to call. */
- if (code == TYPE_CODE_FUNC || code == TYPE_CODE_METHOD)
+ if (code == TYPE_CODE_FUNC)
+ {
+ funaddr = VALUE_ADDRESS (function);
+ value_type = FUNCTION_RETURN_VALUE (ftype);
+ }
+ else if (code == TYPE_CODE_METHOD)
{
funaddr = VALUE_ADDRESS (function);
value_type = TYPE_TARGET_TYPE (ftype);
@@ -1256,9 +1275,13 @@ find_function_addr (value_ptr function, struct type **retval_type)
else if (code == TYPE_CODE_PTR)
{
funaddr = value_as_pointer (function);
- ftype = check_typedef (TYPE_TARGET_TYPE (ftype));
- if (TYPE_CODE (ftype) == TYPE_CODE_FUNC
- || TYPE_CODE (ftype) == TYPE_CODE_METHOD)
+ ftype = check_typedef (POINTER_TARGET_TYPE (ftype));
+ if (TYPE_CODE (ftype) == TYPE_CODE_FUNC)
+ {
+ funaddr =CONVERT_FROM_FUNC_PTR_ADDR (funaddr);
+ value_type = FUNCTION_RETURN_VALUE (ftype);
+ }
+ else if (TYPE_CODE (ftype) == TYPE_CODE_METHOD)
{
funaddr = CONVERT_FROM_FUNC_PTR_ADDR (funaddr);
value_type = TYPE_TARGET_TYPE (ftype);
@@ -1476,7 +1499,7 @@ hand_function_call (value_ptr function, int nargs, value_ptr *args)
if (param_type)
/* if this parameter is a pointer to function */
if (TYPE_CODE (param_type) == TYPE_CODE_PTR)
- if (TYPE_CODE (param_type->target_type) == TYPE_CODE_FUNC)
+ if (TYPE_CODE (POINTER_TARGET_TYPE(param_type)) == TYPE_CODE_FUNC)
/* elz: FIXME here should go the test about the compiler used
to compile the target. We want to issue the error
message only if the compiler used was HP's aCC.
@@ -1817,7 +1840,7 @@ value_array (int lowbound, int highbound, value_ptr *elemvec)
int idx;
unsigned int typelength;
value_ptr val;
- struct type *rangetype;
+ struct range_type *rangetype;
struct type *arraytype;
CORE_ADDR addr;
@@ -1838,9 +1861,9 @@ value_array (int lowbound, int highbound, value_ptr *elemvec)
}
}
- rangetype = create_range_type ((struct type *) NULL, builtin_type_int,
+ rangetype = make_range_type (NULL, builtin_type_int,
lowbound, highbound);
- arraytype = create_array_type ((struct type *) NULL,
+ arraytype = (struct type *)make_array_type (NULL,
VALUE_ENCLOSING_TYPE (elemvec[0]), rangetype);
if (!current_language->c_style_arrays)
@@ -1887,11 +1910,9 @@ value_string (char *ptr, int len)
{
value_ptr val;
int lowbound = current_language->string_lower_bound;
- struct type *rangetype = create_range_type ((struct type *) NULL,
- builtin_type_int,
- lowbound, len + lowbound - 1);
- struct type *stringtype
- = create_string_type ((struct type *) NULL, rangetype);
+ struct range_type *rangetype = make_range_type (NULL, builtin_type_int,
+ lowbound, len + lowbound - 1);
+ struct type *stringtype = (struct type *)make_string_type (NULL, rangetype);
CORE_ADDR addr;
if (current_language->c_style_arrays == 0)
@@ -1916,9 +1937,8 @@ value_ptr
value_bitstring (char *ptr, int len)
{
value_ptr val;
- struct type *domain_type = create_range_type (NULL, builtin_type_int,
- 0, len - 1);
- struct type *type = create_set_type ((struct type *) NULL, domain_type);
+ struct range_type *domain_type = make_range_type (NULL, builtin_type_int, 0, len - 1);
+ struct type *type = (struct type *)make_set_type (NULL, domain_type);
TYPE_CODE (type) = TYPE_CODE_BITSTRING;
val = allocate_value (type);
memcpy (VALUE_CONTENTS_RAW (val), ptr, TYPE_LENGTH (type));
@@ -1982,13 +2002,16 @@ typecmp (int staticp, struct type *t1[], value_ptr t2[])
while ( TYPE_CODE(tt1) == TYPE_CODE_REF ||
TYPE_CODE (tt1) == TYPE_CODE_PTR)
{
- tt1 = check_typedef( TYPE_TARGET_TYPE(tt1) );
+ tt1 = check_typedef( POINTER_TARGET_TYPE(tt1) );
}
while ( TYPE_CODE(tt2) == TYPE_CODE_ARRAY ||
TYPE_CODE(tt2) == TYPE_CODE_PTR ||
TYPE_CODE(tt2) == TYPE_CODE_REF)
{
- tt2 = check_typedef( TYPE_TARGET_TYPE(tt2) );
+ while (TYPE_CODE (tt2) == TYPE_CODE_REF || TYPE_CODE (tt2) == TYPE_CODE_PTR)
+ tt2 = check_typedef (POINTER_TARGET_TYPE (tt2));
+ while (TYPE_CODE (tt2) == TYPE_CODE_ARRAY)
+ tt2 = check_typedef (ARRAY_ELEMENT_TYPE (tt2));
}
if (TYPE_CODE (tt1) == TYPE_CODE (tt2))
continue;
@@ -2010,34 +2033,123 @@ typecmp (int staticp, struct type *t1[], value_ptr t2[])
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. */
+ looking_for_baseclass has three possible values :
+ 1) no_baseclass : look for structure field.
+ 2) only_baseclass : look for baseclass named NAME.
+ 3) struct_or_baseclass : look for structure field first, and then
+ the baseclass named NAME. Return the first
+ structure field if it is found.
+ The value is used when hp_som_som_object_present
+ is true. */
static value_ptr
-search_struct_field (char *name, register value_ptr arg1, int offset,
- register struct type *type, int looking_for_baseclass)
+search_struct_field (name, arg1, offset, type, looking_for_baseclass,
+ domain_name)
+ const char *name;
+ register value_ptr arg1;
+ int offset;
+ register struct type *type;
+ enum looking_for_baseclass_type looking_for_baseclass;
+ char *domain_name;
+{
+ int found = 0;
+ char found_class[1024];
+ value_ptr v;
+ struct type *vbase = NULL;
+
+ found_class[0] = '\000';
+
+ v = search_struct_field_aux (name, arg1, offset, type,
+ looking_for_baseclass, &found,
+ found_class, &vbase, domain_name);
+ if (found > 1)
+ warning ("%s ambiguous; using %s::%s. Use a cast to disambiguate.",
+ name, found_class, name);
+
+ return v;
+}
+
+static value_ptr
+search_struct_field_aux (name, arg1, offset, type,
+ looking_for_baseclass, found,
+ found_class_name, vbase, domain_name)
+ const char *name;
+ value_ptr arg1;
+ int offset;
+ register struct type *type;
+ enum looking_for_baseclass_type looking_for_baseclass;
+ int *found;
+ char *found_class_name;
+ struct type **vbase;
+ char *domain_name;
{
int i;
+ value_ptr retval = NULL;
+ char tmp_class_name[1024];
+ int tmp_found = 0;
+ int assigned = 0;
int nbases = TYPE_N_BASECLASSES (type);
+ tmp_class_name[0] = '\000';
+
CHECK_TYPEDEF (type);
- if (!looking_for_baseclass)
+ if (looking_for_baseclass == no_baseclass ||
+ looking_for_baseclass == struct_or_baseclass)
for (i = TYPE_NFIELDS (type) - 1; i >= nbases; i--)
{
char *t_field_name = TYPE_FIELD_NAME (type, i);
if (t_field_name && (strcmp_iw (t_field_name, name) == 0))
{
- value_ptr v;
+ value_ptr v = NULL;
if (TYPE_FIELD_STATIC (type, i))
v = value_static_field (type, i);
+ if (v != NULL)
+ {
+ if (!*found)
+ {
+ /* Record return value and class name, and continue
+ looking for possible ambiguous members */
+ char *class_name = TYPE_TAG_NAME (type);
+ retval = v;
+ if (class_name)
+ strcpy (found_class_name, class_name);
+ else
+ found_class_name = NULL;
+ }
+ (*found)++;
+ }
else
- v = value_primitive_field (arg1, offset, i, type);
- if (v == 0)
- error ("there is no field named %s", name);
- return v;
- }
+ {
+ char *fullname = (domain_name ?
+ (strncmp (domain_name, "data member of", 14) ?
+ NULL : &domain_name[15])
+ : NULL );
+ if (!fullname || !strcmp(TYPE_TAG_NAME(type), fullname))
+ {
+ v = value_primitive_field (arg1, offset, i, type);
+ if (v != NULL)
+ {
+ if (!*found)
+ {
+ /* Record return value and class name, and continue
+ looking for possible ambiguous members */
+ char *class_name = TYPE_TAG_NAME (type);
+ retval = v;
+ if (class_name)
+ strcpy (found_class_name, class_name);
+ else
+ found_class_name = NULL;
+ }
+ (*found)++;
+ }
+ }
+ }
+
+ if (v == 0 && looking_for_baseclass != struct_or_baseclass)
+ error ("Couldn't retrieve field named %s", name);
+ }
if (t_field_name
&& (t_field_name[0] == '\0'
@@ -2070,14 +2182,40 @@ search_struct_field (char *name, register value_ptr arg1, int offset,
&& 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);
- if (v)
- return v;
- }
- }
+ v = search_struct_field_aux (name, arg1, new_offset,
+ field_type,
+ looking_for_baseclass,
+ &tmp_found, tmp_class_name,
+ vbase, domain_name);
+ if (!*found && v)
+ {
+ /* Record return value and class name, and continue
+ looking for possible ambiguous members */
+ retval = v;
+ /* TYPE_TAG_NAME can be null in case of an anonymous union */
+ if (TYPE_TAG_NAME (type))
+ strcpy (found_class_name, TYPE_TAG_NAME (type));
+ else
+ strcpy (found_class_name, " ");
+ strcat (found_class_name, "::");
+ strcat (found_class_name, tmp_class_name);
+ }
+ *found += tmp_found;
+ tmp_found = 0;
+ }
+ }
}
+ /* Return the structure field if it is found. */
+ if (*found > 0 && looking_for_baseclass == struct_or_baseclass)
+ return retval;
+
+ /* RM: If we are looking for a structure field, and we have found
+ one, don't look through the baseclasses -- names there are
+ hidden. ANSI C++ standard, section 10.2 */
+ if (*found > 0 && looking_for_baseclass == no_baseclass)
+ return retval;
+
for (i = 0; i < nbases; i++)
{
value_ptr v;
@@ -2092,12 +2230,12 @@ search_struct_field (char *name, register value_ptr arg1, int offset,
if (BASETYPE_VIA_VIRTUAL (type, i))
{
int boffset;
- value_ptr v2 = allocate_value (basetype);
+ value_ptr v2 = allocate_value (VALUE_ENCLOSING_TYPE (arg1));
boffset = baseclass_offset (type, i,
- VALUE_CONTENTS (arg1) + offset,
+ &arg1, VALUE_CONTENTS (arg1) + offset,
VALUE_ADDRESS (arg1)
- + VALUE_OFFSET (arg1) + offset);
+ + VALUE_OFFSET (arg1) + offset, offset);
if (boffset == -1)
error ("virtual baseclass botch");
@@ -2110,12 +2248,13 @@ search_struct_field (char *name, register value_ptr arg1, int offset,
{
CORE_ADDR base_addr;
- base_addr = VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1) + boffset;
+ base_addr = VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1) + boffset;
if (target_read_memory (base_addr, VALUE_CONTENTS_RAW (v2),
TYPE_LENGTH (basetype)) != 0)
error ("virtual baseclass botch");
VALUE_LVAL (v2) = lval_memory;
VALUE_ADDRESS (v2) = base_addr;
+ assigned = 1;
}
else
{
@@ -2129,113 +2268,125 @@ search_struct_field (char *name, register value_ptr arg1, int offset,
VALUE_CONTENTS_RAW (arg1) + boffset,
TYPE_LENGTH (basetype));
}
-
- if (found_baseclass)
- return v2;
- v = search_struct_field (name, v2, 0, TYPE_BASECLASS (type, i),
- looking_for_baseclass);
- }
+#if 0
+ if (!assigned)
+ {
+ VALUE_LVAL (v2) = VALUE_LVAL (arg1);
+ VALUE_ADDRESS (v2) = VALUE_ADDRESS (arg1);
+ }
+ /* Earlier, this code used to allocate a value of type
+ basetype and copy the contents of arg1 at the
+ appropriate offset into the new value. This doesn't
+ work because there is important stuff (virtual bases,
+ for example) that could be anywhere in the contents
+ of arg1, and not just within the length of a basetype
+ object. In particular the boffset below could be
+ negative, with the HP/Taligent C++ runtime system.
+ So, the only way to ensure that required information
+ is not lost is to always allocate a value of the same
+ type as arg1 and to fill it with the _entire_
+ contents of arg1. It sounds wasteful, but there is
+ really no way around it if later member lookup,
+ casts, etc. have to work correctly with the returned
+ value. */
+
+
+ VALUE_TYPE (v2) = basetype;
+ VALUE_OFFSET (v2) = VALUE_OFFSET (arg1);
+ VALUE_EMBEDDED_OFFSET (v2)
+ = VALUE_EMBEDDED_OFFSET (arg1) + offset + boffset;
+ if (VALUE_LAZY (arg1))
+ VALUE_LAZY (v2) = 1;
+ else
+ memcpy ((char *) (v2)->aligner.contents,
+ (char *) (arg1)->aligner.contents,
+ TYPE_LENGTH (VALUE_ENCLOSING_TYPE (arg1)));
+#endif
+ if (found_baseclass)
+ {
+ /*return v2; */
+
+ if (!*found) /* not yet found anything */
+ {
+ /* Record return value and class name, and continue
+ looking for possible ambiguous members */
+ retval = v2;
+ strcpy (found_class_name, TYPE_TAG_NAME (type));
+ }
+ /* Don't count virtual bases twice when deciding ambiguity */
+ if (*vbase != basetype) /* works for null *vbase */
+ (*found)++;
+ /* Is this the first virtual base where we "found" something? */
+ if (!*vbase)
+ *vbase = basetype;
+ }
+ else
+ /* base not found, or looking for member */
+ {
+ v = search_struct_field_aux (name, /*arg1*/v2, 0/*offset + boffset*/,
+ TYPE_BASECLASS (type, i),
+ looking_for_baseclass, &tmp_found,
+ tmp_class_name, vbase, domain_name);
+ if (!*found && v)
+ {
+ /* Record return value and class name, and continue
+ looking for possible ambiguous members */
+ retval = v;
+ /* TYPE_TAG_NAME can be null in case of an anonymous union */
+ if (TYPE_TAG_NAME (type))
+ strcpy (found_class_name, TYPE_TAG_NAME (type));
+ else
+ strcpy (found_class_name, " ");
+ strcat (found_class_name, "::");
+ strcat (found_class_name, tmp_class_name);
+ }
+ /* Don't count virtual bases twice when deciding ambiguity */
+ if (*vbase != basetype) /* works for null *vbase */
+ *found += tmp_found;
+ /* Is this the first virtual base where we "found" something? */
+ if (!*vbase)
+ *vbase = basetype;
+ tmp_found = 0;
+ }
+ }
else if (found_baseclass)
- v = value_primitive_field (arg1, offset, i, type);
+ {
+ v = value_primitive_field (arg1, offset, i, type);
+ if (!*found)
+ {
+ /* Record return value and class name, and continue
+ looking for possible ambiguous members */
+ retval = v;
+ strcpy (found_class_name, TYPE_TAG_NAME (type));
+ }
+ (*found)++;
+ }
else
- v = search_struct_field (name, arg1,
- offset + TYPE_BASECLASS_BITPOS (type, i) / 8,
- basetype, looking_for_baseclass);
- if (v)
- return v;
- }
- return NULL;
-}
-
-
-/* Return the offset (in bytes) of the virtual base of type BASETYPE
- * in an object pointed to by VALADDR (on the host), assumed to be of
- * type TYPE. OFFSET is number of bytes beyond start of ARG to start
- * looking (in case VALADDR is the contents of an enclosing object).
- *
- * This routine recurses on the primary base of the derived class because
- * the virtual base entries of the primary base appear before the other
- * virtual base entries.
- *
- * If the virtual base is not found, a negative integer is returned.
- * The magnitude of the negative integer is the number of entries in
- * the virtual table to skip over (entries corresponding to various
- * ancestral classes in the chain of primary bases).
- *
- * Important: This assumes the HP / Taligent C++ runtime
- * conventions. Use baseclass_offset() instead to deal with g++
- * conventions. */
-
-void
-find_rt_vbase_offset (struct type *type, struct type *basetype, char *valaddr,
- int offset, int *boffset_p, int *skip_p)
-{
- int boffset; /* offset of virtual base */
- int index; /* displacement to use in virtual table */
- int skip;
-
- value_ptr vp;
- CORE_ADDR vtbl; /* the virtual table pointer */
- struct type *pbc; /* the primary base class */
-
- /* Look for the virtual base recursively in the primary base, first.
- * This is because the derived class object and its primary base
- * subobject share the primary virtual table. */
-
- boffset = 0;
- pbc = TYPE_PRIMARY_BASE (type);
- if (pbc)
- {
- find_rt_vbase_offset (pbc, basetype, valaddr, offset, &boffset, &skip);
- if (skip < 0)
- {
- *boffset_p = boffset;
- *skip_p = -1;
- return;
- }
- }
- else
- skip = 0;
-
-
- /* Find the index of the virtual base according to HP/Taligent
- runtime spec. (Depth-first, left-to-right.) */
- index = virtual_base_index_skip_primaries (basetype, type);
-
- if (index < 0)
- {
- *skip_p = skip + virtual_base_list_length_skip_primaries (type);
- *boffset_p = 0;
- return;
+ {
+ v = search_struct_field_aux (name, arg1,
+ offset + TYPE_BASECLASS_BITPOS (type, i) / 8,
+ basetype, looking_for_baseclass, &tmp_found,
+ tmp_class_name, vbase, domain_name);
+ if (!*found && v)
+ {
+ /* Record return value and class name, and continue
+ looking for possible ambiguous members */
+ retval = v;
+ /* TYPE_TAG_NAME can be null in case of an anonymous union */
+ if (TYPE_TAG_NAME (type))
+ strcpy (found_class_name, TYPE_TAG_NAME (type));
+ else
+ strcpy (found_class_name, " ");
+ strcat (found_class_name, "::");
+ strcat (found_class_name, tmp_class_name);
+ }
+ *found += tmp_found;
+ tmp_found = 0;
+ }
}
-
- /* pai: FIXME -- 32x64 possible problem */
- /* First word (4 bytes) in object layout is the vtable pointer */
- vtbl = *(CORE_ADDR *) (valaddr + offset);
-
- /* Before the constructor is invoked, things are usually zero'd out. */
- if (vtbl == 0)
- error ("Couldn't find virtual table -- object may not be constructed yet.");
-
-
- /* Find virtual base's offset -- jump over entries for primary base
- * ancestors, then use the index computed above. But also adjust by
- * HP_ACC_VBASE_START for the vtable slots before the start of the
- * virtual base entries. Offset is negative -- virtual base entries
- * appear _before_ the address point of the virtual table. */
-
- /* pai: FIXME -- 32x64 problem, if word = 8 bytes, change multiplier
- & use long type */
-
- /* epstein : FIXME -- added param for overlay section. May not be correct */
- vp = value_at (builtin_type_int, vtbl + 4 * (-skip - index - HP_ACC_VBASE_START), NULL);
- boffset = value_as_long (vp);
- *skip_p = -1;
- *boffset_p = boffset;
- return;
+ return retval;
}
-
/* 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.
@@ -2243,7 +2394,7 @@ find_rt_vbase_offset (struct type *type, struct type *basetype, char *valaddr,
else return NULL. */
static value_ptr
-search_struct_method (char *name, register value_ptr *arg1p,
+search_struct_method (const char *name, register value_ptr *arg1p,
register value_ptr *args, int offset,
int *static_memfuncp, register struct type *type)
{
@@ -2300,46 +2451,31 @@ search_struct_method (char *name, register value_ptr *arg1p,
if (BASETYPE_VIA_VIRTUAL (type, i))
{
- if (TYPE_HAS_VTABLE (type))
- {
- /* HP aCC compiled type, search for virtual base offset
- according to HP/Taligent runtime spec. */
- int skip;
- find_rt_vbase_offset (type, TYPE_BASECLASS (type, i),
- VALUE_CONTENTS_ALL (*arg1p),
- offset + VALUE_EMBEDDED_OFFSET (*arg1p),
- &base_offset, &skip);
- if (skip >= 0)
- error ("Virtual base class offset not found in vtable");
- }
- else
+ struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i));
+ char *base_valaddr;
+
+ /* The virtual base class pointer might have been clobbered by the
+ user program. Make sure that it still points to a valid memory
+ location. */
+
+ if (offset < 0 || offset >= TYPE_LENGTH (type))
{
- struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i));
- char *base_valaddr;
-
- /* The virtual base class pointer might have been clobbered by the
- user program. Make sure that it still points to a valid memory
- location. */
-
- if (offset < 0 || offset >= TYPE_LENGTH (type))
- {
- base_valaddr = (char *) alloca (TYPE_LENGTH (baseclass));
- if (target_read_memory (VALUE_ADDRESS (*arg1p)
- + VALUE_OFFSET (*arg1p) + offset,
- base_valaddr,
- TYPE_LENGTH (baseclass)) != 0)
- error ("virtual baseclass botch");
- }
- else
- base_valaddr = VALUE_CONTENTS (*arg1p) + offset;
-
- base_offset =
- baseclass_offset (type, i, base_valaddr,
- VALUE_ADDRESS (*arg1p)
- + VALUE_OFFSET (*arg1p) + offset);
- if (base_offset == -1)
+ base_valaddr = (char *) alloca (TYPE_LENGTH (baseclass));
+ if (target_read_memory (VALUE_ADDRESS (*arg1p)
+ + VALUE_OFFSET (*arg1p) + offset,
+ base_valaddr,
+ TYPE_LENGTH (baseclass)) != 0)
error ("virtual baseclass botch");
}
+ else
+ base_valaddr = VALUE_CONTENTS (*arg1p) + offset;
+
+ base_offset =
+ baseclass_offset (type, i, arg1p, base_valaddr,
+ VALUE_ADDRESS (*arg1p)
+ + VALUE_OFFSET (*arg1p) + offset, offset);
+ if (base_offset == -1)
+ error ("virtual baseclass botch");
}
else
{
@@ -2414,13 +2550,20 @@ value_struct_elt (register value_ptr *argp, register value_ptr *args,
if (!args)
{
/* if there are no arguments ...do this... */
-
+
/* Try as a field first, because if we succeed, there
is less work to be done. */
- v = search_struct_field (name, *argp, 0, t, 0);
+ if (strncmp (err, "data member", 11))
+ {
+ v = search_struct_field (name, *argp, VALUE_EMBEDDED_OFFSET (*argp), t, no_baseclass, NULL);
+ }
+ else
+ {
+ v = search_struct_field (name, *argp, VALUE_EMBEDDED_OFFSET (*argp), t, struct_or_baseclass, err);
+ }
if (v)
return v;
-
+
/* C++: If it was not found as a data field, then try to
return it as a pointer to a method. */
@@ -2476,7 +2619,7 @@ value_struct_elt (register value_ptr *argp, register value_ptr *args,
/* See if user tried to invoke data as function. If so,
hand it back. If it's not callable (i.e., a pointer to function),
gdb should give an error. */
- v = search_struct_field (name, *argp, 0, t, 0);
+ v = search_struct_field (name, *argp, 0, t, no_baseclass, NULL);
}
if (!v)
@@ -2528,29 +2671,13 @@ find_method_list (value_ptr *argp, char *method, int offset,
int base_offset;
if (BASETYPE_VIA_VIRTUAL (type, i))
{
- if (TYPE_HAS_VTABLE (type))
- {
- /* HP aCC compiled type, search for virtual base offset
- * according to HP/Taligent runtime spec. */
- int skip;
- find_rt_vbase_offset (type, TYPE_BASECLASS (type, i),
- VALUE_CONTENTS_ALL (*argp),
- offset + VALUE_EMBEDDED_OFFSET (*argp),
- &base_offset, &skip);
- if (skip >= 0)
- error ("Virtual base class offset not found in vtable");
- }
- else
- {
- /* probably g++ runtime model */
- base_offset = VALUE_OFFSET (*argp) + offset;
- base_offset =
- baseclass_offset (type, i,
- VALUE_CONTENTS (*argp) + base_offset,
- VALUE_ADDRESS (*argp) + base_offset);
- if (base_offset == -1)
- error ("virtual baseclass botch");
- }
+ base_offset = VALUE_OFFSET (*argp) + offset;
+ base_offset =
+ baseclass_offset (type, i, argp,
+ VALUE_CONTENTS (*argp) + base_offset,
+ VALUE_ADDRESS (*argp) + base_offset, offset);
+ if (base_offset == -1)
+ error ("virtual baseclass botch");
}
else
/* non-virtual base, simply use bit position from debug info */
@@ -2664,7 +2791,7 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method,
register int jj;
register int ix;
- char *obj_type_name = NULL;
+ const char *obj_type_name = NULL;
char *func_name = NULL;
/* Get the list of overloaded methods or functions */
@@ -2678,7 +2805,7 @@ find_overload_match (struct type **arg_types, int nargs, char *name, int method,
value rather than the object itself, so try again */
if ((!obj_type_name || !*obj_type_name) &&
(TYPE_CODE (VALUE_TYPE (obj)) == TYPE_CODE_PTR))
- obj_type_name = TYPE_NAME (TYPE_TARGET_TYPE (VALUE_TYPE (obj)));
+ obj_type_name = TYPE_NAME (POINTER_TARGET_TYPE (VALUE_TYPE (obj)));
fns_ptr = value_find_oload_method_list (&temp, name, 0,
staticp,
@@ -2880,7 +3007,7 @@ destructor_name_p (const char *name, const struct type *type)
if (name[0] == '~')
{
- char *dname = type_name_no_tag (type);
+ const char *dname = type_name_no_tag (type);
char *cp = strchr (dname, '<');
unsigned int len;
@@ -2958,7 +3085,7 @@ check_field (register value_ptr arg1, const char *name)
CHECK_TYPEDEF (t);
if (TYPE_CODE (t) != TYPE_CODE_PTR && TYPE_CODE (t) != TYPE_CODE_REF)
break;
- t = TYPE_TARGET_TYPE (t);
+ t = POINTER_TARGET_TYPE (t);
}
if (TYPE_CODE (t) == TYPE_CODE_MEMBER)
@@ -2981,12 +3108,12 @@ check_field (register value_ptr arg1, const char *name)
value_ptr
value_struct_elt_for_reference (struct type *domain, int offset,
struct type *curtype, char *name,
- struct type *intype)
+ struct type *intype, int look_for_this)
{
register struct type *t = curtype;
register int i;
value_ptr v;
-
+
if (TYPE_CODE (t) != TYPE_CODE_STRUCT
&& TYPE_CODE (t) != TYPE_CODE_UNION)
error ("Internal error: non-aggregate type to value_struct_elt_for_reference");
@@ -2997,6 +3124,7 @@ value_struct_elt_for_reference (struct type *domain, int offset,
if (t_field_name && STREQ (t_field_name, name))
{
+ value_ptr argp;
if (TYPE_FIELD_STATIC (t, i))
{
v = value_static_field (t, i);
@@ -3007,14 +3135,28 @@ value_struct_elt_for_reference (struct type *domain, int offset,
}
if (TYPE_FIELD_PACKED (t, i))
error ("pointers to bitfield members not allowed");
-
+ if (look_for_this)
+ {
+ /* It can be a class data member. */
+ argp = value_of_this (1);
+ if (argp != 0)
+ {
+ char *class_name;
+ class_name = alloca (strlen (TYPE_TAG_NAME(domain)) +strlen ("data member of ")+1);
+ strcat (class_name, "data member of ");
+ strcat (class_name, TYPE_TAG_NAME(domain));
+ v = value_struct_elt (&argp, NULL, name, NULL, class_name);
+ if (v != 0)
+ return v;
+ }
+ }
return value_from_longest
(lookup_reference_type (lookup_member_type (TYPE_FIELD_TYPE (t, i),
domain)),
offset + (LONGEST) (TYPE_FIELD_BITPOS (t, i) >> 3));
}
}
-
+
/* C++: If it was not found as a data field, then try to
return it as a pointer to a method. */
@@ -3026,7 +3168,7 @@ value_struct_elt_for_reference (struct type *domain, int offset,
/* Perform all necessary dereferencing. */
while (intype && TYPE_CODE (intype) == TYPE_CODE_PTR)
- intype = TYPE_TARGET_TYPE (intype);
+ intype = POINTER_TARGET_TYPE (intype);
for (i = TYPE_NFN_FIELDS (t) - 1; i >= 0; --i)
{
@@ -3104,7 +3246,7 @@ value_struct_elt_for_reference (struct type *domain, int offset,
offset + base_offset,
TYPE_BASECLASS (t, i),
name,
- intype);
+ intype, look_for_this);
if (v)
return v;
}
@@ -3256,7 +3398,8 @@ value_of_this (int complain)
value_ptr
value_slice (value_ptr array, int lowbound, int length)
{
- struct type *slice_range_type, *slice_type, *range_type;
+ struct type *slice_type;
+ struct range_type *slice_range_type, *range_type;
LONGEST lowerbound, upperbound, offset;
value_ptr slice;
struct type *array_type;
@@ -3266,24 +3409,24 @@ value_slice (value_ptr array, int lowbound, int length)
&& TYPE_CODE (array_type) != TYPE_CODE_STRING
&& TYPE_CODE (array_type) != TYPE_CODE_BITSTRING)
error ("cannot take slice of non-array");
- range_type = TYPE_INDEX_TYPE (array_type);
- if (get_discrete_bounds (range_type, &lowerbound, &upperbound) < 0)
- error ("slice from bad array or bitstring");
+ range_type = ARRAY_RANGE_TYPE (array_type);
+ lowerbound = RANGE_LOWER_BOUND (range_type);
+ upperbound = RANGE_UPPER_BOUND (range_type);
if (lowbound < lowerbound || length < 0
|| lowbound + length - 1 > upperbound
/* Chill allows zero-length strings but not arrays. */
|| (current_language->la_language == language_chill
&& length == 0 && TYPE_CODE (array_type) == TYPE_CODE_ARRAY))
error ("slice out of range");
- /* FIXME-type-allocation: need a way to free this type when we are
+ /* TYPEFIX-type-allocation: need a way to free this type when we are
done with it. */
- slice_range_type = create_range_type ((struct type *) NULL,
- TYPE_TARGET_TYPE (range_type),
+ slice_range_type = make_range_type (NULL,
+ RANGE_INDEX_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);
+ slice_type = (struct type *)make_set_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++)
@@ -3307,10 +3450,10 @@ value_slice (value_ptr array, int lowbound, int length)
}
else
{
- struct type *element_type = TYPE_TARGET_TYPE (array_type);
+ struct type *element_type = ARRAY_ELEMENT_TYPE (array_type);
offset
= (lowbound - lowerbound) * TYPE_LENGTH (check_typedef (element_type));
- slice_type = create_array_type ((struct type *) NULL, element_type,
+ slice_type = (struct type *)make_array_type (NULL, element_type,
slice_range_type);
TYPE_CODE (slice_type) = TYPE_CODE (array_type);
slice = allocate_value (slice_type);