X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fvalops.c;h=f902304e811b8b80ee03beb8a02c70d6e039a394;hb=d7cd1264695236f7bc59123655b9dc8f85e01cb1;hp=ad3d8f99dce2510cdc8f5ef37b135e0816dc0933;hpb=e70bba9f276b2af03f5cc3d80ad20fd982d4eb1a;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/valops.c b/gdb/valops.c index ad3d8f99dc..f902304e81 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -1,5 +1,5 @@ /* Perform non-arithmetic operations on values, for GDB. - Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994 + Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc. This file is part of GDB. @@ -16,7 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software -Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "defs.h" #include "symtab.h" @@ -30,15 +30,30 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "language.h" #include -#include +#include "gdb_string.h" + +/* Default to coercing float to double in function calls only when there is + no prototype. Otherwise on targets where the debug information is incorrect + for either the prototype or non-prototype case, we can force it by defining + COERCE_FLOAT_TO_DOUBLE in the target configuration file. */ + +#ifndef COERCE_FLOAT_TO_DOUBLE +#define COERCE_FLOAT_TO_DOUBLE (param_type == NULL) +#endif /* Local functions. */ static int typecmp PARAMS ((int staticp, struct type *t1[], value_ptr t2[])); +#ifdef CALL_DUMMY static CORE_ADDR find_function_addr PARAMS ((value_ptr, struct type **)); +static value_ptr value_arg_coerce PARAMS ((value_ptr, struct type *)); +#endif + +#ifndef PUSH_ARGUMENTS static CORE_ADDR value_push PARAMS ((CORE_ADDR, value_ptr)); +#endif static value_ptr search_struct_field PARAMS ((char *, value_ptr, int, struct type *, int)); @@ -55,48 +70,59 @@ static value_ptr cast_into_complex PARAMS ((struct type *, value_ptr)); #define VALUE_SUBSTRING_START(VAL) VALUE_FRAME(VAL) +/* Flag for whether we want to abandon failed expression evals by default. */ + +#if 0 +static int auto_abandon = 0; +#endif + -/* Allocate NBYTES of space in the inferior using the inferior's malloc - and return a value that is a pointer to the allocated space. */ +/* Find the address of function name NAME in the inferior. */ -static CORE_ADDR -allocate_space_in_inferior (len) - int len; +value_ptr +find_function_in_inferior (name) + char *name; { - register value_ptr val; register struct symbol *sym; - struct minimal_symbol *msymbol; - struct type *type; - value_ptr blocklen; - LONGEST maddr; - - /* Find the address of malloc in the inferior. */ - - sym = lookup_symbol ("malloc", 0, VAR_NAMESPACE, 0, NULL); + sym = lookup_symbol (name, 0, VAR_NAMESPACE, 0, NULL); if (sym != NULL) { if (SYMBOL_CLASS (sym) != LOC_BLOCK) { - error ("\"malloc\" exists in this program but is not a function."); + error ("\"%s\" exists in this program but is not a function.", + name); } - val = value_of_variable (sym, NULL); + return value_of_variable (sym, NULL); } else { - msymbol = lookup_minimal_symbol ("malloc", NULL, NULL); + struct minimal_symbol *msymbol = lookup_minimal_symbol(name, NULL, NULL); if (msymbol != NULL) { + struct type *type; + LONGEST maddr; type = lookup_pointer_type (builtin_type_char); type = lookup_function_type (type); type = lookup_pointer_type (type); maddr = (LONGEST) SYMBOL_VALUE_ADDRESS (msymbol); - val = value_from_longest (type, maddr); + return value_from_longest (type, maddr); } else { - error ("evaluation of this expression requires the program to have a function \"malloc\"."); + error ("evaluation of this expression requires the program to have a function \"%s\".", name); } } +} + +/* Allocate NBYTES of space in the inferior using the inferior's malloc + and return a value that is a pointer to the allocated space. */ + +value_ptr +value_allocate_space_in_inferior (len) + int len; +{ + value_ptr blocklen; + register value_ptr val = find_function_in_inferior ("malloc"); blocklen = value_from_longest (builtin_type_int, (LONGEST) len); val = call_function_by_hand (val, 1, &blocklen); @@ -104,7 +130,14 @@ allocate_space_in_inferior (len) { error ("No memory available to program."); } - return (value_as_long (val)); + return val; +} + +static CORE_ADDR +allocate_space_in_inferior (len) + int len; +{ + return value_as_long (value_allocate_space_in_inferior (len)); } /* Cast value ARG2 to type TYPE and return as a value. @@ -117,54 +150,65 @@ value_cast (type, arg2) struct type *type; register value_ptr arg2; { - register enum type_code code1 = TYPE_CODE (type); + register enum type_code code1; register enum type_code code2; register int scalar; + struct type *type2; if (VALUE_TYPE (arg2) == type) return arg2; + CHECK_TYPEDEF (type); + code1 = TYPE_CODE (type); COERCE_REF(arg2); + type2 = check_typedef (VALUE_TYPE (arg2)); /* A cast to an undetermined-length array_type, such as (TYPE [])OBJECT, is treated like a cast to (TYPE [N])OBJECT, where N is sizeof(OBJECT)/sizeof(TYPE). */ - if (code1 == TYPE_CODE_ARRAY - && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0 - && TYPE_ARRAY_UPPER_BOUND_TYPE (type) == BOUND_CANNOT_BE_DETERMINED) + if (code1 == TYPE_CODE_ARRAY) { struct type *element_type = TYPE_TARGET_TYPE (type); - struct type *range_type = TYPE_INDEX_TYPE (type); - int low_bound = TYPE_LOW_BOUND (range_type); - int val_length = TYPE_LENGTH (VALUE_TYPE (arg2)); - int new_length = val_length / TYPE_LENGTH (element_type); - if (val_length % TYPE_LENGTH (element_type) != 0) - warning("array element type size does not divide object size in cast"); - range_type = create_range_type ((struct type *) NULL, - TYPE_TARGET_TYPE (range_type), - low_bound, new_length + low_bound - 1); - VALUE_TYPE (arg2) = create_array_type ((struct type *) NULL, - element_type, range_type); - return arg2; + unsigned element_length = TYPE_LENGTH (check_typedef (element_type)); + if (element_length > 0 + && TYPE_ARRAY_UPPER_BOUND_TYPE (type) == BOUND_CANNOT_BE_DETERMINED) + { + struct type *range_type = TYPE_INDEX_TYPE (type); + int val_length = TYPE_LENGTH (type2); + LONGEST low_bound, high_bound, new_length; + if (get_discrete_bounds (range_type, &low_bound, &high_bound) < 0) + low_bound = 0, high_bound = 0; + 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 + done with it. */ + range_type = create_range_type ((struct type *) NULL, + TYPE_TARGET_TYPE (range_type), + low_bound, + new_length + low_bound - 1); + VALUE_TYPE (arg2) = create_array_type ((struct type *) NULL, + element_type, range_type); + return arg2; + } } if (current_language->c_style_arrays - && (VALUE_REPEATED (arg2) - || TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_ARRAY)) + && TYPE_CODE (type2) == TYPE_CODE_ARRAY) arg2 = value_coerce_array (arg2); - if (TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_FUNC) + if (TYPE_CODE (type2) == TYPE_CODE_FUNC) arg2 = value_coerce_function (arg2); - COERCE_VARYING_ARRAY (arg2); - - code2 = TYPE_CODE (VALUE_TYPE (arg2)); + type2 = check_typedef (VALUE_TYPE (arg2)); + COERCE_VARYING_ARRAY (arg2, type2); + code2 = TYPE_CODE (type2); - if (code1 == TYPE_CODE_COMPLEX) - return cast_into_complex (type, arg2); - if (code1 == TYPE_CODE_BOOL) + if (code1 == TYPE_CODE_COMPLEX) + return cast_into_complex (type, arg2); + if (code1 == TYPE_CODE_BOOL || code1 == TYPE_CODE_CHAR) code1 = TYPE_CODE_INT; - if (code2 == TYPE_CODE_BOOL) + if (code2 == TYPE_CODE_BOOL || code2 == TYPE_CODE_CHAR) code2 = TYPE_CODE_INT; scalar = (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_FLT @@ -178,7 +222,7 @@ value_cast (type, 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, VALUE_TYPE (arg2), 1); + arg2, 0, type2, 1); if (v) { VALUE_TYPE (v) = type; @@ -191,15 +235,15 @@ value_cast (type, arg2) || code1 == TYPE_CODE_RANGE) && (scalar || code2 == TYPE_CODE_PTR)) return value_from_longest (type, value_as_long (arg2)); - else if (TYPE_LENGTH (type) == TYPE_LENGTH (VALUE_TYPE (arg2))) + else if (TYPE_LENGTH (type) == TYPE_LENGTH (type2)) { if (code1 == TYPE_CODE_PTR && code2 == TYPE_CODE_PTR) { /* Look in the type of the source to see if it contains the type of the target as a superclass. If so, we'll need to offset the pointer rather than just change its type. */ - struct type *t1 = TYPE_TARGET_TYPE (type); - struct type *t2 = TYPE_TARGET_TYPE (VALUE_TYPE (arg2)); + struct type *t1 = check_typedef (TYPE_TARGET_TYPE (type)); + struct type *t2 = check_typedef (TYPE_TARGET_TYPE (type2)); if ( TYPE_CODE (t1) == TYPE_CODE_STRUCT && TYPE_CODE (t2) == TYPE_CODE_STRUCT && TYPE_NAME (t1) != 0) /* if name unknown, can't have supercl */ @@ -223,19 +267,26 @@ value_cast (type, arg2) struct type *range1, *range2, *eltype1, *eltype2; value_ptr val; int count1, count2; + LONGEST low_bound, high_bound; char *valaddr, *valaddr_data; if (code2 == TYPE_CODE_BITSTRING) error ("not implemented: converting bitstring to varying type"); if ((code2 != TYPE_CODE_ARRAY && code2 != TYPE_CODE_STRING) - || (eltype1 = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, 1)), - eltype2 = TYPE_TARGET_TYPE (VALUE_TYPE (arg2)), + || (eltype1 = check_typedef (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, 1))), + eltype2 = check_typedef (TYPE_TARGET_TYPE (type2)), (TYPE_LENGTH (eltype1) != TYPE_LENGTH (eltype2) /* || TYPE_CODE (eltype1) != TYPE_CODE (eltype2) */ ))) error ("Invalid conversion to varying type"); range1 = TYPE_FIELD_TYPE (TYPE_FIELD_TYPE (type, 1), 0); - range2 = TYPE_FIELD_TYPE (VALUE_TYPE (arg2), 0); - count1 = TYPE_HIGH_BOUND (range1) - TYPE_LOW_BOUND (range1) + 1; - count2 = TYPE_HIGH_BOUND (range2) - TYPE_LOW_BOUND (range2) + 1; + range2 = TYPE_FIELD_TYPE (type2, 0); + if (get_discrete_bounds (range1, &low_bound, &high_bound) < 0) + count1 = -1; + else + count1 = high_bound - low_bound + 1; + if (get_discrete_bounds (range2, &low_bound, &high_bound) < 0) + count1 = -1, count2 = 0; /* To force error before */ + else + count2 = high_bound - low_bound + 1; if (count2 > count1) error ("target varying type is too small"); val = allocate_value (type); @@ -254,7 +305,8 @@ value_cast (type, arg2) } else if (VALUE_LVAL (arg2) == lval_memory) { - return value_at_lazy (type, VALUE_ADDRESS (arg2) + VALUE_OFFSET (arg2)); + return value_at_lazy (type, VALUE_ADDRESS (arg2) + VALUE_OFFSET (arg2), + VALUE_BFD_SECTION (arg2)); } else if (code1 == TYPE_CODE_VOID) { @@ -276,7 +328,7 @@ value_zero (type, lv) { register value_ptr val = allocate_value (type); - memset (VALUE_CONTENTS (val), 0, TYPE_LENGTH (type)); + memset (VALUE_CONTENTS (val), 0, TYPE_LENGTH (check_typedef (type))); VALUE_LVAL (val) = lv; return val; @@ -292,21 +344,35 @@ value_zero (type, lv) the contents are actually required. */ value_ptr -value_at (type, addr) +value_at (type, addr, sect) struct type *type; CORE_ADDR addr; + asection *sect; { register value_ptr val; - if (TYPE_CODE (type) == TYPE_CODE_VOID) + if (TYPE_CODE (check_typedef (type)) == TYPE_CODE_VOID) error ("Attempt to dereference a generic pointer."); val = allocate_value (type); - read_memory (addr, VALUE_CONTENTS_RAW (val), TYPE_LENGTH (type)); +#ifdef GDB_TARGET_IS_D10V + if (TYPE_TARGET_TYPE(type) && TYPE_CODE(TYPE_TARGET_TYPE(type)) == TYPE_CODE_FUNC) + { + int num; + short snum; + read_memory (addr, (char *)&snum, 2); + num = D10V_MAKE_IADDR(snum); + memcpy( VALUE_CONTENTS_RAW (val), &num, 4); + } + else +#endif + + read_memory_section (addr, VALUE_CONTENTS_RAW (val), TYPE_LENGTH (type), sect); VALUE_LVAL (val) = lval_memory; VALUE_ADDRESS (val) = addr; + VALUE_BFD_SECTION (val) = sect; return val; } @@ -314,13 +380,14 @@ value_at (type, addr) /* Return a lazy value with type TYPE located at ADDR (cf. value_at). */ value_ptr -value_at_lazy (type, addr) +value_at_lazy (type, addr, sect) struct type *type; CORE_ADDR addr; + asection *sect; { register value_ptr val; - if (TYPE_CODE (type) == TYPE_CODE_VOID) + if (TYPE_CODE (check_typedef (type)) == TYPE_CODE_VOID) error ("Attempt to dereference a generic pointer."); val = allocate_value (type); @@ -328,6 +395,7 @@ value_at_lazy (type, addr) VALUE_LVAL (val) = lval_memory; VALUE_ADDRESS (val) = addr; VALUE_LAZY (val) = 1; + VALUE_BFD_SECTION (val) = sect; return val; } @@ -349,10 +417,24 @@ value_fetch_lazy (val) register value_ptr val; { CORE_ADDR addr = VALUE_ADDRESS (val) + VALUE_OFFSET (val); + int length = TYPE_LENGTH (VALUE_TYPE (val)); - if (TYPE_LENGTH (VALUE_TYPE (val))) - read_memory (addr, VALUE_CONTENTS_RAW (val), - TYPE_LENGTH (VALUE_TYPE (val))); +#ifdef GDB_TARGET_IS_D10V + struct type *type = VALUE_TYPE(val); + if (TYPE_TARGET_TYPE(type) && TYPE_CODE(TYPE_TARGET_TYPE(type)) == TYPE_CODE_FUNC) + { + int num; + short snum; + read_memory (addr, (char *)&snum, 2); + num = D10V_MAKE_IADDR(snum); + memcpy( VALUE_CONTENTS_RAW (val), &num, 4); + } + else +#endif + + if (length) + read_memory_section (addr, VALUE_CONTENTS_RAW (val), length, + VALUE_BFD_SECTION (val)); VALUE_LAZY (val) = 0; return 0; } @@ -373,12 +455,14 @@ value_assign (toval, fromval) if (!toval->modifiable) error ("Left operand of assignment is not a modifiable lvalue."); - COERCE_ARRAY (fromval); COERCE_REF (toval); type = VALUE_TYPE (toval); if (VALUE_LVAL (toval) != lval_internalvar) fromval = value_cast (type, fromval); + else + COERCE_ARRAY (fromval); + CHECK_TYPEDEF (type); /* If TOVAL is a special machine register requiring conversion of program values to a special raw format, @@ -392,7 +476,8 @@ value_assign (toval, fromval) int regno = VALUE_REGNO (toval); if (REGISTER_CONVERTIBLE (regno)) { - REGISTER_CONVERT_TO_RAW (VALUE_TYPE (fromval), regno, + struct type *fromtype = check_typedef (VALUE_TYPE (fromval)); + REGISTER_CONVERT_TO_RAW (fromtype, regno, VALUE_CONTENTS (fromval), raw_buffer); use_buffer = REGISTER_RAW_SIZE (regno); } @@ -403,7 +488,7 @@ value_assign (toval, fromval) { case lval_internalvar: set_internalvar (VALUE_INTERNALVAR (toval), fromval); - break; + return value_copy (VALUE_INTERNALVAR (toval)->value); case lval_internalvar_component: set_internalvar_component (VALUE_INTERNALVAR (toval), @@ -424,7 +509,7 @@ value_assign (toval, fromval) + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT; - if (len > sizeof (LONGEST)) + if (len > (int) sizeof (LONGEST)) error ("Can't handle bitfields which don't fit in a %d bit word.", sizeof (LONGEST) * HOST_CHAR_BIT); @@ -449,7 +534,7 @@ value_assign (toval, fromval) char buffer[sizeof (LONGEST)]; int len = REGISTER_RAW_SIZE (VALUE_REGNO (toval)); - if (len > sizeof (LONGEST)) + if (len > (int) sizeof (LONGEST)) error ("Can't handle bitfields in registers larger than %d bits.", sizeof (LONGEST) * HOST_CHAR_BIT); @@ -575,17 +660,22 @@ Can't handle bitfield which doesn't fit in a single register."); error ("Left operand of assignment is not an lvalue."); } - /* Return a value just like TOVAL except with the contents of FROMVAL - (except in the case of the type if TOVAL is an internalvar). */ - - if (VALUE_LVAL (toval) == lval_internalvar - || VALUE_LVAL (toval) == lval_internalvar_component) + /* If the field does not entirely fill a LONGEST, then zero the sign bits. + If the field is signed, and is negative, then sign extend. */ + if ((VALUE_BITSIZE (toval) > 0) + && (VALUE_BITSIZE (toval) < 8 * (int) sizeof (LONGEST))) { - type = VALUE_TYPE (fromval); + LONGEST fieldval = value_as_long (fromval); + LONGEST valmask = (((ULONGEST) 1) << VALUE_BITSIZE (toval)) - 1; + + fieldval &= valmask; + if (!TYPE_UNSIGNED (type) && (fieldval & (valmask ^ (valmask >> 1)))) + fieldval |= ~valmask; + + fromval = value_from_longest (type, fieldval); } - val = allocate_value (type); - memcpy (val, toval, VALUE_CONTENTS_RAW (val) - (char *) val); + val = value_copy (toval); memcpy (VALUE_CONTENTS_RAW (val), VALUE_CONTENTS (fromval), TYPE_LENGTH (type)); VALUE_TYPE (val) = type; @@ -611,7 +701,7 @@ value_repeat (arg1, count) read_memory (VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1), VALUE_CONTENTS_RAW (val), - TYPE_LENGTH (VALUE_TYPE (val)) * count); + TYPE_LENGTH (VALUE_TYPE (val))); VALUE_LVAL (val) = lval_memory; VALUE_ADDRESS (val) = VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1); @@ -624,27 +714,26 @@ value_of_variable (var, b) struct block *b; { value_ptr val; - struct frame_info *frame; + struct frame_info *frame = NULL; - if (b == NULL) - /* Use selected frame. */ - frame = NULL; - else + if (!b) + frame = NULL; /* Use selected frame. */ + else if (symbol_read_needs_frame (var)) { frame = block_innermost_frame (b); - if (frame == NULL && symbol_read_needs_frame (var)) - { - if (BLOCK_FUNCTION (b) != NULL - && SYMBOL_NAME (BLOCK_FUNCTION (b)) != NULL) - error ("No frame is currently executing in block %s.", - SYMBOL_NAME (BLOCK_FUNCTION (b))); - else - error ("No frame is currently executing in specified block"); - } + if (!frame) + if (BLOCK_FUNCTION (b) + && SYMBOL_NAME (BLOCK_FUNCTION (b))) + error ("No frame is currently executing in block %s.", + SYMBOL_NAME (BLOCK_FUNCTION (b))); + else + error ("No frame is currently executing in specified block"); } + val = read_var_value (var, frame); - if (val == 0) + if (!val) error ("Address of symbol \"%s\" is unknown.", SYMBOL_SOURCE_NAME (var)); + return val; } @@ -675,21 +764,12 @@ value_ptr value_coerce_array (arg1) value_ptr arg1; { - register struct type *type; + register struct type *type = check_typedef (VALUE_TYPE (arg1)); if (VALUE_LVAL (arg1) != lval_memory) error ("Attempt to take address of value not located in memory."); - /* Get type of elements. */ - if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_ARRAY - || TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_STRING) - type = TYPE_TARGET_TYPE (VALUE_TYPE (arg1)); - else - /* A phony array made by value_repeat. - Its type is the type of the elements, not an array type. */ - type = VALUE_TYPE (arg1); - - return value_from_longest (lookup_pointer_type (type), + return value_from_longest (lookup_pointer_type (TYPE_TARGET_TYPE (type)), (LONGEST) (VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1))); } @@ -700,12 +780,15 @@ value_ptr value_coerce_function (arg1) value_ptr arg1; { + value_ptr retval; if (VALUE_LVAL (arg1) != lval_memory) error ("Attempt to take address of value not located in memory."); - return value_from_longest (lookup_pointer_type (VALUE_TYPE (arg1)), - (LONGEST) (VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1))); + retval = value_from_longest (lookup_pointer_type (VALUE_TYPE (arg1)), + (LONGEST) (VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1))); + VALUE_BFD_SECTION (retval) = VALUE_BFD_SECTION (arg1); + return retval; } /* Return a pointer value for the object for which ARG1 is the contents. */ @@ -714,7 +797,9 @@ value_ptr value_addr (arg1) value_ptr arg1; { - struct type *type = VALUE_TYPE (arg1); + value_ptr retval; + + struct type *type = check_typedef (VALUE_TYPE (arg1)); if (TYPE_CODE (type) == TYPE_CODE_REF) { /* Copy the value, but change the type from (T&) to (T*). @@ -724,18 +809,16 @@ value_addr (arg1) VALUE_TYPE (arg2) = lookup_pointer_type (TYPE_TARGET_TYPE (type)); return arg2; } - if (current_language->c_style_arrays - && (VALUE_REPEATED (arg1) - || TYPE_CODE (type) == TYPE_CODE_ARRAY)) - return value_coerce_array (arg1); if (TYPE_CODE (type) == TYPE_CODE_FUNC) return value_coerce_function (arg1); if (VALUE_LVAL (arg1) != lval_memory) error ("Attempt to take address of value not located in memory."); - return value_from_longest (lookup_pointer_type (type), - (LONGEST) (VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1))); + retval = value_from_longest (lookup_pointer_type (VALUE_TYPE (arg1)), + (LONGEST) (VALUE_ADDRESS (arg1) + VALUE_OFFSET (arg1))); + VALUE_BFD_SECTION (retval) = VALUE_BFD_SECTION (arg1); + return retval; } /* Given a value of a pointer type, apply the C unary * operator to it. */ @@ -744,21 +827,24 @@ value_ptr value_ind (arg1) value_ptr arg1; { + struct type *type1; COERCE_ARRAY (arg1); + type1 = check_typedef (VALUE_TYPE (arg1)); - if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_MEMBER) + if (TYPE_CODE (type1) == TYPE_CODE_MEMBER) error ("not implemented: member types in value_ind"); /* Allow * on an integer so we can cast it to whatever we want. This returns an int, which seems like the most C-like thing to do. "long long" variables are rare enough that BUILTIN_TYPE_LONGEST would seem to be a mistake. */ - if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_INT) + if (TYPE_CODE (type1) == TYPE_CODE_INT) return value_at (builtin_type_int, - (CORE_ADDR) value_as_long (arg1)); - else if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR) - return value_at_lazy (TYPE_TARGET_TYPE (VALUE_TYPE (arg1)), - value_as_pointer (arg1)); + (CORE_ADDR) value_as_long (arg1), + VALUE_BFD_SECTION (arg1)); + else if (TYPE_CODE (type1) == TYPE_CODE_PTR) + return value_at_lazy (TYPE_TARGET_TYPE (type1), value_as_pointer (arg1), + VALUE_BFD_SECTION (arg1)); error ("Attempt to take contents of a non-pointer value."); return 0; /* For lint -- never reached */ } @@ -770,7 +856,7 @@ value_ind (arg1) CORE_ADDR push_word (sp, word) CORE_ADDR sp; - unsigned LONGEST word; + ULONGEST word; { register int len = REGISTER_SIZE; char buffer[MAX_REGISTER_RAW_SIZE]; @@ -808,6 +894,8 @@ push_bytes (sp, buffer, len) /* Push onto the stack the specified value VALUE. */ +#ifndef PUSH_ARGUMENTS + static CORE_ADDR value_push (sp, arg) register CORE_ADDR sp; @@ -826,6 +914,9 @@ value_push (sp, arg) return sp; } +#endif /* !PUSH_ARGUMENTS */ + +#ifdef CALL_DUMMY /* Perform the standard coercions that are specified for arguments to be passed to C functions. @@ -836,12 +927,14 @@ value_arg_coerce (arg, param_type) value_ptr arg; struct type *param_type; { - register struct type *type = param_type ? param_type : VALUE_TYPE (arg); + register struct type *arg_type = check_typedef (VALUE_TYPE (arg)); + register struct type *type + = param_type ? check_typedef (param_type) : arg_type; switch (TYPE_CODE (type)) { case TYPE_CODE_REF: - if (TYPE_CODE (VALUE_TYPE (arg)) != TYPE_CODE_REF) + if (TYPE_CODE (arg_type) != TYPE_CODE_REF) { arg = value_addr (arg); VALUE_TYPE (arg) = param_type; @@ -855,22 +948,40 @@ value_arg_coerce (arg, param_type) if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_int)) type = builtin_type_int; break; - case TYPE_CODE_FLT: - if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_double)) - type = builtin_type_double; - break; + case TYPE_CODE_FLT: + /* coerce float to double, unless the function prototype specifies float */ + if (COERCE_FLOAT_TO_DOUBLE) + { + if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin_type_double)) + type = builtin_type_double; + else if (TYPE_LENGTH (type) > TYPE_LENGTH (builtin_type_double)) + type = builtin_type_long_double; + } + break; case TYPE_CODE_FUNC: type = lookup_pointer_type (type); break; + case TYPE_CODE_ARRAY: + if (current_language->c_style_arrays) + type = lookup_pointer_type (TYPE_TARGET_TYPE (type)); + break; + case TYPE_CODE_UNDEF: + case TYPE_CODE_PTR: + case TYPE_CODE_STRUCT: + case TYPE_CODE_UNION: + case TYPE_CODE_VOID: + case TYPE_CODE_SET: + case TYPE_CODE_RANGE: + case TYPE_CODE_STRING: + case TYPE_CODE_BITSTRING: + case TYPE_CODE_ERROR: + case TYPE_CODE_MEMBER: + case TYPE_CODE_METHOD: + case TYPE_CODE_COMPLEX: + default: + break; } -#if 1 /* FIXME: This is only a temporary patch. -fnf */ - if (current_language->c_style_arrays - && (VALUE_REPEATED (arg) - || TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_ARRAY)) - arg = value_coerce_array (arg); -#endif - return value_cast (type, arg); } @@ -882,7 +993,7 @@ find_function_addr (function, retval_type) value_ptr function; struct type **retval_type; { - register struct type *ftype = VALUE_TYPE (function); + register struct type *ftype = check_typedef (VALUE_TYPE (function)); register enum type_code code = TYPE_CODE (ftype); struct type *value_type; CORE_ADDR funaddr; @@ -899,8 +1010,9 @@ find_function_addr (function, retval_type) else if (code == TYPE_CODE_PTR) { funaddr = value_as_pointer (function); - if (TYPE_CODE (TYPE_TARGET_TYPE (ftype)) == TYPE_CODE_FUNC - || TYPE_CODE (TYPE_TARGET_TYPE (ftype)) == TYPE_CODE_METHOD) + ftype = check_typedef (TYPE_TARGET_TYPE (ftype)); + if (TYPE_CODE (ftype) == TYPE_CODE_FUNC + || TYPE_CODE (ftype) == TYPE_CODE_METHOD) { #ifdef CONVERT_FROM_FUNC_PTR_ADDR /* FIXME: This is a workaround for the unusual function @@ -908,7 +1020,7 @@ find_function_addr (function, retval_type) in config/rs6000/tm-rs6000.h */ funaddr = CONVERT_FROM_FUNC_PTR_ADDR (funaddr); #endif - value_type = TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (ftype)); + value_type = TYPE_TARGET_TYPE (ftype); } else value_type = builtin_type_int; @@ -932,7 +1044,6 @@ find_function_addr (function, retval_type) return funaddr; } -#if defined (CALL_DUMMY) /* All this stuff with a dummy frame may seem unnecessarily complicated (why not just save registers in GDB?). The purpose of pushing a dummy frame which looks just like a real frame is so that if you call a @@ -962,20 +1073,20 @@ call_function_by_hand (function, nargs, args) CORE_ADDR start_sp; /* CALL_DUMMY is an array of words (REGISTER_SIZE), but each word is in host byte order. Before calling FIX_CALL_DUMMY, we byteswap it - and remove any extra bytes which might exist because unsigned LONGEST is + and remove any extra bytes which might exist because ULONGEST is bigger than REGISTER_SIZE. */ - static unsigned LONGEST dummy[] = CALL_DUMMY; - char dummy1[REGISTER_SIZE * sizeof dummy / sizeof (unsigned LONGEST)]; + static ULONGEST dummy[] = CALL_DUMMY; + char dummy1[REGISTER_SIZE * sizeof dummy / sizeof (ULONGEST)]; CORE_ADDR old_sp; struct type *value_type; unsigned char struct_return; - CORE_ADDR struct_addr; + CORE_ADDR struct_addr = 0; struct inferior_status inf_status; struct cleanup *old_chain; CORE_ADDR funaddr; - int using_gcc; + int using_gcc; /* Set to version of gcc in use, or zero if not gcc */ CORE_ADDR real_pc; - struct type *ftype = SYMBOL_TYPE (function); + struct type *ftype = check_typedef (SYMBOL_TYPE (function)); if (!target_has_execution) noprocess(); @@ -999,11 +1110,12 @@ call_function_by_hand (function, nargs, args) #endif funaddr = find_function_addr (function, &value_type); + CHECK_TYPEDEF (value_type); { struct block *b = block_for_pc (funaddr); - /* If compiled without -g, assume GCC. */ - using_gcc = b == NULL ? 0 : BLOCK_GCC_COMPILED (b); + /* If compiled without -g, assume GCC 2. */ + using_gcc = (b == NULL ? 2 : BLOCK_GCC_COMPILED (b)); } /* Are we returning a value using a structure return or a normal @@ -1014,10 +1126,10 @@ call_function_by_hand (function, nargs, args) /* Create a call sequence customized for this function and the number of arguments for it. */ - for (i = 0; i < sizeof dummy / sizeof (dummy[0]); i++) + for (i = 0; i < (int) (sizeof (dummy) / sizeof (dummy[0])); i++) store_unsigned_integer (&dummy1[i * REGISTER_SIZE], REGISTER_SIZE, - (unsigned LONGEST)dummy[i]); + (ULONGEST)dummy[i]); #ifdef GDB_TARGET_IS_HPPA real_pc = FIX_CALL_DUMMY (dummy1, start_sp, funaddr, nargs, args, @@ -1087,40 +1199,51 @@ call_function_by_hand (function, nargs, args) /* This is a machine like the sparc, where we may need to pass a pointer to the structure, not the structure itself. */ for (i = nargs - 1; i >= 0; i--) - if ((TYPE_CODE (VALUE_TYPE (args[i])) == TYPE_CODE_STRUCT - || TYPE_CODE (VALUE_TYPE (args[i])) == TYPE_CODE_UNION - || TYPE_CODE (VALUE_TYPE (args[i])) == TYPE_CODE_ARRAY - || TYPE_CODE (VALUE_TYPE (args[i])) == TYPE_CODE_STRING) - && REG_STRUCT_HAS_ADDR (using_gcc, VALUE_TYPE (args[i]))) - { - CORE_ADDR addr; - int len = TYPE_LENGTH (VALUE_TYPE (args[i])); + { + struct type *arg_type = check_typedef (VALUE_TYPE (args[i])); + if ((TYPE_CODE (arg_type) == TYPE_CODE_STRUCT + || TYPE_CODE (arg_type) == TYPE_CODE_UNION + || TYPE_CODE (arg_type) == TYPE_CODE_ARRAY + || TYPE_CODE (arg_type) == TYPE_CODE_STRING + || TYPE_CODE (arg_type) == TYPE_CODE_BITSTRING + || TYPE_CODE (arg_type) == TYPE_CODE_SET + || (TYPE_CODE (arg_type) == TYPE_CODE_FLT + && TYPE_LENGTH (arg_type) > 8) + ) + && REG_STRUCT_HAS_ADDR (using_gcc, arg_type)) + { + CORE_ADDR addr; + int len = TYPE_LENGTH (arg_type); #ifdef STACK_ALIGN - int aligned_len = STACK_ALIGN (len); + /* MVS 11/22/96: I think at least some of this stack_align code is + really broken. Better to let PUSH_ARGUMENTS adjust the stack in + a target-defined manner. */ + int aligned_len = STACK_ALIGN (len); #else - int aligned_len = len; + int aligned_len = len; #endif #if !(1 INNER_THAN 2) - /* The stack grows up, so the address of the thing we push - is the stack pointer before we push it. */ - addr = sp; + /* The stack grows up, so the address of the thing we push + is the stack pointer before we push it. */ + addr = sp; #else - sp -= aligned_len; + sp -= aligned_len; #endif - /* Push the structure. */ - write_memory (sp, VALUE_CONTENTS (args[i]), len); + /* Push the structure. */ + write_memory (sp, VALUE_CONTENTS (args[i]), len); #if 1 INNER_THAN 2 - /* The stack grows down, so the address of the thing we push - is the stack pointer after we push it. */ - addr = sp; + /* The stack grows down, so the address of the thing we push + is the stack pointer after we push it. */ + addr = sp; #else - sp += aligned_len; + sp += aligned_len; #endif - /* The value we're going to pass is the address of the thing - we just pushed. */ - args[i] = value_from_longest (lookup_pointer_type (value_type), - (LONGEST) addr); - } + /* The value we're going to pass is the address of the thing + we just pushed. */ + args[i] = value_from_longest (lookup_pointer_type (value_type), + (LONGEST) addr); + } + } } #endif /* REG_STRUCT_HAS_ADDR. */ @@ -1131,6 +1254,9 @@ call_function_by_hand (function, nargs, args) { int len = TYPE_LENGTH (value_type); #ifdef STACK_ALIGN + /* MVS 11/22/96: I think at least some of this stack_align code is + really broken. Better to let PUSH_ARGUMENTS adjust the stack in + a target-defined manner. */ len = STACK_ALIGN (len); #endif #if 1 INNER_THAN 2 @@ -1142,9 +1268,12 @@ call_function_by_hand (function, nargs, args) #endif } -#ifdef STACK_ALIGN - /* If stack grows down, we must leave a hole at the top. */ +#if defined(STACK_ALIGN) && (1 INNER_THAN 2) + /* MVS 11/22/96: I think at least some of this stack_align code is + really broken. Better to let PUSH_ARGUMENTS adjust the stack in + a target-defined manner. */ { + /* If stack grows down, we must leave a hole at the top. */ int len = 0; for (i = nargs - 1; i >= 0; i--) @@ -1152,11 +1281,7 @@ call_function_by_hand (function, nargs, args) #ifdef CALL_DUMMY_STACK_ADJUST len += CALL_DUMMY_STACK_ADJUST; #endif -#if 1 INNER_THAN 2 sp -= STACK_ALIGN (len) - len; -#else - sp += STACK_ALIGN (len) - len; -#endif } #endif /* STACK_ALIGN */ @@ -1167,11 +1292,38 @@ call_function_by_hand (function, nargs, args) sp = value_push (sp, args[i]); #endif /* !PUSH_ARGUMENTS */ +#ifdef PUSH_RETURN_ADDRESS /* for targets that use no CALL_DUMMY */ + /* There are a number of targets now which actually don't write any + CALL_DUMMY instructions into the target, but instead just save the + machine state, push the arguments, and jump directly to the callee + function. Since this doesn't actually involve executing a JSR/BSR + instruction, the return address must be set up by hand, either by + pushing onto the stack or copying into a return-address register + as appropriate. Formerly this has been done in PUSH_ARGUMENTS, + but that's overloading its functionality a bit, so I'm making it + explicit to do it here. */ + sp = PUSH_RETURN_ADDRESS(real_pc, sp); +#endif /* PUSH_RETURN_ADDRESS */ + +#if defined(STACK_ALIGN) && !(1 INNER_THAN 2) + { + /* If stack grows up, we must leave a hole at the bottom, note + that sp already has been advanced for the arguments! */ +#ifdef CALL_DUMMY_STACK_ADJUST + sp += CALL_DUMMY_STACK_ADJUST; +#endif + sp = STACK_ALIGN (sp); + } +#endif /* STACK_ALIGN */ + +/* XXX This seems wrong. For stacks that grow down we shouldn't do + anything here! */ + /* MVS 11/22/96: I think at least some of this stack_align code is + really broken. Better to let PUSH_ARGUMENTS adjust the stack in + a target-defined manner. */ #ifdef CALL_DUMMY_STACK_ADJUST #if 1 INNER_THAN 2 sp -= CALL_DUMMY_STACK_ADJUST; -#else - sp += CALL_DUMMY_STACK_ADJUST; #endif #endif /* CALL_DUMMY_STACK_ADJUST */ @@ -1290,7 +1442,7 @@ value_array (lowbound, highbound, elemvec) { int nelem; int idx; - int typelength; + unsigned int typelength; value_ptr val; struct type *rangetype; struct type *arraytype; @@ -1305,7 +1457,7 @@ value_array (lowbound, highbound, elemvec) error ("bad array bounds (%d, %d)", lowbound, highbound); } typelength = TYPE_LENGTH (VALUE_TYPE (elemvec[0])); - for (idx = 0; idx < nelem; idx++) + for (idx = 1; idx < nelem; idx++) { if (TYPE_LENGTH (VALUE_TYPE (elemvec[idx])) != typelength) { @@ -1313,6 +1465,24 @@ value_array (lowbound, highbound, elemvec) } } + rangetype = create_range_type ((struct type *) NULL, builtin_type_int, + lowbound, highbound); + arraytype = create_array_type ((struct type *) NULL, + VALUE_TYPE (elemvec[0]), rangetype); + + if (!current_language->c_style_arrays) + { + val = allocate_value (arraytype); + for (idx = 0; idx < nelem; idx++) + { + memcpy (VALUE_CONTENTS_RAW (val) + (idx * typelength), + VALUE_CONTENTS (elemvec[idx]), + typelength); + } + VALUE_BFD_SECTION (val) = VALUE_BFD_SECTION (elemvec[0]); + return val; + } + /* Allocate space to store the array in the inferior, and then initialize it by copying in each element. FIXME: Is it worth it to create a local buffer in which to collect each value and then write all the @@ -1327,11 +1497,7 @@ value_array (lowbound, highbound, elemvec) /* Create the array type and set up an array value to be evaluated lazily. */ - rangetype = create_range_type ((struct type *) NULL, builtin_type_int, - lowbound, highbound); - arraytype = create_array_type ((struct type *) NULL, - VALUE_TYPE (elemvec[0]), rangetype); - val = value_at_lazy (arraytype, addr); + val = value_at_lazy (arraytype, addr, VALUE_BFD_SECTION (elemvec[0])); return (val); } @@ -1371,7 +1537,7 @@ value_string (ptr, len) addr = allocate_space_in_inferior (len); write_memory (addr, ptr, len); - val = value_at_lazy (stringtype, addr); + val = value_at_lazy (stringtype, addr, NULL); return (val); } @@ -1386,7 +1552,7 @@ value_bitstring (ptr, len) struct type *type = create_set_type ((struct type*) NULL, domain_type); TYPE_CODE (type) = TYPE_CODE_BITSTRING; val = allocate_value (type); - memcpy (VALUE_CONTENTS_RAW (val), ptr, TYPE_LENGTH (type) / TARGET_CHAR_BIT); + memcpy (VALUE_CONTENTS_RAW (val), ptr, TYPE_LENGTH (type)); return val; } @@ -1426,21 +1592,25 @@ typecmp (staticp, t1, t2) struct type *tt1, *tt2; if (! t2[i]) return i+1; - tt1 = t1[i]; - tt2 = VALUE_TYPE(t2[i]); + tt1 = check_typedef (t1[i]); + tt2 = check_typedef (VALUE_TYPE(t2[i])); if (TYPE_CODE (tt1) == TYPE_CODE_REF /* We should be doing hairy argument matching, as below. */ - && (TYPE_CODE (TYPE_TARGET_TYPE (tt1)) == TYPE_CODE (tt2))) + && (TYPE_CODE (check_typedef (TYPE_TARGET_TYPE (tt1))) == TYPE_CODE (tt2))) { - t2[i] = value_addr (t2[i]); + if (TYPE_CODE (tt2) == TYPE_CODE_ARRAY) + t2[i] = value_coerce_array (t2[i]); + else + t2[i] = value_addr (t2[i]); continue; } while (TYPE_CODE (tt1) == TYPE_CODE_PTR - && (TYPE_CODE(tt2)==TYPE_CODE_ARRAY || TYPE_CODE(tt2)==TYPE_CODE_PTR)) + && ( TYPE_CODE (tt2) == TYPE_CODE_ARRAY + || TYPE_CODE (tt2) == TYPE_CODE_PTR)) { - tt1 = TYPE_TARGET_TYPE(tt1); - tt2 = TYPE_TARGET_TYPE(tt2); + tt1 = check_typedef (TYPE_TARGET_TYPE(tt1)); + tt2 = check_typedef (TYPE_TARGET_TYPE(tt2)); } if (TYPE_CODE(tt1) == TYPE_CODE(tt2)) continue; /* Array to pointer is a `trivial conversion' according to the ARM. */ @@ -1473,7 +1643,7 @@ search_struct_field (name, arg1, offset, type, looking_for_baseclass) { int i; - check_stub_type (type); + CHECK_TYPEDEF (type); if (! looking_for_baseclass) for (i = TYPE_NFIELDS (type) - 1; i >= TYPE_N_BASECLASSES (type); i--) @@ -1492,7 +1662,7 @@ search_struct_field (name, arg1, offset, type, looking_for_baseclass) error ("Internal error: could not find physical static variable named %s", phys_name); v = value_at (TYPE_FIELD_TYPE (type, i), - (CORE_ADDR)SYMBOL_BLOCK_VALUE (sym)); + SYMBOL_VALUE_ADDRESS (sym), SYMBOL_BFD_SECTION (sym)); } else v = value_primitive_field (arg1, offset, i, type); @@ -1500,22 +1670,50 @@ search_struct_field (name, arg1, offset, type, looking_for_baseclass) error("there is no field named %s", name); return v; } - if (t_field_name && t_field_name[0] == '\0' - && TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_UNION) + + if (t_field_name + && (t_field_name[0] == '\0' + || (TYPE_CODE (type) == TYPE_CODE_UNION + && STREQ (t_field_name, "else")))) { - /* Look for a match through the fields of an anonymous union. */ - value_ptr v; - v = search_struct_field (name, arg1, offset, - TYPE_FIELD_TYPE (type, i), - looking_for_baseclass); - if (v) - return v; + struct type *field_type = TYPE_FIELD_TYPE (type, i); + if (TYPE_CODE (field_type) == TYPE_CODE_UNION + || TYPE_CODE (field_type) == TYPE_CODE_STRUCT) + { + /* Look for a match through the fields of an anonymous union, + or anonymous struct. C++ provides anonymous unions. + + In the GNU Chill implementation of variant record types, + each has an (anonymous) union type, + each member of the union represents a . + Each is represented as a struct, + with a member for each . */ + + value_ptr v; + int new_offset = offset; + + /* This is pretty gross. In G++, the offset in an anonymous + union is relative to the beginning of the enclosing struct. + In the GNU Chill implementation of variant records, + the bitpos is zero in an anonymous union field, so we + have to add the offset of the union here. */ + if (TYPE_CODE (field_type) == TYPE_CODE_STRUCT + || (TYPE_NFIELDS (field_type) > 0 + && 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; + } } } for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--) { value_ptr v; + 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 name is not yet filled in. */ @@ -1525,15 +1723,28 @@ search_struct_field (name, arg1, offset, type, looking_for_baseclass) if (BASETYPE_VIA_VIRTUAL (type, i)) { - value_ptr v2; - /* Fix to use baseclass_offset instead. FIXME */ - baseclass_addr (type, i, VALUE_CONTENTS (arg1) + offset, - &v2, (int *)NULL); - if (v2 == 0) + int boffset = VALUE_OFFSET (arg1) + offset; + boffset = baseclass_offset (type, i, + VALUE_CONTENTS (arg1) + boffset, + VALUE_ADDRESS (arg1) + boffset); + if (boffset == -1) error ("virtual baseclass botch"); if (found_baseclass) - return v2; - v = search_struct_field (name, v2, 0, TYPE_BASECLASS (type, i), + { + value_ptr v2 = allocate_value (basetype); + VALUE_LVAL (v2) = VALUE_LVAL (arg1); + VALUE_ADDRESS (v2) = VALUE_ADDRESS (arg1); + VALUE_OFFSET (v2) = VALUE_OFFSET (arg1) + offset + boffset; + if (VALUE_LAZY (arg1)) + VALUE_LAZY (v2) = 1; + else + memcpy (VALUE_CONTENTS_RAW (v2), + VALUE_CONTENTS_RAW (arg1) + offset + boffset, + TYPE_LENGTH (basetype)); + return v2; + } + v = search_struct_field (name, arg1, offset + boffset, + TYPE_BASECLASS (type, i), looking_for_baseclass); } else if (found_baseclass) @@ -1541,8 +1752,7 @@ search_struct_field (name, arg1, offset, type, looking_for_baseclass) else v = search_struct_field (name, arg1, offset + TYPE_BASECLASS_BITPOS (type, i) / 8, - TYPE_BASECLASS (type, i), - looking_for_baseclass); + basetype, looking_for_baseclass); if (v) return v; } return NULL; @@ -1566,10 +1776,11 @@ search_struct_method (name, arg1p, args, offset, static_memfuncp, type) int name_matched = 0; char dem_opname[64]; - check_stub_type (type); + CHECK_TYPEDEF (type); for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; i--) { 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 || strncmp(t_field_name, "op", 2)==0 || strncmp(t_field_name, "type", 4)==0 ) @@ -1612,7 +1823,11 @@ search_struct_method (name, arg1p, args, offset, static_memfuncp, type) if (BASETYPE_VIA_VIRTUAL (type, i)) { - base_offset = baseclass_offset (type, i, *arg1p, offset); + base_offset = VALUE_OFFSET (*arg1p) + offset; + base_offset = + baseclass_offset (type, i, + VALUE_CONTENTS (*arg1p) + base_offset, + VALUE_ADDRESS (*arg1p) + base_offset); if (base_offset == -1) error ("virtual baseclass botch"); } @@ -1663,7 +1878,7 @@ value_struct_elt (argp, args, name, static_memfuncp, err) COERCE_ARRAY (*argp); - t = VALUE_TYPE (*argp); + t = check_typedef (VALUE_TYPE (*argp)); /* Follow pointers until we get to a non-pointer. */ @@ -1673,7 +1888,7 @@ value_struct_elt (argp, args, name, static_memfuncp, err) /* Don't coerce fn pointer to fn and then back again! */ if (TYPE_CODE (VALUE_TYPE (*argp)) != TYPE_CODE_FUNC) COERCE_ARRAY (*argp); - t = VALUE_TYPE (*argp); + t = check_typedef (VALUE_TYPE (*argp)); } if (TYPE_CODE (t) == TYPE_CODE_MEMBER) @@ -1721,11 +1936,19 @@ value_struct_elt (argp, args, name, static_memfuncp, err) { if (!args[1]) { - /* destructors are a special case. */ - v = value_fn_field (NULL, TYPE_FN_FIELDLIST1 (t, 0), - TYPE_FN_FIELDLIST_LENGTH (t, 0), 0, 0); - if (!v) error("could not find destructor function named %s.", name); - else return v; + /* Destructors are a special case. */ + int m_index, f_index; + + v = NULL; + if (get_destructor_fn_field (t, &m_index, &f_index)) + { + v = value_fn_field (NULL, TYPE_FN_FIELDLIST1 (t, m_index), + f_index, NULL, 0); + } + if (v == NULL) + error ("could not find destructor function named %s.", name); + else + return v; } else { @@ -1766,7 +1989,7 @@ destructor_name_p (name, type) { char *dname = type_name_no_tag (type); char *cp = strchr (dname, '<'); - int len; + unsigned int len; /* Do not compare the template part for template classes. */ if (cp == NULL) @@ -1804,7 +2027,11 @@ check_field_in (type, name) /* Destructors are a special case. */ if (destructor_name_p (name, type)) - return 1; + { + int m_index, f_index; + + return get_destructor_fn_field (type, &m_index, &f_index); + } for (i = TYPE_NFN_FIELDS (type) - 1; i >= 0; --i) { @@ -1837,8 +2064,13 @@ check_field (arg1, name) /* Follow pointers until we get to a non-pointer. */ - while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF) - t = TYPE_TARGET_TYPE (t); + for (;;) + { + CHECK_TYPEDEF (t); + if (TYPE_CODE (t) != TYPE_CODE_PTR && TYPE_CODE (t) != TYPE_CODE_REF) + break; + t = TYPE_TARGET_TYPE (t); + } if (TYPE_CODE (t) == TYPE_CODE_MEMBER) error ("not implemented: member type in check_field"); @@ -1886,7 +2118,8 @@ value_struct_elt_for_reference (domain, offset, curtype, name, intype) error ("Internal error: could not find physical static variable named %s", phys_name); return value_at (SYMBOL_TYPE (sym), - (CORE_ADDR)SYMBOL_BLOCK_VALUE (sym)); + SYMBOL_VALUE_ADDRESS (sym), + SYMBOL_BFD_SECTION (sym)); } if (TYPE_FIELD_PACKED (t, i)) error ("pointers to bitfield members not allowed"); @@ -2054,30 +2287,63 @@ value_slice (array, lowbound, length) value_ptr array; int lowbound, length; { - if (TYPE_CODE (VALUE_TYPE (array)) == TYPE_CODE_BITSTRING) - error ("not implemented - bitstring slice"); - if (TYPE_CODE (VALUE_TYPE (array)) != TYPE_CODE_ARRAY - && TYPE_CODE (VALUE_TYPE (array)) != TYPE_CODE_STRING) + struct type *slice_range_type, *slice_type, *range_type; + LONGEST lowerbound, upperbound, offset; + value_ptr slice; + struct type *array_type; + array_type = check_typedef (VALUE_TYPE (array)); + COERCE_VARYING_ARRAY (array, array_type); + if (TYPE_CODE (array_type) != TYPE_CODE_ARRAY + && 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"); + 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 + done with it. */ + slice_range_type = create_range_type ((struct type*) NULL, + 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 (BITS_BIG_ENDIAN) + 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 clice + 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 *slice_range_type, *slice_type; - value_ptr slice; - struct type *range_type = TYPE_FIELD_TYPE (VALUE_TYPE (array), 0); - struct type *element_type = TYPE_TARGET_TYPE (VALUE_TYPE (array)); - int lowerbound = TYPE_LOW_BOUND (range_type); - int upperbound = TYPE_HIGH_BOUND (range_type); - int offset = (lowbound - lowerbound) * TYPE_LENGTH (element_type); - if (lowbound < lowerbound || length < 0 - || lowbound + length - 1 > upperbound) - error ("slice out of range"); - slice_range_type = create_range_type ((struct type*) NULL, - TYPE_TARGET_TYPE (range_type), - lowerbound, - lowerbound + length - 1); + struct type *element_type = TYPE_TARGET_TYPE (array_type); + offset + = (lowbound - lowerbound) * TYPE_LENGTH (check_typedef (element_type)); slice_type = create_array_type ((struct type*) NULL, element_type, slice_range_type); - TYPE_CODE (slice_type) = TYPE_CODE (VALUE_TYPE (array)); + TYPE_CODE (slice_type) = TYPE_CODE (array_type); slice = allocate_value (slice_type); if (VALUE_LAZY (array)) VALUE_LAZY (slice) = 1; @@ -2090,8 +2356,8 @@ value_slice (array, lowbound, length) VALUE_LVAL (slice) = VALUE_LVAL (array); VALUE_ADDRESS (slice) = VALUE_ADDRESS (array); VALUE_OFFSET (slice) = VALUE_OFFSET (array) + offset; - return slice; } + return slice; } /* Assuming chill_varying_type (VARRAY) is true, return an equivalent @@ -2101,7 +2367,7 @@ value_ptr varying_to_slice (varray) value_ptr varray; { - struct type *vtype = VALUE_TYPE (varray); + struct type *vtype = check_typedef (VALUE_TYPE (varray)); LONGEST length = unpack_long (TYPE_FIELD_TYPE (vtype, 0), VALUE_CONTENTS (varray) + TYPE_FIELD_BITPOS (vtype, 0) / 8); @@ -2162,3 +2428,15 @@ cast_into_complex (type, val) else error ("cannot cast non-number to complex"); } + +void +_initialize_valops () +{ +#if 0 + add_show_from_set + (add_set_cmd ("abandon", class_support, var_boolean, (char *)&auto_abandon, + "Set automatic abandonment of expressions upon failure.", + &setlist), + &showlist); +#endif +}