| Index: gdb/eval.c
|
| diff --git a/gdb/eval.c b/gdb/eval.c
|
| index 7d3a8b96e3628237b7e644008ed3470538f0a2ec..9d81a92bcc537e82b051eddd12e0f90daf38355e 100644
|
| --- a/gdb/eval.c
|
| +++ b/gdb/eval.c
|
| @@ -1,6 +1,6 @@
|
| /* Evaluate expressions for GDB.
|
|
|
| - Copyright (C) 1986-2003, 2005-2012 Free Software Foundation, Inc.
|
| + Copyright (C) 1986-2013 Free Software Foundation, Inc.
|
|
|
| This file is part of GDB.
|
|
|
| @@ -18,7 +18,7 @@
|
| along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
|
| #include "defs.h"
|
| -#include "gdb_string.h"
|
| +#include <string.h>
|
| #include "symtab.h"
|
| #include "gdbtypes.h"
|
| #include "value.h"
|
| @@ -56,8 +56,6 @@ static struct value *evaluate_subexp_for_sizeof (struct expression *, int *);
|
| static struct value *evaluate_subexp_for_address (struct expression *,
|
| int *, enum noside);
|
|
|
| -static char *get_label (struct expression *, int *);
|
| -
|
| static struct value *evaluate_struct_tuple (struct value *,
|
| struct expression *, int *,
|
| enum noside, int);
|
| @@ -78,7 +76,7 @@ evaluate_subexp (struct type *expect_type, struct expression *exp,
|
| and return the result as a number. */
|
|
|
| CORE_ADDR
|
| -parse_and_eval_address (char *exp)
|
| +parse_and_eval_address (const char *exp)
|
| {
|
| struct expression *expr = parse_expression (exp);
|
| CORE_ADDR addr;
|
| @@ -93,7 +91,7 @@ parse_and_eval_address (char *exp)
|
| /* Like parse_and_eval_address, but treats the value of the expression
|
| as an integer, not an address, returns a LONGEST, not a CORE_ADDR. */
|
| LONGEST
|
| -parse_and_eval_long (char *exp)
|
| +parse_and_eval_long (const char *exp)
|
| {
|
| struct expression *expr = parse_expression (exp);
|
| LONGEST retval;
|
| @@ -106,7 +104,7 @@ parse_and_eval_long (char *exp)
|
| }
|
|
|
| struct value *
|
| -parse_and_eval (char *exp)
|
| +parse_and_eval (const char *exp)
|
| {
|
| struct expression *expr = parse_expression (exp);
|
| struct value *val;
|
| @@ -123,7 +121,7 @@ parse_and_eval (char *exp)
|
| EXPP is advanced to point to the comma. */
|
|
|
| struct value *
|
| -parse_to_comma_and_eval (char **expp)
|
| +parse_to_comma_and_eval (const char **expp)
|
| {
|
| struct expression *expr = parse_exp_1 (expp, 0, (struct block *) 0, 1);
|
| struct value *val;
|
| @@ -173,10 +171,12 @@ evaluate_subexpression_type (struct expression *exp, int subexp)
|
| in *VAL_CHAIN. RESULTP and VAL_CHAIN may be NULL if the caller does
|
| not need them.
|
|
|
| - If a memory error occurs while evaluating the expression, *RESULTP will
|
| - be set to NULL. *RESULTP may be a lazy value, if the result could
|
| - not be read from memory. It is used to determine whether a value
|
| - is user-specified (we should watch the whole value) or intermediate
|
| + If PRESERVE_ERRORS is true, then exceptions are passed through.
|
| + Otherwise, if PRESERVE_ERRORS is false, then if a memory error
|
| + occurs while evaluating the expression, *RESULTP will be set to
|
| + NULL. *RESULTP may be a lazy value, if the result could not be
|
| + read from memory. It is used to determine whether a value is
|
| + user-specified (we should watch the whole value) or intermediate
|
| (we should watch only the bit used to locate the final value).
|
|
|
| If the final value, or any intermediate value, could not be read
|
| @@ -191,7 +191,8 @@ evaluate_subexpression_type (struct expression *exp, int subexp)
|
|
|
| void
|
| fetch_subexp_value (struct expression *exp, int *pc, struct value **valp,
|
| - struct value **resultp, struct value **val_chain)
|
| + struct value **resultp, struct value **val_chain,
|
| + int preserve_errors)
|
| {
|
| struct value *mark, *new_mark, *result;
|
| volatile struct gdb_exception ex;
|
| @@ -212,13 +213,14 @@ fetch_subexp_value (struct expression *exp, int *pc, struct value **valp,
|
| }
|
| if (ex.reason < 0)
|
| {
|
| - /* Ignore memory errors, we want watchpoints pointing at
|
| + /* Ignore memory errors if we want watchpoints pointing at
|
| inaccessible memory to still be created; otherwise, throw the
|
| error to some higher catcher. */
|
| switch (ex.error)
|
| {
|
| case MEMORY_ERROR:
|
| - break;
|
| + if (!preserve_errors)
|
| + break;
|
| default:
|
| throw_exception (ex);
|
| break;
|
| @@ -280,27 +282,8 @@ extract_field_op (struct expression *exp, int *subexp)
|
| return result;
|
| }
|
|
|
| -/* If the next expression is an OP_LABELED, skips past it,
|
| - returning the label. Otherwise, does nothing and returns NULL. */
|
| -
|
| -static char *
|
| -get_label (struct expression *exp, int *pos)
|
| -{
|
| - if (exp->elts[*pos].opcode == OP_LABELED)
|
| - {
|
| - int pc = (*pos)++;
|
| - char *name = &exp->elts[pc + 2].string;
|
| - int tem = longest_to_int (exp->elts[pc + 1].longconst);
|
| -
|
| - (*pos) += 3 + BYTES_TO_EXP_ELEM (tem + 1);
|
| - return name;
|
| - }
|
| - else
|
| - return NULL;
|
| -}
|
| -
|
| -/* This function evaluates tuples (in (the deleted) Chill) or
|
| - brace-initializers (in C/C++) for structure types. */
|
| +/* This function evaluates brace-initializers (in C/C++) for
|
| + structure types. */
|
|
|
| static struct value *
|
| evaluate_struct_tuple (struct value *struct_val,
|
| @@ -308,143 +291,57 @@ evaluate_struct_tuple (struct value *struct_val,
|
| int *pos, enum noside noside, int nargs)
|
| {
|
| struct type *struct_type = check_typedef (value_type (struct_val));
|
| - struct type *substruct_type = struct_type;
|
| struct type *field_type;
|
| int fieldno = -1;
|
| - int variantno = -1;
|
| - int subfieldno = -1;
|
|
|
| while (--nargs >= 0)
|
| {
|
| - int pc = *pos;
|
| struct value *val = NULL;
|
| - int nlabels = 0;
|
| int bitpos, bitsize;
|
| bfd_byte *addr;
|
|
|
| - /* Skip past the labels, and count them. */
|
| - while (get_label (exp, pos) != NULL)
|
| - nlabels++;
|
| -
|
| - do
|
| - {
|
| - char *label = get_label (exp, &pc);
|
| -
|
| - if (label)
|
| - {
|
| - for (fieldno = 0; fieldno < TYPE_NFIELDS (struct_type);
|
| - fieldno++)
|
| - {
|
| - const char *field_name =
|
| - TYPE_FIELD_NAME (struct_type, fieldno);
|
| -
|
| - if (field_name != NULL && strcmp (field_name, label) == 0)
|
| - {
|
| - variantno = -1;
|
| - subfieldno = fieldno;
|
| - substruct_type = struct_type;
|
| - goto found;
|
| - }
|
| - }
|
| - for (fieldno = 0; fieldno < TYPE_NFIELDS (struct_type);
|
| - fieldno++)
|
| - {
|
| - const char *field_name =
|
| - TYPE_FIELD_NAME (struct_type, fieldno);
|
| -
|
| - field_type = TYPE_FIELD_TYPE (struct_type, fieldno);
|
| - if ((field_name == 0 || *field_name == '\0')
|
| - && TYPE_CODE (field_type) == TYPE_CODE_UNION)
|
| - {
|
| - variantno = 0;
|
| - for (; variantno < TYPE_NFIELDS (field_type);
|
| - variantno++)
|
| - {
|
| - substruct_type
|
| - = TYPE_FIELD_TYPE (field_type, variantno);
|
| - if (TYPE_CODE (substruct_type) == TYPE_CODE_STRUCT)
|
| - {
|
| - for (subfieldno = 0;
|
| - subfieldno < TYPE_NFIELDS (substruct_type);
|
| - subfieldno++)
|
| - {
|
| - if (strcmp(TYPE_FIELD_NAME (substruct_type,
|
| - subfieldno),
|
| - label) == 0)
|
| - {
|
| - goto found;
|
| - }
|
| - }
|
| - }
|
| - }
|
| - }
|
| - }
|
| - error (_("there is no field named %s"), label);
|
| - found:
|
| - ;
|
| - }
|
| - else
|
| - {
|
| - /* Unlabelled tuple element - go to next field. */
|
| - if (variantno >= 0)
|
| - {
|
| - subfieldno++;
|
| - if (subfieldno >= TYPE_NFIELDS (substruct_type))
|
| - {
|
| - variantno = -1;
|
| - substruct_type = struct_type;
|
| - }
|
| - }
|
| - if (variantno < 0)
|
| - {
|
| - fieldno++;
|
| - /* Skip static fields. */
|
| - while (fieldno < TYPE_NFIELDS (struct_type)
|
| - && field_is_static (&TYPE_FIELD (struct_type,
|
| - fieldno)))
|
| - fieldno++;
|
| - subfieldno = fieldno;
|
| - if (fieldno >= TYPE_NFIELDS (struct_type))
|
| - error (_("too many initializers"));
|
| - field_type = TYPE_FIELD_TYPE (struct_type, fieldno);
|
| - if (TYPE_CODE (field_type) == TYPE_CODE_UNION
|
| - && TYPE_FIELD_NAME (struct_type, fieldno)[0] == '0')
|
| - error (_("don't know which variant you want to set"));
|
| - }
|
| - }
|
| + fieldno++;
|
| + /* Skip static fields. */
|
| + while (fieldno < TYPE_NFIELDS (struct_type)
|
| + && field_is_static (&TYPE_FIELD (struct_type,
|
| + fieldno)))
|
| + fieldno++;
|
| + if (fieldno >= TYPE_NFIELDS (struct_type))
|
| + error (_("too many initializers"));
|
| + field_type = TYPE_FIELD_TYPE (struct_type, fieldno);
|
| + if (TYPE_CODE (field_type) == TYPE_CODE_UNION
|
| + && TYPE_FIELD_NAME (struct_type, fieldno)[0] == '0')
|
| + error (_("don't know which variant you want to set"));
|
| +
|
| + /* Here, struct_type is the type of the inner struct,
|
| + while substruct_type is the type of the inner struct.
|
| + These are the same for normal structures, but a variant struct
|
| + contains anonymous union fields that contain substruct fields.
|
| + The value fieldno is the index of the top-level (normal or
|
| + anonymous union) field in struct_field, while the value
|
| + subfieldno is the index of the actual real (named inner) field
|
| + in substruct_type. */
|
| +
|
| + field_type = TYPE_FIELD_TYPE (struct_type, fieldno);
|
| + if (val == 0)
|
| + val = evaluate_subexp (field_type, exp, pos, noside);
|
| +
|
| + /* Now actually set the field in struct_val. */
|
| +
|
| + /* Assign val to field fieldno. */
|
| + if (value_type (val) != field_type)
|
| + val = value_cast (field_type, val);
|
| +
|
| + bitsize = TYPE_FIELD_BITSIZE (struct_type, fieldno);
|
| + bitpos = TYPE_FIELD_BITPOS (struct_type, fieldno);
|
| + addr = value_contents_writeable (struct_val) + bitpos / 8;
|
| + if (bitsize)
|
| + modify_field (struct_type, addr,
|
| + value_as_long (val), bitpos % 8, bitsize);
|
| + else
|
| + memcpy (addr, value_contents (val),
|
| + TYPE_LENGTH (value_type (val)));
|
|
|
| - /* Here, struct_type is the type of the inner struct,
|
| - while substruct_type is the type of the inner struct.
|
| - These are the same for normal structures, but a variant struct
|
| - contains anonymous union fields that contain substruct fields.
|
| - The value fieldno is the index of the top-level (normal or
|
| - anonymous union) field in struct_field, while the value
|
| - subfieldno is the index of the actual real (named inner) field
|
| - in substruct_type. */
|
| -
|
| - field_type = TYPE_FIELD_TYPE (substruct_type, subfieldno);
|
| - if (val == 0)
|
| - val = evaluate_subexp (field_type, exp, pos, noside);
|
| -
|
| - /* Now actually set the field in struct_val. */
|
| -
|
| - /* Assign val to field fieldno. */
|
| - if (value_type (val) != field_type)
|
| - val = value_cast (field_type, val);
|
| -
|
| - bitsize = TYPE_FIELD_BITSIZE (substruct_type, subfieldno);
|
| - bitpos = TYPE_FIELD_BITPOS (struct_type, fieldno);
|
| - if (variantno >= 0)
|
| - bitpos += TYPE_FIELD_BITPOS (substruct_type, subfieldno);
|
| - addr = value_contents_writeable (struct_val) + bitpos / 8;
|
| - if (bitsize)
|
| - modify_field (struct_type, addr,
|
| - value_as_long (val), bitpos % 8, bitsize);
|
| - else
|
| - memcpy (addr, value_contents (val),
|
| - TYPE_LENGTH (value_type (val)));
|
| - }
|
| - while (--nlabels > 0);
|
| }
|
| return struct_val;
|
| }
|
| @@ -810,7 +707,6 @@ evaluate_subexp_standard (struct type *expect_type,
|
| struct type *type;
|
| int nargs;
|
| struct value **argvec;
|
| - int lower;
|
| int code;
|
| int ix;
|
| long mem_offset;
|
| @@ -900,7 +796,7 @@ evaluate_subexp_standard (struct type *expect_type,
|
| if (noside == EVAL_AVOID_SIDE_EFFECTS)
|
| return value_zero (SYMBOL_TYPE (sym), not_lval);
|
|
|
| - if (SYMBOL_CLASS (sym) != LOC_COMPUTED
|
| + if (SYMBOL_COMPUTED_OPS (sym) == NULL
|
| || SYMBOL_COMPUTED_OPS (sym)->read_variable_at_entry == NULL)
|
| error (_("Symbol \"%s\" does not have any specific entry value"),
|
| SYMBOL_PRINT_NAME (sym));
|
| @@ -970,16 +866,6 @@ evaluate_subexp_standard (struct type *expect_type,
|
| }
|
| return value_nsstring (exp->gdbarch, &exp->elts[pc + 2].string, tem + 1);
|
|
|
| - case OP_BITSTRING:
|
| - tem = longest_to_int (exp->elts[pc + 1].longconst);
|
| - (*pos)
|
| - += 3 + BYTES_TO_EXP_ELEM ((tem + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT);
|
| - if (noside == EVAL_SKIP)
|
| - goto nosideret;
|
| - return value_bitstring (&exp->elts[pc + 2].string, tem,
|
| - builtin_type (exp->gdbarch)->builtin_int);
|
| - break;
|
| -
|
| case OP_ARRAY:
|
| (*pos) += 3;
|
| tem2 = longest_to_int (exp->elts[pc + 1].longconst);
|
| @@ -1150,17 +1036,6 @@ evaluate_subexp_standard (struct type *expect_type,
|
| return value_slice (array, lowbound, upper - lowbound + 1);
|
| }
|
|
|
| - case TERNOP_SLICE_COUNT:
|
| - {
|
| - struct value *array = evaluate_subexp (NULL_TYPE, exp, pos, noside);
|
| - int lowbound
|
| - = value_as_long (evaluate_subexp (NULL_TYPE, exp, pos, noside));
|
| - int length
|
| - = value_as_long (evaluate_subexp (NULL_TYPE, exp, pos, noside));
|
| -
|
| - return value_slice (array, lowbound, length);
|
| - }
|
| -
|
| case TERNOP_COND:
|
| /* Skip third and second args to evaluate the first one. */
|
| arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
|
| @@ -1493,7 +1368,6 @@ evaluate_subexp_standard (struct type *expect_type,
|
| alloca (sizeof (struct value *) * (nargs + 3));
|
| if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR)
|
| {
|
| - nargs++;
|
| /* First, evaluate the structure into arg2. */
|
| pc2 = (*pos)++;
|
|
|
| @@ -1517,22 +1391,39 @@ evaluate_subexp_standard (struct type *expect_type,
|
|
|
| arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
|
|
|
| - if (TYPE_CODE (check_typedef (value_type (arg1)))
|
| - != TYPE_CODE_METHODPTR)
|
| - error (_("Non-pointer-to-member value used in pointer-to-member "
|
| - "construct"));
|
| + type = check_typedef (value_type (arg1));
|
| + if (TYPE_CODE (type) == TYPE_CODE_METHODPTR)
|
| + {
|
| + if (noside == EVAL_AVOID_SIDE_EFFECTS)
|
| + arg1 = value_zero (TYPE_TARGET_TYPE (type), not_lval);
|
| + else
|
| + arg1 = cplus_method_ptr_to_value (&arg2, arg1);
|
|
|
| - if (noside == EVAL_AVOID_SIDE_EFFECTS)
|
| + /* Now, say which argument to start evaluating from. */
|
| + nargs++;
|
| + tem = 2;
|
| + argvec[1] = arg2;
|
| + }
|
| + else if (TYPE_CODE (type) == TYPE_CODE_MEMBERPTR)
|
| {
|
| - struct type *method_type = check_typedef (value_type (arg1));
|
| + struct type *type_ptr
|
| + = lookup_pointer_type (TYPE_DOMAIN_TYPE (type));
|
| + struct type *target_type_ptr
|
| + = lookup_pointer_type (TYPE_TARGET_TYPE (type));
|
| +
|
| + /* Now, convert these values to an address. */
|
| + arg2 = value_cast (type_ptr, arg2);
|
| +
|
| + mem_offset = value_as_long (arg1);
|
|
|
| - arg1 = value_zero (method_type, not_lval);
|
| + arg1 = value_from_pointer (target_type_ptr,
|
| + value_as_long (arg2) + mem_offset);
|
| + arg1 = value_ind (arg1);
|
| + tem = 1;
|
| }
|
| else
|
| - arg1 = cplus_method_ptr_to_value (&arg2, arg1);
|
| -
|
| - /* Now, say which argument to start evaluating from. */
|
| - tem = 2;
|
| + error (_("Non-pointer-to-member value used in pointer-to-member "
|
| + "construct"));
|
| }
|
| else if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR)
|
| {
|
| @@ -1703,7 +1594,6 @@ evaluate_subexp_standard (struct type *expect_type,
|
|
|
| find_overload_match (&argvec[1], nargs, func_name,
|
| NON_METHOD, /* not method */
|
| - 0, /* strict match */
|
| NULL, NULL, /* pass NULL symbol since
|
| symbol is unknown */
|
| NULL, &symp, NULL, 0);
|
| @@ -1739,7 +1629,6 @@ evaluate_subexp_standard (struct type *expect_type,
|
|
|
| (void) find_overload_match (&argvec[1], nargs, tstr,
|
| METHOD, /* method */
|
| - 0, /* strict match */
|
| &arg2, /* the object */
|
| NULL, &valp, NULL,
|
| &static_memfuncp, 0);
|
| @@ -1783,7 +1672,7 @@ evaluate_subexp_standard (struct type *expect_type,
|
| }
|
| else if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR)
|
| {
|
| - argvec[1] = arg2;
|
| + /* Pointer to member. argvec[1] is already set up. */
|
| argvec[0] = arg1;
|
| }
|
| else if (op == OP_VAR_VALUE || (op == OP_SCOPE && function != NULL))
|
| @@ -1811,7 +1700,6 @@ evaluate_subexp_standard (struct type *expect_type,
|
| (void) find_overload_match (&argvec[1], nargs,
|
| NULL, /* no need for name */
|
| NON_METHOD, /* not method */
|
| - 0, /* strict match */
|
| NULL, function, /* the function */
|
| NULL, &symp, NULL, no_adl);
|
|
|
| @@ -1963,18 +1851,11 @@ evaluate_subexp_standard (struct type *expect_type,
|
| arg1 = evaluate_subexp (NULL_TYPE, exp, pos, noside);
|
| if (noside == EVAL_SKIP)
|
| goto nosideret;
|
| + arg3 = value_struct_elt (&arg1, NULL, &exp->elts[pc + 2].string,
|
| + NULL, "structure");
|
| if (noside == EVAL_AVOID_SIDE_EFFECTS)
|
| - return value_zero (lookup_struct_elt_type (value_type (arg1),
|
| - &exp->elts[pc + 2].string,
|
| - 0),
|
| - lval_memory);
|
| - else
|
| - {
|
| - struct value *temp = arg1;
|
| -
|
| - return value_struct_elt (&temp, NULL, &exp->elts[pc + 2].string,
|
| - NULL, "structure");
|
| - }
|
| + arg3 = value_zero (value_type (arg3), not_lval);
|
| + return arg3;
|
|
|
| case STRUCTOP_PTR:
|
| tem = longest_to_int (exp->elts[pc + 1].longconst);
|
| @@ -2024,18 +1905,11 @@ evaluate_subexp_standard (struct type *expect_type,
|
| }
|
| }
|
|
|
| + arg3 = value_struct_elt (&arg1, NULL, &exp->elts[pc + 2].string,
|
| + NULL, "structure pointer");
|
| if (noside == EVAL_AVOID_SIDE_EFFECTS)
|
| - return value_zero (lookup_struct_elt_type (value_type (arg1),
|
| - &exp->elts[pc + 2].string,
|
| - 0),
|
| - lval_memory);
|
| - else
|
| - {
|
| - struct value *temp = arg1;
|
| -
|
| - return value_struct_elt (&temp, NULL, &exp->elts[pc + 2].string,
|
| - NULL, "structure pointer");
|
| - }
|
| + arg3 = value_zero (value_type (arg3), not_lval);
|
| + return arg3;
|
|
|
| case STRUCTOP_MEMBER:
|
| case STRUCTOP_MPTR:
|
| @@ -2344,12 +2218,6 @@ evaluate_subexp_standard (struct type *expect_type,
|
| arg1 = value_subscript (arg1, value_as_long (arg2));
|
| break;
|
|
|
| - case TYPE_CODE_BITSTRING:
|
| - type = language_bool_type (exp->language_defn, exp->gdbarch);
|
| - arg1 = value_bitstring_subscript (type, arg1,
|
| - value_as_long (arg2));
|
| - break;
|
| -
|
| default:
|
| if (TYPE_NAME (type))
|
| error (_("cannot subscript something of type `%s'"),
|
| @@ -2397,8 +2265,8 @@ evaluate_subexp_standard (struct type *expect_type,
|
| struct type *array_type = check_typedef (value_type (array));
|
| LONGEST index = subscript_array[i - 1];
|
|
|
| - lower = f77_get_lowerbound (array_type);
|
| - array = value_subscripted_rvalue (array, index, lower);
|
| + array = value_subscripted_rvalue (array, index,
|
| + f77_get_lowerbound (array_type));
|
| }
|
|
|
| return array;
|
| @@ -2707,17 +2575,27 @@ evaluate_subexp_standard (struct type *expect_type,
|
| arg1 = value_cast (type, arg1);
|
| return arg1;
|
|
|
| + case UNOP_CAST_TYPE:
|
| + arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
|
| + type = value_type (arg1);
|
| + arg1 = evaluate_subexp (type, exp, pos, noside);
|
| + if (noside == EVAL_SKIP)
|
| + goto nosideret;
|
| + if (type != value_type (arg1))
|
| + arg1 = value_cast (type, arg1);
|
| + return arg1;
|
| +
|
| case UNOP_DYNAMIC_CAST:
|
| - (*pos) += 2;
|
| - type = exp->elts[pc + 1].type;
|
| + arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
|
| + type = value_type (arg1);
|
| arg1 = evaluate_subexp (type, exp, pos, noside);
|
| if (noside == EVAL_SKIP)
|
| goto nosideret;
|
| return value_dynamic_cast (type, arg1);
|
|
|
| case UNOP_REINTERPRET_CAST:
|
| - (*pos) += 2;
|
| - type = exp->elts[pc + 1].type;
|
| + arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
|
| + type = value_type (arg1);
|
| arg1 = evaluate_subexp (type, exp, pos, noside);
|
| if (noside == EVAL_SKIP)
|
| goto nosideret;
|
| @@ -2734,6 +2612,17 @@ evaluate_subexp_standard (struct type *expect_type,
|
| return value_at_lazy (exp->elts[pc + 1].type,
|
| value_as_address (arg1));
|
|
|
| + case UNOP_MEMVAL_TYPE:
|
| + arg1 = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
|
| + type = value_type (arg1);
|
| + arg1 = evaluate_subexp (expect_type, exp, pos, noside);
|
| + if (noside == EVAL_SKIP)
|
| + goto nosideret;
|
| + if (noside == EVAL_AVOID_SIDE_EFFECTS)
|
| + return value_zero (type, lval_memory);
|
| + else
|
| + return value_at_lazy (type, value_as_address (arg1));
|
| +
|
| case UNOP_MEMVAL_TLS:
|
| (*pos) += 3;
|
| arg1 = evaluate_subexp (expect_type, exp, pos, noside);
|
| @@ -2878,6 +2767,62 @@ evaluate_subexp_standard (struct type *expect_type,
|
| else
|
| error (_("Attempt to use a type name as an expression"));
|
|
|
| + case OP_TYPEOF:
|
| + case OP_DECLTYPE:
|
| + if (noside == EVAL_SKIP)
|
| + {
|
| + evaluate_subexp (NULL_TYPE, exp, pos, EVAL_SKIP);
|
| + goto nosideret;
|
| + }
|
| + else if (noside == EVAL_AVOID_SIDE_EFFECTS)
|
| + {
|
| + enum exp_opcode sub_op = exp->elts[*pos].opcode;
|
| + struct value *result;
|
| +
|
| + result = evaluate_subexp (NULL_TYPE, exp, pos,
|
| + EVAL_AVOID_SIDE_EFFECTS);
|
| +
|
| + /* 'decltype' has special semantics for lvalues. */
|
| + if (op == OP_DECLTYPE
|
| + && (sub_op == BINOP_SUBSCRIPT
|
| + || sub_op == STRUCTOP_MEMBER
|
| + || sub_op == STRUCTOP_MPTR
|
| + || sub_op == UNOP_IND
|
| + || sub_op == STRUCTOP_STRUCT
|
| + || sub_op == STRUCTOP_PTR
|
| + || sub_op == OP_SCOPE))
|
| + {
|
| + struct type *type = value_type (result);
|
| +
|
| + if (TYPE_CODE (check_typedef (type)) != TYPE_CODE_REF)
|
| + {
|
| + type = lookup_reference_type (type);
|
| + result = allocate_value (type);
|
| + }
|
| + }
|
| +
|
| + return result;
|
| + }
|
| + else
|
| + error (_("Attempt to use a type as an expression"));
|
| +
|
| + case OP_TYPEID:
|
| + {
|
| + struct value *result;
|
| + enum exp_opcode sub_op = exp->elts[*pos].opcode;
|
| +
|
| + if (sub_op == OP_TYPE || sub_op == OP_DECLTYPE || sub_op == OP_TYPEOF)
|
| + result = evaluate_subexp (NULL_TYPE, exp, pos,
|
| + EVAL_AVOID_SIDE_EFFECTS);
|
| + else
|
| + result = evaluate_subexp (NULL_TYPE, exp, pos, noside);
|
| +
|
| + if (noside != EVAL_NORMAL)
|
| + return allocate_value (cplus_typeid_type (exp->gdbarch));
|
| +
|
| + return cplus_typeid (result);
|
| + }
|
| +
|
| default:
|
| /* Removing this case and compiling with gcc -Wall reveals that
|
| a lot of cases are hitting this case. Some of these should
|
| @@ -2936,6 +2881,17 @@ evaluate_subexp_for_address (struct expression *exp, int *pos,
|
| return value_cast (lookup_pointer_type (exp->elts[pc + 1].type),
|
| evaluate_subexp (NULL_TYPE, exp, pos, noside));
|
|
|
| + case UNOP_MEMVAL_TYPE:
|
| + {
|
| + struct type *type;
|
| +
|
| + (*pos) += 1;
|
| + x = evaluate_subexp (NULL_TYPE, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
|
| + type = value_type (x);
|
| + return value_cast (lookup_pointer_type (type),
|
| + evaluate_subexp (NULL_TYPE, exp, pos, noside));
|
| + }
|
| +
|
| case OP_VAR_VALUE:
|
| var = exp->elts[pc + 2].symbol;
|
|
|
| @@ -2980,12 +2936,12 @@ evaluate_subexp_for_address (struct expression *exp, int *pos,
|
| {
|
| struct type *type = check_typedef (value_type (x));
|
|
|
| - if (VALUE_LVAL (x) == lval_memory || value_must_coerce_to_target (x))
|
| - return value_zero (lookup_pointer_type (value_type (x)),
|
| - not_lval);
|
| - else if (TYPE_CODE (type) == TYPE_CODE_REF)
|
| + if (TYPE_CODE (type) == TYPE_CODE_REF)
|
| return value_zero (lookup_pointer_type (TYPE_TARGET_TYPE (type)),
|
| not_lval);
|
| + else if (VALUE_LVAL (x) == lval_memory || value_must_coerce_to_target (x))
|
| + return value_zero (lookup_pointer_type (value_type (x)),
|
| + not_lval);
|
| else
|
| error (_("Attempt to take address of "
|
| "value not located in memory."));
|
| @@ -3078,6 +3034,12 @@ evaluate_subexp_for_sizeof (struct expression *exp, int *pos)
|
| type = check_typedef (exp->elts[pc + 1].type);
|
| return value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type));
|
|
|
| + case UNOP_MEMVAL_TYPE:
|
| + (*pos) += 1;
|
| + val = evaluate_subexp (NULL, exp, pos, EVAL_AVOID_SIDE_EFFECTS);
|
| + type = check_typedef (value_type (val));
|
| + return value_from_longest (size_type, (LONGEST) TYPE_LENGTH (type));
|
| +
|
| case OP_VAR_VALUE:
|
| (*pos) += 4;
|
| type = check_typedef (SYMBOL_TYPE (exp->elts[pc + 2].symbol));
|
|
|